Embedded Template Library 1.0
Loading...
Searching...
No Matches
functional.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2014 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_FUNCTIONAL_INCLUDED
32#define ETL_FUNCTIONAL_INCLUDED
33
34#include "platform.h"
35#include "utility.h"
36
39
42
43namespace etl
44{
45 //***************************************************************************
48 //***************************************************************************
49 template <typename T>
50 class reference_wrapper
51 {
52 public:
53
54 typedef T type;
55
56 ETL_CONSTEXPR20 explicit reference_wrapper(T& t_) ETL_NOEXCEPT
57 : t(&t_)
58 {
59 }
60
61 ETL_CONSTEXPR20 reference_wrapper(const reference_wrapper& rhs) ETL_NOEXCEPT
62 : t(rhs.t)
63 {
64 }
65
66 ETL_CONSTEXPR20 reference_wrapper<T>& operator=(const reference_wrapper& rhs) ETL_NOEXCEPT
67 {
68 t = rhs.t;
69 return *this;
70 }
71
72 ETL_CONSTEXPR20 T& get() const ETL_NOEXCEPT
73 {
74 return *t;
75 }
76
77 ETL_CONSTEXPR20 operator T&() const ETL_NOEXCEPT
78 {
79 return *t;
80 }
81
82#if ETL_USING_CPP11
83 // implementation without etl::invoke, which would add a circular dependency
84 template <typename... TArgs>
85 ETL_CONSTEXPR20 auto operator()(TArgs&&... args) const
86 noexcept(noexcept(etl::declval<T&>()(etl::declval<TArgs>()...))) -> decltype(etl::declval<T&>()(etl::declval<TArgs>()...))
87 {
88 return get()(etl::forward<TArgs>(args)...);
89 }
90#endif
91
92 private:
93
94 T* t;
95 };
96
97 //***************************************************************************
98 template <typename T>
99 reference_wrapper<T> ref(T& t)
100 {
101 return reference_wrapper<T>(t);
102 }
103
104 //***************************************************************************
105 template <typename T>
106 reference_wrapper<T> ref(reference_wrapper<T> t)
107 {
108 return reference_wrapper<T>(t.get());
109 }
110
111 //***************************************************************************
112 template <typename T>
113 reference_wrapper<const T> cref(const T& t)
114 {
116 }
117
118 //***************************************************************************
119 template <typename T>
121 {
122 return reference_wrapper<const T>(t.get());
123 }
124
125 //***************************************************************************
127 //***************************************************************************
128 template <class T>
130 {
131 typedef T type;
132 };
133
134 template <typename T>
136 {
137 typedef T& type;
138 };
139
140#if ETL_USING_CPP11
141 template <typename T>
142 using unwrap_reference_t = typename unwrap_reference<T>::type;
143#endif
144
145 //***************************************************************************
147 //***************************************************************************
148 template <typename T>
149 struct unwrap_ref_decay : etl::unwrap_reference<typename etl::decay<T>::type>
150 {
151 };
152
153#if ETL_USING_CPP11
154 template <typename T>
155 using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type;
156#endif
157
158 //***************************************************************************
159 // is_reference_wrapper
160 // Detect etl::reference_wrapper<T>
161 //***************************************************************************
162 template <typename T>
166
167 template <typename T>
168 struct is_reference_wrapper<etl::reference_wrapper<T> > : etl::true_type
169 {
170 };
171
172#if ETL_USING_CPP17
173 template <typename T>
174 inline constexpr bool is_reference_wrapper_v = is_reference_wrapper<T>::value;
175#endif
176
177 //***************************************************************************
179 //***************************************************************************
180 template <typename TArgumentType, typename TResultType>
182 {
183 typedef TArgumentType argument_type;
184 typedef TResultType result_type;
185 };
186
187 //***************************************************************************
189 //***************************************************************************
190 template <typename TFirstArgumentType, typename TSecondArgumentType, typename TResultType>
192 {
193 typedef TFirstArgumentType first_argument_type;
194 typedef TSecondArgumentType second_argument_type;
195 typedef TResultType result_type;
196 };
197
198 //***************************************************************************
199 template <typename T = void>
200 struct less : public etl::binary_function<T, T, bool>
201 {
202 typedef T value_type;
203
204 ETL_CONSTEXPR bool operator()(const T& lhs, const T& rhs) const
205 {
206 return (lhs < rhs);
207 }
208 };
209
210#if ETL_USING_CPP11
211 template <>
212 struct less<void> : public etl::binary_function<void, void, bool>
213 {
214 typedef int is_transparent;
215
216 template <typename T1, typename T2>
217 constexpr auto operator()(T1&& lhs, T2&& rhs) const -> decltype(static_cast<T1&&>(lhs) < static_cast<T2&&>(rhs))
218 {
219 return static_cast<T1&&>(lhs) < static_cast<T2&&>(rhs);
220 }
221 };
222#endif
223
224 //***************************************************************************
225 template <typename T = void>
226 struct less_equal : public etl::binary_function<T, T, bool>
227 {
228 typedef T value_type;
229
230 ETL_CONSTEXPR bool operator()(const T& lhs, const T& rhs) const
231 {
232 return !(rhs < lhs);
233 }
234 };
235
236#if ETL_USING_CPP11
237 template <>
238 struct less_equal<void> : public etl::binary_function<void, void, bool>
239 {
240 typedef int is_transparent;
241
242 template <typename T1, typename T2>
243 constexpr auto operator()(T1&& lhs, T2&& rhs) const -> decltype(!(static_cast<T2&&>(rhs) < static_cast<T1&&>(lhs)))
244 {
245 return !(static_cast<T2&&>(rhs) < static_cast<T1&&>(lhs));
246 }
247 };
248#endif
249
250 //***************************************************************************
251 template <typename T = void>
252 struct greater : public etl::binary_function<T, T, bool>
253 {
254 typedef T value_type;
255
256 ETL_CONSTEXPR bool operator()(const T& lhs, const T& rhs) const
257 {
258 return (rhs < lhs);
259 }
260 };
261
262#if ETL_USING_CPP11
263 template <>
264 struct greater<void> : public etl::binary_function<void, void, bool>
265 {
266 typedef int is_transparent;
267
268 template <typename T1, typename T2>
269 constexpr auto operator()(T1&& lhs, T2&& rhs) const -> decltype(static_cast<T2&&>(rhs) < static_cast<T1&&>(lhs))
270 {
271 return static_cast<T2&&>(rhs) < static_cast<T1&&>(lhs);
272 }
273 };
274#endif
275
276 //***************************************************************************
277 template <typename T = void>
278 struct greater_equal : public etl::binary_function<T, T, bool>
279 {
280 typedef T value_type;
281
282 ETL_CONSTEXPR bool operator()(const T& lhs, const T& rhs) const
283 {
284 return !(lhs < rhs);
285 }
286 };
287
288#if ETL_USING_CPP11
289 template <>
290 struct greater_equal<void> : public etl::binary_function<void, void, bool>
291 {
292 typedef int is_transparent;
293
294 template <typename T1, typename T2>
295 constexpr auto operator()(T1&& lhs, T2&& rhs) const -> decltype(!(static_cast<T1&&>(lhs) < static_cast<T2&&>(rhs)))
296 {
297 return !(static_cast<T1&&>(lhs) < static_cast<T2&&>(rhs));
298 }
299 };
300#endif
301
302 //***************************************************************************
303 template <typename T = void>
304 struct equal_to : public etl::binary_function<T, T, bool>
305 {
306 typedef T value_type;
307
308 ETL_CONSTEXPR bool operator()(const T& lhs, const T& rhs) const
309 {
310 return lhs == rhs;
311 }
312 };
313
314#if ETL_USING_CPP11
315 template <>
316 struct equal_to<void> : public etl::binary_function<void, void, bool>
317 {
318 typedef void value_type;
319 typedef int is_transparent;
320
321 template <typename T1, typename T2>
322 constexpr auto operator()(T1&& lhs, T2&& rhs) const -> decltype(static_cast<T1&&>(lhs) == static_cast<T2&&>(rhs))
323 {
324 return static_cast<T1&&>(lhs) == static_cast<T2&&>(rhs);
325 }
326 };
327#endif
328
329 //***************************************************************************
330 template <typename T = void>
331 struct not_equal_to : public etl::binary_function<T, T, bool>
332 {
333 typedef T value_type;
334
335 ETL_CONSTEXPR bool operator()(const T& lhs, const T& rhs) const
336 {
337 return !(lhs == rhs);
338 }
339 };
340
341#if ETL_USING_CPP11
342 template <>
343 struct not_equal_to<void> : public etl::binary_function<void, void, bool>
344 {
345 typedef int is_transparent;
346
347 template <typename T1, typename T2>
348 constexpr auto operator()(T1&& lhs, T2&& rhs) const -> decltype(!(static_cast<T1&&>(lhs) == static_cast<T2&&>(rhs)))
349 {
350 return !(static_cast<T1&&>(lhs) == static_cast<T2&&>(rhs));
351 }
352 };
353#endif
354
355 //***************************************************************************
356 template <typename TFunction>
357 class binder1st : public etl::unary_function<typename TFunction::second_argument_type, typename TFunction::result_type>
358 {
359 protected:
360
361 TFunction operation;
362 typename TFunction::first_argument_type value;
363
364 public:
365
366 binder1st(const TFunction& f, const typename TFunction::first_argument_type& v)
367 : operation(f)
368 , value(v)
369 {
370 }
371
372 typename TFunction::result_type operator()(typename TFunction::second_argument_type& x) const
373 {
374 return operation(value, x);
375 }
376
377 typename TFunction::result_type operator()(const typename TFunction::second_argument_type& x) const
378 {
379 return operation(value, x);
380 }
381 };
382
383 template <typename F, typename T>
384 binder1st<F> bind1st(const F& f, const T& x)
385 {
386 return binder1st<F>(f, x);
387 }
388
389 //***************************************************************************
390 template <typename TFunction >
391 class binder2nd : public etl::unary_function<typename TFunction::first_argument_type, typename TFunction::result_type>
392 {
393 protected:
394
395 TFunction operation;
396 typename TFunction::second_argument_type value;
397
398 public:
399
400 binder2nd(const TFunction& f, const typename TFunction::second_argument_type& v)
401 : operation(f)
402 , value(v)
403 {
404 }
405
406 typename TFunction::result_type operator()(typename TFunction::first_argument_type& x) const
407 {
408 return operation(x, value);
409 }
410
411 typename TFunction::result_type operator()(const typename TFunction::first_argument_type& x) const
412 {
413 return operation(x, value);
414 }
415 };
416
417 template <typename F, typename T>
418 binder2nd<F> bind2nd(const F& f, const T& x)
419 {
420 return binder2nd<F>(f, x);
421 }
422
423 //***************************************************************************
424 template <typename T = void>
425 struct plus
426 {
427 typedef T first_argument_type;
428 typedef T second_argument_type;
429 typedef T result_type;
430
431 ETL_CONSTEXPR T operator()(const T& lhs, const T& rhs) const
432 {
433 return lhs + rhs;
434 }
435 };
436
437 //***************************************************************************
438 template <typename T = void>
439 struct minus
440 {
441 typedef T first_argument_type;
442 typedef T second_argument_type;
443 typedef T result_type;
444
445 ETL_CONSTEXPR T operator()(const T& lhs, const T& rhs) const
446 {
447 return lhs - rhs;
448 }
449 };
450
451 //***************************************************************************
452 template <typename T = void>
453 struct negate
454 {
455 typedef T argument_type;
456 typedef T result_type;
457
458 ETL_CONSTEXPR T operator()(const T& lhs) const
459 {
460 return -lhs;
461 }
462 };
463
464 //***************************************************************************
465 template <typename T = void>
467 {
468 typedef T first_argument_type;
469 typedef T second_argument_type;
470 typedef T result_type;
471
472 ETL_CONSTEXPR T operator()(const T& lhs, const T& rhs) const
473 {
474 return lhs * rhs;
475 }
476 };
477
478 //***************************************************************************
479 template <typename T = void>
480 struct divides
481 {
482 typedef T first_argument_type;
483 typedef T second_argument_type;
484 typedef T result_type;
485
486 ETL_CONSTEXPR T operator()(const T& lhs, const T& rhs) const
487 {
488 return lhs / rhs;
489 }
490 };
491
492 //***************************************************************************
493 template <typename T = void>
494 struct modulus
495 {
496 typedef T first_argument_type;
497 typedef T second_argument_type;
498 typedef T result_type;
499
500 ETL_CONSTEXPR T operator()(const T& lhs, const T& rhs) const
501 {
502 return lhs % rhs;
503 }
504 };
505
506 //***************************************************************************
507 template <typename T = void>
509 {
510 typedef T first_argument_type;
511 typedef T second_argument_type;
512 typedef T result_type;
513
514 ETL_CONSTEXPR T operator()(const T& lhs, const T& rhs) const
515 {
516 return lhs && rhs;
517 }
518 };
519
520 //***************************************************************************
521 template <typename T = void>
523 {
524 typedef T first_argument_type;
525 typedef T second_argument_type;
526 typedef T result_type;
527
528 ETL_CONSTEXPR T operator()(const T& lhs, const T& rhs) const
529 {
530 return lhs || rhs;
531 }
532 };
533
534 //***************************************************************************
535 template <typename T = void>
537 {
538 typedef T first_argument_type;
539 typedef T second_argument_type;
540 typedef T result_type;
541
542 ETL_CONSTEXPR T operator()(const T& lhs) const
543 {
544 return !lhs;
545 }
546 };
547
548 //***************************************************************************
549 template <typename T = void>
550 struct bit_and
551 {
552 typedef T first_argument_type;
553 typedef T second_argument_type;
554 typedef T result_type;
555
556 ETL_CONSTEXPR T operator()(const T& lhs, const T& rhs) const
557 {
558 return lhs & rhs;
559 }
560 };
561
562 //***************************************************************************
563 template <typename T = void>
564 struct bit_or
565 {
566 typedef T first_argument_type;
567 typedef T second_argument_type;
568 typedef T result_type;
569
570 ETL_CONSTEXPR T operator()(const T& lhs, const T& rhs) const
571 {
572 return lhs | rhs;
573 }
574 };
575
576 //***************************************************************************
577 template <typename T = void>
578 struct bit_xor
579 {
580 typedef T first_argument_type;
581 typedef T second_argument_type;
582 typedef T result_type;
583
584 ETL_CONSTEXPR T operator()(const T& lhs, const T& rhs) const
585 {
586 return lhs ^ rhs;
587 }
588 };
589
590 //***************************************************************************
591 template <typename T = void>
592 struct bit_not
593 {
594 typedef T first_argument_type;
595 typedef T second_argument_type;
596 typedef T result_type;
597
598 ETL_CONSTEXPR T operator()(const T& lhs) const
599 {
600 return ~lhs;
601 }
602 };
603
604#if ETL_USING_CPP11
605 namespace private_functional
606 {
607 //***************************************************************************
608 template <typename TReturnType, typename TClassType, typename... TArgs>
609 class mem_fn_impl
610 {
611 public:
612
613 typedef TReturnType (TClassType::*MemberFunctionType)(TArgs...);
614
615 ETL_CONSTEXPR mem_fn_impl(MemberFunctionType member_function_)
616 : member_function(member_function_)
617 {
618 }
619
620 ETL_CONSTEXPR TReturnType operator()(TClassType& instance, TArgs... args) const
621 {
622 return (instance.*member_function)(etl::forward<TArgs>(args)...);
623 }
624
625 private:
626
627 MemberFunctionType member_function;
628 };
629
630 //***************************************************************************
631 template <typename TReturnType, typename TClassType, typename... TArgs>
632 class const_mem_fn_impl
633 {
634 public:
635
636 typedef TReturnType (TClassType::*MemberFunctionType)(TArgs...) const;
637
638 ETL_CONSTEXPR const_mem_fn_impl(MemberFunctionType member_function_)
639 : member_function(member_function_)
640 {
641 }
642
643 ETL_CONSTEXPR TReturnType operator()(const TClassType& instance, TArgs... args) const
644 {
645 return (instance.*member_function)(etl::forward<TArgs>(args)...);
646 }
647
648 private:
649
650 MemberFunctionType member_function;
651 };
652 } // namespace private_functional
653
654 //***************************************************************************
655 template <typename TReturnType, typename TClassType, typename... TArgs>
656 ETL_CONSTEXPR private_functional::mem_fn_impl<TReturnType, TClassType, TArgs...> mem_fn(TReturnType (TClassType::*member_function)(TArgs...))
657 {
658 return private_functional::mem_fn_impl<TReturnType, TClassType, TArgs...>(member_function);
659 }
660
661 //***************************************************************************
662 template <typename TReturnType, typename TClassType, typename... TArgs>
663 ETL_CONSTEXPR private_functional::const_mem_fn_impl<TReturnType, TClassType, TArgs...> mem_fn(TReturnType (TClassType::*member_function)(TArgs...)
664 const)
665 {
666 return private_functional::const_mem_fn_impl<TReturnType, TClassType, TArgs...>(member_function);
667 }
668#endif
669
670#if ETL_USING_CPP14
671 struct identity
672 {
673 template <class T>
674 constexpr T&& operator()(T&& t) const noexcept
675 {
676 return etl::forward<T>(t);
677 }
678 };
679#endif
680
681#if ETL_USING_CPP17
682 namespace ranges
683 {
684 struct equal_to
685 {
686 template <typename T, typename U>
687 constexpr auto operator()(T&& t, U&& u) const -> decltype(static_cast<T&&>(t) == static_cast<U&&>(u))
688 {
689 return static_cast<T&&>(t) == static_cast<U&&>(u);
690 }
691 };
692
693 struct less
694 {
695 template <typename T, typename U>
696 constexpr auto operator()(T&& t, U&& u) const -> decltype(static_cast<T&&>(t) < static_cast<U&&>(u))
697 {
698 return static_cast<T&&>(t) < static_cast<U&&>(u);
699 }
700 };
701 } // namespace ranges
702#endif
703
704} // namespace etl
705
706#endif
Definition functional.h:358
Definition functional.h:392
Definition functional.h:51
bitset_ext
Definition absolute.h:40
integral_constant< bool, false > false_type
integral_constant specialisations
Definition type_traits.h:80
binary_function
Definition functional.h:192
Definition functional.h:551
Definition functional.h:593
Definition functional.h:565
Definition functional.h:579
Definition functional.h:481
Definition functional.h:305
Definition functional.h:279
Definition functional.h:253
Definition functional.h:164
Definition functional.h:227
Definition functional.h:201
Definition functional.h:509
Definition functional.h:537
Definition functional.h:523
Definition functional.h:440
Definition functional.h:495
Definition functional.h:467
Definition functional.h:454
Definition functional.h:332
Definition functional.h:426
unary_function
Definition functional.h:182
unwrap_ref_decay.
Definition functional.h:150
unwrap_reference.
Definition functional.h:130