Embedded Template Library 1.0
Loading...
Searching...
No Matches
type_traits.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_TYPE_TRAITS_INCLUDED
32#define ETL_TYPE_TRAITS_INCLUDED
33
34#include "platform.h"
35#include "nullptr.h"
36#include "static_assert.h"
37
38#include <stddef.h>
39#include <stdint.h>
40
45
46#if ETL_USING_STL && ETL_USING_CPP11
47 #include <type_traits>
48#endif
49
50namespace etl
51{
52#if ETL_USING_CPP11
53 template <typename...>
54 using void_t = void;
55#endif
56
57#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED
58
59 //*****************************************************************************
60 // Traits are defined by the ETL
61 //*****************************************************************************
62
63 //***************************************************************************
65 template <typename T, T VALUE>
67 {
68 static const T value = VALUE;
69
70 typedef T value_type;
71 typedef integral_constant<T, VALUE> type;
72
73 operator value_type() const
74 {
75 return value;
76 }
77 };
78
81 typedef integral_constant<bool, true> true_type;
82
83 template <typename T, T VALUE>
84 const T integral_constant<T, VALUE>::value;
85
86 #if ETL_USING_CPP17
87 template <typename T, T VALUE>
88 inline constexpr T integral_constant_v = etl::integral_constant<T, VALUE>::value;
89 #endif
90
91 #if ETL_USING_CPP11
92 template <bool BValue>
94 #else
95 template <bool BValue>
99 #endif
100
101 #if ETL_USING_CPP17
102 template <bool BValue>
103 inline constexpr bool bool_constant_v = bool_constant<BValue>::value;
104 #endif
105
106 //***************************************************************************
108 template <typename T>
109 struct negation : etl::bool_constant<!bool(T::value)>
110 {
111 };
112
113 #if ETL_USING_CPP17
114 template <typename T>
115 inline constexpr bool negation_v = negation<T>::value;
116 #endif
117
118 //***************************************************************************
120 template <typename T>
122 {
123 typedef T type;
124 };
125 template <typename T>
127 {
128 typedef T type;
129 };
130 #if ETL_USING_CPP11
131 template <typename T>
132 struct remove_reference<T&&>
133 {
134 typedef T type;
135 };
136 #endif
137
138 #if ETL_USING_CPP11
139 template <typename T>
140 using remove_reference_t = typename remove_reference<T>::type;
141 #endif
142
143 //***************************************************************************
145 template <typename T>
147 {
148 typedef T type;
149 };
150 template <typename T>
151 struct remove_pointer<T*>
152 {
153 typedef T type;
154 };
155 template <typename T>
156 struct remove_pointer<const T*>
157 {
158 typedef const T type;
159 };
160 template <typename T>
161 struct remove_pointer<volatile T*>
162 {
163 typedef volatile T type;
164 };
165 template <typename T>
166 struct remove_pointer<const volatile T*>
167 {
168 typedef const volatile T type;
169 };
170 template <typename T>
171 struct remove_pointer<T* const>
172 {
173 typedef T type;
174 };
175 template <typename T>
176 struct remove_pointer<const T* const>
177 {
178 typedef const T type;
179 };
180 template <typename T>
181 struct remove_pointer<volatile T* const>
182 {
183 typedef volatile T type;
184 };
185 template <typename T>
186 struct remove_pointer<const volatile T* const>
187 {
188 typedef const volatile T type;
189 };
190
191 #if ETL_USING_CPP11
192 template <typename T>
193 using remove_pointer_t = typename remove_pointer<T>::type;
194 #endif
195
196 //***************************************************************************
198 template <typename T>
200 {
201 typedef typename remove_reference<T>::type* type;
202 };
203
204 #if ETL_USING_CPP11
205 template <typename T>
206 using add_pointer_t = typename add_pointer<T>::type;
207 #endif
208
209 //***************************************************************************
211 template <typename T>
213 {
214 };
215 template <typename T>
216 struct is_const<const T> : true_type
217 {
218 };
219 template <typename T>
220 struct is_const<const volatile T> : true_type
221 {
222 };
223
224 #if ETL_USING_CPP17
225 template <typename T>
226 inline constexpr bool is_const_v = is_const<T>::value;
227 #endif
228
229 //***************************************************************************
231 template <typename T>
233 {
234 typedef T type;
235 };
236 template <typename T>
237 struct remove_const<const T>
238 {
239 typedef T type;
240 };
241
242 #if ETL_USING_CPP11
243 template <typename T>
244 using remove_const_t = typename remove_const<T>::type;
245 #endif
246
247 //***************************************************************************
249 template <typename T>
251 {
252 typedef const T type;
253 };
254 template <typename T>
255 struct add_const<const T>
256 {
257 typedef const T type;
258 };
259
260 #if ETL_USING_CPP11
261 template <typename T>
262 using add_const_t = typename add_const<T>::type;
263 #endif
264
265 //***************************************************************************
267 template <typename T>
269 {
270 };
271 template <typename T>
272 struct is_volatile<volatile T> : true_type
273 {
274 };
275 template <typename T>
276 struct is_volatile<const volatile T> : true_type
277 {
278 };
279
280 #if ETL_USING_CPP17
281 template <typename T>
282 inline constexpr bool is_volatile_v = is_volatile<T>::value;
283 #endif
284
285 //***************************************************************************
287 template <typename T>
289 {
290 typedef T type;
291 };
292 template <typename T>
293 struct remove_volatile<volatile T>
294 {
295 typedef T type;
296 };
297
298 #if ETL_USING_CPP11
299 template <typename T>
300 using remove_volatile_t = typename remove_volatile<T>::type;
301 #endif
302
303 //***************************************************************************
305 template <typename T>
307 {
308 typedef volatile T type;
309 };
310 template <typename T>
311 struct add_volatile<volatile T>
312 {
313 typedef volatile T type;
314 };
315
316 #if ETL_USING_CPP11
317 template <typename T>
318 using add_volatile_t = typename add_volatile<T>::type;
319 #endif
320
321 //***************************************************************************
323 template <typename T>
325 {
326 typedef typename remove_volatile<typename remove_const<T>::type>::type type;
327 };
328
329 #if ETL_USING_CPP11
330 template <typename T>
331 using remove_cv_t = typename remove_cv<T>::type;
332 #endif
333
334 //***************************************************************************
336 template <typename T>
337 struct add_cv
338 {
339 typedef typename add_volatile<typename add_const<T>::type>::type type;
340 };
341
342 #if ETL_USING_CPP11
343 template <typename T>
344 using add_cv_t = typename add_cv<T>::type;
345 #endif
346
347 //***************************************************************************
349 template <typename T>
351 {
352 typedef typename remove_cv<typename remove_reference<T>::type>::type type;
353 };
354
355 #if ETL_USING_CPP11
356 template <typename T>
357 using remove_cvref_t = typename remove_cvref<T>::type;
358 #endif
359
360 //***************************************************************************
362 template <typename T>
364 {
365 };
366 template <>
367 struct is_integral<bool> : true_type
368 {
369 };
370 template <>
371 struct is_integral<char> : true_type
372 {
373 };
374 template <>
375 struct is_integral<unsigned char> : true_type
376 {
377 };
378 template <>
379 struct is_integral<signed char> : true_type
380 {
381 };
382 template <>
383 struct is_integral<wchar_t> : true_type
384 {
385 };
386 template <>
387 struct is_integral<short> : true_type
388 {
389 };
390 template <>
391 struct is_integral<unsigned short> : true_type
392 {
393 };
394 template <>
395 struct is_integral<int> : true_type
396 {
397 };
398 template <>
399 struct is_integral<unsigned int> : true_type
400 {
401 };
402 template <>
403 struct is_integral<long> : true_type
404 {
405 };
406 template <>
407 struct is_integral<unsigned long> : true_type
408 {
409 };
410 template <>
411 struct is_integral<long long> : true_type
412 {
413 };
414 template <>
415 struct is_integral<unsigned long long> : true_type
416 {
417 };
418 #if ETL_HAS_NATIVE_CHAR8_T
419 template <>
420 struct is_integral<char8_t> : true_type
421 {
422 };
423 #endif
424 #if ETL_HAS_NATIVE_CHAR16_T
425 template <>
426 struct is_integral<char16_t> : true_type
427 {
428 };
429 #endif
430 #if ETL_HAS_NATIVE_CHAR32_T
431 template <>
432 struct is_integral<char32_t> : true_type
433 {
434 };
435 #endif
436 template <typename T>
437 struct is_integral<const T> : is_integral<T>
438 {
439 };
440 template <typename T>
441 struct is_integral<volatile T> : is_integral<T>
442 {
443 };
444 template <typename T>
445 struct is_integral<const volatile T> : is_integral<T>
446 {
447 };
448
449 #if ETL_USING_CPP17
450 template <typename T>
451 inline constexpr bool is_integral_v = is_integral<T>::value;
452 #endif
453
454 //***************************************************************************
456 template <typename T>
458 {
459 };
460 template <>
461 struct is_signed<char> : etl::bool_constant<(char(255) < 0)>
462 {
463 };
464 template <>
465 struct is_signed<wchar_t> : public etl::bool_constant<wchar_t(-1) < wchar_t(0)>
466 {
467 };
468 template <>
469 struct is_signed<signed char> : true_type
470 {
471 };
472 template <>
473 struct is_signed<short> : true_type
474 {
475 };
476 template <>
477 struct is_signed<int> : true_type
478 {
479 };
480 template <>
481 struct is_signed<long> : true_type
482 {
483 };
484 template <>
485 struct is_signed<long long> : true_type
486 {
487 };
488 template <>
489 struct is_signed<float> : true_type
490 {
491 };
492 template <>
493 struct is_signed<double> : true_type
494 {
495 };
496 template <>
497 struct is_signed<long double> : true_type
498 {
499 };
500 #if ETL_HAS_NATIVE_CHAR8_T
501 template <>
502 struct is_signed<char8_t> : false_type
503 {
504 };
505 #endif
506 #if ETL_HAS_NATIVE_CHAR16_T
507 template <>
508 struct is_signed<char16_t> : false_type
509 {
510 };
511 #endif
512 #if ETL_HAS_NATIVE_CHAR32_T
513 template <>
514 struct is_signed<char32_t> : false_type
515 {
516 };
517 #endif
518 template <typename T>
519 struct is_signed<const T> : is_signed<T>
520 {
521 };
522 template <typename T>
523 struct is_signed<volatile T> : is_signed<T>
524 {
525 };
526 template <typename T>
527 struct is_signed<const volatile T> : is_signed<T>
528 {
529 };
530
531 #if ETL_USING_CPP17
532 template <typename T>
533 inline constexpr bool is_signed_v = is_signed<T>::value;
534 #endif
535
536 //***************************************************************************
538 template <typename T>
539 struct is_unsigned : false_type
540 {
541 };
542 template <>
543 struct is_unsigned<bool> : true_type
544 {
545 };
546 template <>
547 struct is_unsigned<char> : etl::bool_constant<(char(255) > 0)>
548 {
549 };
550 template <>
551 struct is_unsigned<unsigned char> : true_type
552 {
553 };
554 template <>
555 struct is_unsigned<wchar_t> : public etl::bool_constant<(wchar_t(-1) > wchar_t(0))>{};
556 template <>
557 struct is_unsigned<unsigned short> : true_type
558 {
559 };
560 template <>
561 struct is_unsigned<unsigned int> : true_type
562 {
563 };
564 template <>
565 struct is_unsigned<unsigned long> : true_type
566 {
567 };
568 template <>
569 struct is_unsigned<unsigned long long> : true_type
570 {
571 };
572 #if ETL_HAS_NATIVE_CHAR8_T
573 template <>
574 struct is_unsigned<char8_t> : true_type
575 {
576 };
577 #endif
578 #if ETL_HAS_NATIVE_CHAR16_T
579 template <>
580 struct is_unsigned<char16_t> : true_type
581 {
582 };
583 #endif
584 #if ETL_HAS_NATIVE_CHAR32_T
585 template <>
586 struct is_unsigned<char32_t> : true_type
587 {
588 };
589 #endif
590 template <typename T>
591 struct is_unsigned<const T> : is_unsigned<T>
592 {
593 };
594 template <typename T>
595 struct is_unsigned<volatile T> : is_unsigned<T>
596 {
597 };
598 template <typename T>
599 struct is_unsigned<const volatile T> : is_unsigned<T>
600 {
601 };
602
603 #if ETL_USING_CPP17
604 template <typename T>
605 inline constexpr bool is_unsigned_v = is_unsigned<T>::value;
606 #endif
607
608 //***************************************************************************
610 template <typename T>
611 struct is_floating_point : false_type
612 {
613 };
614 template <>
615 struct is_floating_point<float> : true_type
616 {
617 };
618 template <>
619 struct is_floating_point<double> : true_type
620 {
621 };
622 template <>
623 struct is_floating_point<long double> : true_type
624 {
625 };
626 template <typename T>
627 struct is_floating_point<const T> : is_floating_point<T>
628 {
629 };
630 template <typename T>
631 struct is_floating_point<volatile T> : is_floating_point<T>
632 {
633 };
634 template <typename T>
635 struct is_floating_point<const volatile T> : is_floating_point<T>
636 {
637 };
638
639 #if ETL_USING_CPP17
640 template <typename T>
641 inline constexpr bool is_floating_point_v = is_floating_point<T>::value;
642 #endif
643
644 //***************************************************************************
646 template <typename T1, typename T2>
647 struct is_same : public false_type
648 {
649 };
650 template <typename T>
651 struct is_same<T, T> : public true_type
652 {
653 };
654
655 #if ETL_USING_CPP17
656 template <typename T1, typename T2>
657 inline constexpr bool is_same_v = is_same<T1, T2>::value;
658 #endif
659
660 //***************************************************************************
662 template <typename T>
663 struct is_void : false_type
664 {
665 };
666 template <>
667 struct is_void<void> : true_type
668 {
669 };
670 template <>
671 struct is_void<const void> : true_type
672 {
673 };
674 template <>
675 struct is_void<volatile void> : true_type
676 {
677 };
678 template <>
679 struct is_void<const volatile void> : true_type
680 {
681 };
682
683 #if ETL_USING_CPP17
684 template <typename T>
685 inline constexpr bool is_void_v = is_void<T>::value;
686 #endif
687
688 //***************************************************************************
690 template <typename T>
691 struct is_arithmetic : etl::bool_constant<is_integral<T>::value || is_floating_point<T>::value>
692 {
693 };
694
695 #if ETL_USING_CPP17
696 template <typename T>
697 inline constexpr bool is_arithmetic_v = is_arithmetic<T>::value;
698 #endif
699
700 //***************************************************************************
702 template <typename T>
703 struct is_fundamental : etl::bool_constant<is_arithmetic<T>::value || is_void<T>::value>
704 {
705 };
706
707 #if ETL_USING_CPP17
708 template <typename T>
709 inline constexpr bool is_fundamental_v = is_fundamental<T>::value;
710 #endif
711
712 //***************************************************************************
714 template <typename T>
715 struct is_compound : etl::bool_constant<!is_fundamental<T>::value>
716 {
717 };
718
719 #if ETL_USING_CPP17
720 template <typename T>
721 inline constexpr bool is_compound_v = is_compound<T>::value;
722 #endif
723
724 //***************************************************************************
726 template <typename T>
727 struct is_array : false_type
728 {
729 };
730 template <typename T>
731 struct is_array<T[]> : true_type
732 {
733 };
734 template <typename T, size_t Size>
735 struct is_array<T[Size]> : true_type
736 {
737 };
738
739 #if ETL_USING_CPP17
740 template <typename T>
741 inline constexpr bool is_array_v = is_array<T>::value;
742 #endif
743
744 //***************************************************************************
746 template <typename T>
747 struct is_pointer_helper : false_type
748 {
749 };
750 template <typename T>
751 struct is_pointer_helper<T*> : true_type
752 {
753 };
754 template <typename T>
755 struct is_pointer_helper<const T*> : is_pointer_helper<T*>
756 {
757 };
758 template <typename T>
759 struct is_pointer_helper<volatile T*> : is_pointer_helper<T*>
760 {
761 };
762 template <typename T>
763 struct is_pointer_helper<const volatile T*> : is_pointer_helper<T*>
764 {
765 };
766 template <typename T>
767 struct is_pointer : is_pointer_helper<typename remove_cv<T>::type>
768 {
769 };
770
771 #if ETL_USING_CPP17
772 template <typename T>
773 inline constexpr bool is_pointer_v = is_pointer<T>::value;
774 #endif
775
776 //***************************************************************************
778 template <typename T>
779 struct is_lvalue_reference_helper : false_type
780 {
781 };
782 template <typename T>
783 struct is_lvalue_reference_helper<T&> : true_type
784 {
785 };
786 template <typename T>
787 struct is_lvalue_reference : is_lvalue_reference_helper<typename remove_cv<T>::type>
788 {
789 };
790
791 #if ETL_USING_CPP17
792 template <typename T>
793 inline constexpr bool is_lvalue_reference_v = etl::is_lvalue_reference<T>::value;
794 #endif
795
796 #if ETL_USING_CPP11
797 //***************************************************************************
799 template <typename T>
800 struct is_rvalue_reference_helper : false_type
801 {
802 };
803 template <typename T>
804 struct is_rvalue_reference_helper<T&&> : true_type
805 {
806 };
807 template <typename T>
808 struct is_rvalue_reference : is_rvalue_reference_helper<typename remove_cv<T>::type>
809 {
810 };
811
812 #if ETL_USING_CPP17
813 template <typename T>
814 inline constexpr bool is_rvalue_reference_v = etl::is_rvalue_reference<T>::value;
815 #endif
816 #endif
817
818 //***************************************************************************
820 // Either lvalue or rvalue (for CPP11)
821 template <typename T>
822 struct is_reference
823 : integral_constant<bool, is_lvalue_reference<T>::value
824 #if ETL_USING_CPP11
825 || is_rvalue_reference<T>::value
826 #endif
827 >
828 {
829 };
830
831 #if ETL_USING_CPP17
832 template <typename T>
833 inline constexpr bool is_reference_v = is_reference<T>::value;
834 #endif
835
836 //***************************************************************************
839 template <typename T>
840 struct is_pod : etl::bool_constant<etl::is_fundamental<T>::value || etl::is_pointer<T>::value>
841 {
842 };
843
844 #if ETL_USING_CPP17
845 template <typename T>
846 inline constexpr bool is_pod_v = etl::is_pod<T>::value;
847 #endif
848
849 //***************************************************************************
851 template <bool BValue, typename T, typename F>
852 struct conditional
853 {
854 typedef T type;
855 };
856 template <typename T, typename F>
857 struct conditional<false, T, F>
858 {
859 typedef F type;
860 };
861
862 #if ETL_USING_CPP11
863 template <bool BValue, typename T, typename F>
864 using conditional_t = typename conditional<BValue, T, F>::type;
865 #endif
866
867 //***************************************************************************
869 template <typename T>
870 struct make_signed
871 {
872 typedef T type;
873 };
874 template <>
875 struct make_signed<char>
876 {
877 typedef signed char type;
878 };
879 template <>
880 struct make_signed<unsigned char>
881 {
882 typedef signed char type;
883 };
884
885 template <>
886 struct make_signed<wchar_t>
887 {
888 typedef etl::conditional< sizeof(wchar_t) == sizeof(int16_t), int16_t,
889 etl::conditional<sizeof(wchar_t) == sizeof(int32_t), int32_t, void>::type>::type type;
890 };
891
892 template <>
893 struct make_signed<unsigned short>
894 {
895 typedef short type;
896 };
897 template <>
898 struct make_signed<unsigned int>
899 {
900 typedef int type;
901 };
902 template <>
903 struct make_signed<unsigned long>
904 {
905 typedef long type;
906 };
907 template <>
908 struct make_signed<unsigned long long>
909 {
910 typedef long long type;
911 };
912 template <typename T>
913 struct make_signed<const T> : add_const<typename make_signed<T>::type>
914 {
915 };
916 template <typename T>
917 struct make_signed<volatile T> : add_volatile<typename make_signed<T>::type>
918 {
919 };
920 template <typename T>
921 struct make_signed<const volatile T> : add_const<typename add_volatile<typename make_signed<T>::type>::type>
922 {
923 };
924
925 #if ETL_USING_CPP11
926 template <typename T>
927 using make_signed_t = typename make_signed<T>::type;
928 #endif
929
930 //***************************************************************************
932 template <typename T>
933 struct make_unsigned
934 {
935 typedef T type;
936 };
937 template <>
938 struct make_unsigned<char>
939 {
940 typedef unsigned char type;
941 };
942 template <>
943 struct make_unsigned<signed char>
944 {
945 typedef unsigned char type;
946 };
947 template <>
948 struct make_unsigned<short>
949 {
950 typedef unsigned short type;
951 };
952
953 template <>
954 struct make_unsigned<wchar_t>
955 {
956 typedef etl::conditional< sizeof(wchar_t) == sizeof(uint16_t), uint16_t,
957 etl::conditional<sizeof(wchar_t) == sizeof(uint32_t), uint32_t, void>::type>::type type;
958 };
959
960 template <>
961 struct make_unsigned<int>
962 {
963 typedef unsigned int type;
964 };
965 template <>
966 struct make_unsigned<long>
967 {
968 typedef unsigned long type;
969 };
970 template <>
971 struct make_unsigned<long long>
972 {
973 typedef unsigned long long type;
974 };
975 template <typename T>
976 struct make_unsigned<const T> : add_const<typename make_unsigned<T>::type>
977 {
978 };
979 template <typename T>
980 struct make_unsigned<volatile T> : add_volatile<typename make_unsigned<T>::type>
981 {
982 };
983 template <typename T>
984 struct make_unsigned<const volatile T> : add_const<typename add_volatile<typename make_unsigned<T>::type>::type>
985 {
986 };
987
988 #if ETL_USING_CPP11
989 template <typename T>
990 using make_unsigned_t = typename make_unsigned<T>::type;
991 #endif
992
993 //***************************************************************************
995 template <bool BValue, typename T = void>
996 struct enable_if
997 {
998 };
999 template <typename T>
1000 struct enable_if<true, T>
1001 {
1002 typedef T type;
1003 };
1004
1005 #if ETL_USING_CPP11
1006 template <bool BValue, typename T = void>
1007 using enable_if_t = typename enable_if<BValue, T>::type;
1008 #endif
1009
1010 //***************************************************************************
1012 template <typename T, unsigned Size = 0U>
1013 struct extent : integral_constant<size_t, 0U>
1014 {
1015 };
1016
1017 template <typename T>
1018 struct extent<T[], 0> : integral_constant<size_t, 0U>
1019 {
1020 };
1021
1022 template <typename T, unsigned Size>
1023 struct extent<T[], Size> : integral_constant<size_t, extent<T, Size - 1>::value>
1024 {
1025 };
1026
1027 template <typename T, unsigned Size>
1028 struct extent<T[Size], 0> : integral_constant<size_t, Size>
1029 {
1030 };
1031
1032 template <typename T, unsigned I, unsigned Size>
1033 struct extent<T[I], Size> : integral_constant<size_t, extent<T, Size - 1>::value>
1034 {
1035 };
1036
1037 #if ETL_USING_CPP17
1038 template <typename T, unsigned Size = 0U>
1039 inline constexpr size_t extent_v = extent<T, Size>::value;
1040 #endif
1041
1042 //***************************************************************************
1044 template <typename T>
1045 struct remove_extent
1046 {
1047 typedef T type;
1048 };
1049 template <typename T>
1050 struct remove_extent<T[]>
1051 {
1052 typedef T type;
1053 };
1054 template <typename T, size_t Size>
1055 struct remove_extent<T[Size]>
1056 {
1057 typedef T type;
1058 };
1059
1060 #if ETL_USING_CPP11
1061 template <typename T>
1062 using remove_extent_t = typename remove_extent<T>::type;
1063 #endif
1064
1065 //***************************************************************************
1067 template <typename T>
1068 struct remove_all_extents
1069 {
1070 typedef T type;
1071 };
1072 template <typename T>
1073 struct remove_all_extents<T[]>
1074 {
1075 typedef typename remove_all_extents<T>::type type;
1076 };
1077 template <typename T, size_t Size>
1078 struct remove_all_extents<T[Size]>
1079 {
1080 typedef typename remove_all_extents<T>::type type;
1081 };
1082
1083 #if ETL_USING_CPP11
1084 template <typename T>
1085 using remove_all_extents_t = typename remove_all_extents<T>::type;
1086 #endif
1087
1088 //***************************************************************************
1090 template <typename T>
1091 struct rank : integral_constant<size_t, 0>
1092 {
1093 };
1094 template <typename T>
1095 struct rank<T[]> : public integral_constant<size_t, rank<T>::value + 1>
1096 {
1097 };
1098 template <typename T, size_t Size>
1099 struct rank<T[Size]> : public integral_constant<size_t, rank<T>::value + 1>
1100 {
1101 };
1102
1103 #if ETL_USING_CPP17
1104 template <typename T>
1105 inline constexpr size_t rank_v = rank<T>::value;
1106 #endif
1107
1108 //***************************************************************************
1110 template <typename T>
1111 struct decay
1112 {
1113 typedef typename etl::remove_reference<T>::type U;
1114 typedef typename etl::conditional<etl::is_array<U>::value, typename etl::remove_extent<U>::type*, typename etl::remove_cv<U>::type>::type type;
1115 };
1116
1117 #if ETL_USING_CPP11
1118 template <typename T>
1119 using decay_t = typename decay<T>::type;
1120 #endif
1121
1122 //***************************************************************************
1124 namespace private_type_traits
1125 {
1126 template <typename T>
1127 char test(int T::*); // Match for classes.
1128
1129 struct dummy
1130 {
1131 char c[2];
1132 };
1133 template <typename T>
1134 dummy test(...); // Match for non-classes.
1135 } // namespace private_type_traits
1136
1137 template <typename T>
1138 struct is_class : etl::bool_constant<sizeof(private_type_traits::test<T>(0)) == 1U>
1139 {
1140 };
1141
1142 #if ETL_USING_CPP17
1143 template <typename T>
1144 inline constexpr bool is_class_v = is_class<T>::value;
1145 #endif
1146
1147 //***************************************************************************
1149 #if ETL_USING_CPP11
1150 namespace private_type_traits
1151 {
1152 template <typename B>
1153 etl::true_type test_ptr_conv(const volatile B*);
1154 template <typename>
1155 etl::false_type test_ptr_conv(const volatile void*);
1156
1157 template <typename B, typename D>
1158 auto test_is_base_of(int) -> decltype(test_ptr_conv<B>(static_cast<D*>(nullptr)));
1159 template <typename, typename>
1160 auto test_is_base_of(...) -> etl::true_type; // private or ambiguous base
1161 } // namespace private_type_traits
1162
1163 template <typename TBase, typename TDerived>
1164 struct is_base_of
1165 : etl::integral_constant< bool, etl::is_class<TBase>::value
1166 && etl::is_class<TDerived>::value&& decltype(private_type_traits::test_is_base_of< TBase, TDerived>(0))::value >
1167 {
1168 };
1169 #else
1170 template <typename TBase, typename TDerived,
1171 const bool IsFundamental = (etl::is_fundamental<TBase>::value || etl::is_fundamental<TDerived>::value || etl::is_array<TDerived>::value)>
1172 struct is_base_of
1173 {
1174 private:
1175
1176 static TBase* check(TBase*)
1177 {
1178 return (TBase*)0;
1179 }
1180 static char check(...)
1181 {
1182 return 0;
1183 }
1184
1185 public:
1186
1187 static const bool value = (sizeof(check((TDerived*)0)) == sizeof(TBase*));
1188 };
1189
1190 // For when TBase or TDerived is a fundamental type.
1191 template <typename TBase, typename TDerived>
1192 struct is_base_of<TBase, TDerived, true>
1193 {
1194 static const bool value = false;
1195 };
1196 #endif
1197
1198 #if ETL_USING_CPP17
1199 template <typename T1, typename T2>
1200 inline constexpr bool is_base_of_v = is_base_of<T1, T2>::value;
1201 #endif
1202
1203 //***************************************************************************
1206 #if ETL_USING_CPP11 && ETL_USING_BUILTIN_IS_VIRTUAL_BASE_OF
1207 template <typename TBase, typename TDerived>
1208 struct is_virtual_base_of : etl::bool_constant<__is_virtual_base_of(TBase, TDerived)>
1209 {
1210 };
1211
1212 #if ETL_USING_CPP17
1213 template <typename TBase, typename TDerived>
1214 inline constexpr bool is_virtual_base_of_v = is_virtual_base_of<TBase, TDerived>::value;
1215 #endif
1216 #endif
1217
1218 //***************************************************************************
1220 template <typename T>
1221 struct add_lvalue_reference
1222 {
1223 typedef T& type;
1224 };
1225 template <typename T>
1226 struct add_lvalue_reference<T&>
1227 {
1228 typedef T& type;
1229 };
1230 template <>
1231 struct add_lvalue_reference<void>
1232 {
1233 typedef void type;
1234 };
1235 template <>
1236 struct add_lvalue_reference<const void>
1237 {
1238 typedef const void type;
1239 };
1240 template <>
1241 struct add_lvalue_reference<volatile void>
1242 {
1243 typedef volatile void type;
1244 };
1245 template <>
1246 struct add_lvalue_reference<const volatile void>
1247 {
1248 typedef const volatile void type;
1249 };
1250
1251 #if ETL_USING_CPP11
1252 template <typename T>
1253 using add_lvalue_reference_t = typename etl::add_lvalue_reference<T>::type;
1254 #endif
1255
1256 //***************************************************************************
1258 #if ETL_USING_CPP11
1259 template <typename T>
1260 struct add_rvalue_reference
1261 {
1262 using type = T&&;
1263 };
1264 template <typename T>
1265 struct add_rvalue_reference<T&>
1266 {
1267 using type = T&;
1268 };
1269 template <>
1270 struct add_rvalue_reference<void>
1271 {
1272 using type = void;
1273 };
1274 template <>
1275 struct add_rvalue_reference<const void>
1276 {
1277 using type = const void;
1278 };
1279 template <>
1280 struct add_rvalue_reference<volatile void>
1281 {
1282 using type = volatile void;
1283 };
1284 template <>
1285 struct add_rvalue_reference<const volatile void>
1286 {
1287 using type = const volatile void;
1288 };
1289 #endif
1290
1291 #if ETL_USING_CPP11
1292 template <typename T>
1293 using add_rvalue_reference_t = typename etl::add_rvalue_reference<T>::type;
1294 #endif
1295
1296 //***************************************************************************
1298 #if ETL_USING_CPP11
1299 template <typename T>
1300 typename etl::add_rvalue_reference<T>::type declval() ETL_NOEXCEPT;
1301 #endif
1302
1303 #if ETL_USING_CPP11
1304 //***************************************************************************
1309
1310 namespace private_type_traits
1311 {
1312 // Base case
1313 template <typename T, typename = int>
1314 struct is_convertible_to_int : false_type
1315 {
1316 };
1317
1318 // Selected if `static_cast<int>(declval<T>())` is a valid statement
1319 // 2nd template argument of base case defaults to int to ensure that this
1320 // partial specialization is always tried first
1321 template <typename T>
1322 struct is_convertible_to_int<T, decltype(static_cast<int>(declval<T>()))> : true_type
1323 {
1324 };
1325 } // namespace private_type_traits
1326
1327 template <typename T>
1328 struct is_enum
1329 : integral_constant<bool, private_type_traits::is_convertible_to_int<T>::value && !is_class<T>::value && !is_arithmetic<T>::value
1330 && !is_reference<T>::value>
1331 {
1332 };
1333
1334 #if ETL_USING_CPP17
1335 template <typename T>
1336 inline constexpr bool is_enum_v = etl::is_enum<T>::value;
1337 #endif
1338 #else
1339 namespace private_type_traits
1340 {
1341 // Helper to detect if a type is convertible to an integer
1342 template <typename T>
1343 struct is_convertible_to_int
1344 {
1345 static char test(int); // Match if T is convertible to int
1346 static double test(...); // Fallback for other types
1347
1348 static const bool value = sizeof(test(static_cast<T>(0))) == sizeof(char);
1349 };
1350 } // namespace private_type_traits
1351
1352 // Implementation of is_enum
1353 template <typename T>
1354 struct is_enum
1355 {
1356 static const bool value =
1357 private_type_traits::is_convertible_to_int<T>::value && !is_class<T>::value && !is_arithmetic<T>::value && !is_reference<T>::value;
1358 };
1359 #endif
1360
1361 //***************************************************************************
1364 #if ETL_USING_CPP11
1365 namespace private_type_traits
1366 {
1367 template <typename>
1368 using true_type_for = etl::true_type;
1369
1370 template <typename T>
1371 auto returnable(int) -> true_type_for<T()>;
1372
1373 template <typename>
1374 auto returnable(...) -> etl::false_type;
1375
1376 template <typename TFrom, typename TTo>
1377 auto nonvoid_convertible(int) -> true_type_for< decltype(etl::declval<void (&)(TTo)>()(etl::declval<TFrom>())) >;
1378 template <typename, typename>
1379 auto nonvoid_convertible(...) -> etl::false_type;
1380 } // namespace private_type_traits
1381
1382 #if defined(ETL_COMPILER_ARM5)
1383 template <typename TFrom, typename TTo>
1384 struct is_convertible : etl::bool_constant<__is_convertible_to(TFrom, TTo)>
1385 {
1386 };
1387 #else
1388 template <typename TFrom, typename TTo>
1389 struct is_convertible
1390 : etl::bool_constant< (decltype(private_type_traits::returnable<TTo>(0))::value
1391 && decltype(private_type_traits::nonvoid_convertible<TFrom, TTo>(0))::value)
1392 || (etl::is_void<TFrom>::value && etl::is_void<TTo>::value)>
1393 {
1394 };
1395 #endif
1396
1397 // Is convertible and the conversion is noexcept.
1398 template <typename TFrom, typename TTo>
1399 struct is_nothrow_convertible
1400 {
1401 private:
1402
1403 // Helper: a function taking TTo to require the conversion.
1404 static void sink(TTo) noexcept;
1405
1406 // Selected only if 'sink(declval<TFrom>())' is a valid expression.
1407 template <typename F>
1408 static auto test(int) -> etl::bool_constant<noexcept(sink(etl::declval<F>()))>;
1409
1410 // Fallback if conversion is not viable.
1411 template <typename>
1412 static etl::false_type test(...);
1413
1414 public:
1415
1416 static ETL_CONSTANT bool value = decltype(test<TFrom>(0))::value;
1417 };
1418 #else
1419 namespace private_type_traits
1420 {
1421 typedef char yes;
1422 struct no
1423 {
1424 char dummy[2];
1425 };
1426
1427 template <typename TFrom, typename TTo>
1428 struct is_convertible_impl
1429 {
1430 static yes test(TTo);
1431 static no test(...);
1432 static TFrom make();
1433 static const bool value = (sizeof(test(make())) == sizeof(yes));
1434 };
1435
1436 template <typename TTo>
1437 struct is_convertible_impl<void, TTo>
1438 {
1439 static const bool value = false;
1440 };
1441
1442 template <typename TFrom>
1443 struct is_convertible_impl<TFrom, void>
1444 {
1445 static const bool value = false;
1446 };
1447
1448 template <>
1449 struct is_convertible_impl<void, void>
1450 {
1451 static const bool value = true;
1452 };
1453 } // namespace private_type_traits
1454
1455 template <typename TFrom, typename TTo>
1456 struct is_convertible : etl::bool_constant< private_type_traits::is_convertible_impl<TFrom, TTo>::value>
1457 {
1458 };
1459 #endif
1460
1461 #if ETL_USING_CPP17
1462 template <typename TFrom, typename TTo >
1463 inline constexpr bool is_convertible_v = etl::is_convertible<TFrom, TTo>::value;
1464
1465 template <typename TFrom, typename TTo >
1466 inline constexpr bool is_nothrow_convertible_v = etl::is_nothrow_convertible<TFrom, TTo>::value;
1467 #endif
1468
1469 //***************************************************************************
1472 #if ETL_USING_CPP11 && !defined(ETL_COMPILER_ARM5)
1473 template <typename T>
1474 struct alignment_of : integral_constant<size_t, alignof(T)>
1475 {
1476 };
1477 #elif defined(ETL_COMPILER_MICROSOFT)
1478 template <typename T>
1479 struct alignment_of : integral_constant<size_t, size_t(__alignof(T))>
1480 {
1481 };
1482 #elif defined(ETL_COMPILER_IAR) || defined(ETL_COMPILER_TI)
1483 template <typename T>
1484 struct alignment_of : integral_constant<size_t, size_t(__ALIGNOF__(T))>
1485 {
1486 };
1487 #else
1488 template <typename T>
1489 struct alignment_of : integral_constant<size_t, size_t(__alignof__(T))>
1490 {
1491 };
1492 #endif
1493
1496 template <>
1497 struct alignment_of<void> : integral_constant<size_t, 0>
1498 {
1499 };
1500 template <>
1501 struct alignment_of<const void> : integral_constant<size_t, 0>
1502 {
1503 };
1504
1505 #if ETL_USING_CPP17
1506 template <typename T>
1507 inline constexpr size_t alignment_of_v = etl::alignment_of<T>::value;
1508 #endif
1509
1510#else // Condition = ETL_USING_STL && ETL_USING_CPP11
1511
1512 //*****************************************************************************
1513 // Traits are derived from the STL
1514 //*****************************************************************************
1515
1516 //***************************************************************************
1519 template <typename T, T VALUE>
1520 struct integral_constant : std::integral_constant<T, VALUE>
1521 {
1522 };
1523
1527 typedef integral_constant<bool, true> true_type;
1528
1529 #if ETL_USING_CPP17
1530 template <typename T, T VALUE>
1531 inline constexpr T integral_constant_v = std::integral_constant<T, VALUE>::value;
1532 #endif
1533
1534 #if ETL_USING_CPP17
1535 template <bool BValue>
1536 using bool_constant = std::bool_constant<BValue>;
1537 #else
1538 template <bool BValue>
1539 struct bool_constant : std::integral_constant<bool, BValue>
1540 {
1541 };
1542 #endif
1543
1544 #if ETL_USING_CPP17
1545 template <bool BValue>
1546 inline constexpr bool bool_constant_v = bool_constant<BValue>::value;
1547 #endif
1548
1549 //***************************************************************************
1552 #if ETL_USING_CPP17
1553 template <typename T>
1554 using negation = std::negation<T>;
1555 #else
1556 template <typename T>
1557 struct negation : etl::bool_constant<!bool(T::value)>
1558 {
1559 };
1560 #endif
1561
1562 #if ETL_USING_CPP17
1563 template <typename T>
1564 inline constexpr bool negation_v = std::negation_v<T>;
1565 #endif
1566
1567 //***************************************************************************
1570 template <typename T>
1571 struct remove_reference : std::remove_reference<T>
1572 {
1573 };
1574
1575 #if ETL_USING_CPP11
1576 template <typename T>
1577 using remove_reference_t = typename std::remove_reference<T>::type;
1578 #endif
1579
1580 //***************************************************************************
1583 template <typename T>
1584 struct remove_pointer : std::remove_pointer<T>
1585 {
1586 };
1587
1588 #if ETL_USING_CPP11
1589 template <typename T>
1590 using remove_pointer_t = typename std::remove_pointer<T>::type;
1591 #endif
1592
1593 //***************************************************************************
1596 template <typename T>
1597 struct add_pointer : std::add_pointer<T>
1598 {
1599 };
1600
1601 #if ETL_USING_CPP11
1602 template <typename T>
1603 using add_pointer_t = typename std::add_pointer<T>::type;
1604 #endif
1605
1606 //***************************************************************************
1609 template <typename T>
1610 struct is_const : std::is_const<T>
1611 {
1612 };
1613
1614 #if ETL_USING_CPP17
1615 template <typename T>
1616 inline constexpr bool is_const_v = std::is_const_v<T>;
1617 #endif
1618
1619 //***************************************************************************
1622 template <typename T>
1623 struct remove_const : std::remove_const<T>
1624 {
1625 };
1626
1627 #if ETL_USING_CPP11
1628 template <typename T>
1629 using remove_const_t = typename std::remove_const<T>::type;
1630 #endif
1631
1632 //***************************************************************************
1635 template <typename T>
1636 struct add_const : std::add_const<T>
1637 {
1638 };
1639
1640 #if ETL_USING_CPP11
1641 template <typename T>
1642 using add_const_t = typename std::add_const<T>::type;
1643 #endif
1644
1645 //***************************************************************************
1648 template <typename T>
1649 struct is_volatile : std::is_volatile<T>
1650 {
1651 };
1652
1653 #if ETL_USING_CPP17
1654 template <typename T>
1655 inline constexpr bool is_volatile_v = std::is_volatile_v<T>;
1656 #endif
1657
1658 //***************************************************************************
1661 template <typename T>
1662 struct remove_volatile : std::remove_volatile<T>
1663 {
1664 };
1665
1666 #if ETL_USING_CPP11
1667 template <typename T>
1668 using remove_volatile_t = typename std::remove_volatile<T>::type;
1669 #endif
1670
1671 //***************************************************************************
1674 template <typename T>
1675 struct add_volatile : std::add_volatile<T>
1676 {
1677 };
1678
1679 #if ETL_USING_CPP11
1680 template <typename T>
1681 using add_volatile_t = typename std::add_volatile<T>::type;
1682 #endif
1683
1684 //***************************************************************************
1687 template <typename T>
1688 struct remove_cv : std::remove_cv<T>
1689 {
1690 };
1691
1692 #if ETL_USING_CPP11
1693 template <typename T>
1694 using remove_cv_t = typename std::remove_cv<T>::type;
1695 #endif
1696
1697 //***************************************************************************
1700 template <typename T>
1701 struct add_cv : std::add_cv<T>
1702 {
1703 };
1704
1705 #if ETL_USING_CPP11
1706 template <typename T>
1707 using add_cv_t = typename std::add_cv<T>::type;
1708 #endif
1709
1710 //***************************************************************************
1713 template <typename T>
1714 struct remove_cvref
1715 {
1716 typedef typename std::remove_cv<typename std::remove_reference<T>::type>::type type;
1717 };
1718
1719 #if ETL_USING_CPP11
1720 template <typename T>
1721 using remove_cvref_t = typename etl::remove_cvref<T>::type;
1722 #endif
1723
1724 //***************************************************************************
1727 template <typename T>
1728 struct is_integral : std::is_integral<T>
1729 {
1730 };
1731
1732 #if ETL_USING_CPP17
1733 template <typename T>
1734 inline constexpr bool is_integral_v = std::is_integral_v<T>;
1735 #endif
1736
1737 //***************************************************************************
1740 template <typename T>
1741 struct is_signed : std::is_signed<T>
1742 {
1743 };
1744
1745 #if ETL_USING_CPP17
1746 template <typename T>
1747 inline constexpr bool is_signed_v = std::is_signed_v<T>;
1748 #endif
1749
1750 //***************************************************************************
1753 template <typename T>
1754 struct is_unsigned : std::is_unsigned<T>
1755 {
1756 };
1757
1758 #if ETL_USING_CPP17
1759 template <typename T>
1760 inline constexpr bool is_unsigned_v = std::is_unsigned_v<T>;
1761 #endif
1762
1763 //***************************************************************************
1766 template <typename T>
1767 struct is_floating_point : std::is_floating_point<T>
1768 {
1769 };
1770
1771 #if ETL_USING_CPP17
1772 template <typename T>
1773 inline constexpr bool is_floating_point_v = std::is_floating_point_v<T>;
1774 #endif
1775
1776 //***************************************************************************
1779 template <typename T1, typename T2>
1780 struct is_same : std::is_same<T1, T2>
1781 {
1782 };
1783
1784 #if ETL_USING_CPP17
1785 template <typename T1, typename T2>
1786 inline constexpr bool is_same_v = std::is_same_v<T1, T2>;
1787 #endif
1788
1789 //***************************************************************************
1792 template <typename T>
1793 struct is_void : std::is_void<T>
1794 {
1795 };
1796
1797 #if ETL_USING_CPP17
1798 template <typename T>
1799 inline constexpr bool is_void_v = std::is_void_v<T>;
1800 #endif
1801
1802 //***************************************************************************
1805 template <typename T>
1806 struct is_arithmetic : std::is_arithmetic<T>
1807 {
1808 };
1809
1810 #if ETL_USING_CPP17
1811 template <typename T>
1812 inline constexpr bool is_arithmetic_v = std::is_arithmetic_v<T>;
1813 #endif
1814
1815 //***************************************************************************
1818 template <typename T>
1819 struct is_fundamental : std::is_fundamental<T>
1820 {
1821 };
1822
1823 #if ETL_USING_CPP17
1824 template <typename T>
1825 inline constexpr bool is_fundamental_v = std::is_fundamental_v<T>;
1826 #endif
1827
1828 //***************************************************************************
1831 template <typename T>
1832 struct is_compound : std::is_compound<T>
1833 {
1834 };
1835
1836 #if ETL_USING_CPP17
1837 template <typename T>
1838 inline constexpr bool is_compound_v = std::is_compound_v<T>;
1839 #endif
1840
1841 //***************************************************************************
1844 template <typename T>
1845 struct is_array : std::is_array<T>
1846 {
1847 };
1848
1849 #if ETL_USING_CPP17
1850 template <typename T>
1851 inline constexpr bool is_array_v = std::is_array_v<T>;
1852 #endif
1853
1854 //***************************************************************************
1857 template <typename T>
1858 struct is_pointer : std::is_pointer<T>
1859 {
1860 };
1861
1862 #if ETL_USING_CPP17
1863 template <typename T>
1864 inline constexpr bool is_pointer_v = std::is_pointer_v<T>;
1865 #endif
1866
1867 //***************************************************************************
1870 template <typename T>
1871 struct is_reference : std::is_reference<T>
1872 {
1873 };
1874
1875 #if ETL_USING_CPP17
1876 template <typename T>
1877 inline constexpr bool is_reference_v = std::is_reference_v<T>;
1878 #endif
1879
1880 //***************************************************************************
1883 template <typename T>
1884 struct is_lvalue_reference : std::is_lvalue_reference<T>
1885 {
1886 };
1887
1888 #if ETL_USING_CPP17
1889 template <typename T>
1890 inline constexpr bool is_lvalue_reference_v = std::is_lvalue_reference_v<T>;
1891 #endif
1892
1893 //***************************************************************************
1896 #if ETL_USING_CPP11
1897 template <typename T>
1898 struct is_rvalue_reference : std::is_rvalue_reference<T>
1899 {
1900 };
1901
1902 #if ETL_USING_CPP17
1903 template <typename T>
1904 inline constexpr bool is_rvalue_reference_v = std::is_rvalue_reference_v<T>;
1905 #endif
1906 #endif
1907
1908 //***************************************************************************
1911 template <typename T>
1912 struct is_pod
1913 : std::integral_constant< bool, std::is_standard_layout<T>::value && std::is_trivially_default_constructible<T>::value
1914 && std::is_trivially_copyable<T>::value>
1915 {
1916 };
1917
1918 #if ETL_USING_CPP17
1919 template <typename T>
1920 inline constexpr bool is_pod_v = std::is_standard_layout_v<T> && std::is_trivially_default_constructible_v<T> && std::is_trivially_copyable_v<T>;
1921 #endif
1922
1923 #if defined(ETL_COMPILER_GCC)
1924 #if ETL_COMPILER_VERSION >= 5
1925 #define ETL_GCC_V5_TYPE_TRAITS_SUPPORTED
1926 #endif
1927 #endif
1928
1929 //***************************************************************************
1932 template <bool BValue, typename T, typename F>
1933 struct conditional
1934 {
1935 typedef T type;
1936 };
1937 template <typename T, typename F>
1938 struct conditional<false, T, F>
1939 {
1940 typedef F type;
1941 };
1942
1943 #if ETL_USING_CPP11
1944 template <bool BValue, typename T, typename F>
1945 using conditional_t = typename conditional<BValue, T, F>::type;
1946 #endif
1947
1948 //***************************************************************************
1951 template <typename T>
1952 struct make_signed : std::make_signed<T>
1953 {
1954 };
1955
1956 #if ETL_USING_CPP11
1957 template <typename T>
1958 using make_signed_t = typename std::make_signed<T>::type;
1959 #endif
1960
1961 //***************************************************************************
1964 template <typename T>
1965 struct make_unsigned : std::make_unsigned<T>
1966 {
1967 };
1968
1969 #if ETL_USING_CPP11
1970 template <typename T>
1971 using make_unsigned_t = typename std::make_unsigned<T>::type;
1972 #endif
1973
1974 //***************************************************************************
1977 template <bool BValue, typename T = void>
1978 struct enable_if : std::enable_if<BValue, T>
1979 {
1980 };
1981
1982 #if ETL_USING_CPP11
1983 template <bool BValue, typename T = void>
1984 using enable_if_t = typename std::enable_if<BValue, T>::type;
1985 #endif
1986
1987 //***************************************************************************
1990 template <typename T, unsigned Size = 0U>
1991 struct extent : std::extent<T, Size>
1992 {
1993 };
1994
1995 #if ETL_USING_CPP17
1996 template <typename T, unsigned Size = 0U>
1997 inline constexpr size_t extent_v = std::extent_v<T, Size>;
1998 #endif
1999
2000 //***************************************************************************
2003 template <typename T>
2004 struct remove_extent : std::remove_extent<T>
2005 {
2006 };
2007
2008 #if ETL_USING_CPP11
2009 template <typename T>
2010 using remove_extent_t = typename std::remove_extent<T>::type;
2011 #endif
2012
2013 //***************************************************************************
2016 template <typename T>
2017 struct remove_all_extents : std::remove_all_extents<T>
2018 {
2019 };
2020
2021 #if ETL_USING_CPP11
2022 template <typename T>
2023 using remove_all_extents_t = typename std::remove_all_extents<T>::type;
2024 #endif
2025
2026 //***************************************************************************
2029 template <typename T>
2030 struct rank : std::rank<T>
2031 {
2032 };
2033
2034 #if ETL_USING_CPP17
2035 template <typename T>
2036 inline constexpr size_t rank_v = std::rank_v<T>;
2037 #endif
2038
2039 //***************************************************************************
2042 template <typename T>
2043 struct decay : std::decay<T>
2044 {
2045 };
2046
2047 #if ETL_USING_CPP11
2048 template <typename T>
2049 using decay_t = typename std::decay<T>::type;
2050 #endif
2051
2052 //***************************************************************************
2055 template <typename TBase, typename TDerived>
2056 struct is_base_of : std::is_base_of<TBase, TDerived>
2057 {
2058 };
2059
2060 #if ETL_USING_CPP17
2061 template <typename TBase, typename TDerived>
2062 inline constexpr bool is_base_of_v = std::is_base_of_v<TBase, TDerived>;
2063 #endif
2064
2065 //***************************************************************************
2069 #if ETL_HAS_STD_IS_VIRTUAL_BASE_OF
2070 template <typename TBase, typename TDerived>
2071 struct is_virtual_base_of : std::is_virtual_base_of<TBase, TDerived>
2072 {
2073 };
2074
2075 #if ETL_USING_CPP17
2076 template <typename TBase, typename TDerived>
2077 inline constexpr bool is_virtual_base_of_v = std::is_virtual_base_of_v<TBase, TDerived>;
2078 #endif
2079 #elif ETL_USING_BUILTIN_IS_VIRTUAL_BASE_OF
2080 template <typename TBase, typename TDerived>
2081 struct is_virtual_base_of : etl::bool_constant<__is_virtual_base_of(TBase, TDerived)>
2082 {
2083 };
2084
2085 #if ETL_USING_CPP17
2086 template <typename TBase, typename TDerived>
2087 inline constexpr bool is_virtual_base_of_v = is_virtual_base_of<TBase, TDerived>::value;
2088 #endif
2089 #endif
2090
2091 //***************************************************************************
2093 template <typename T>
2094 struct is_class : std::is_class<T>
2095 {
2096 };
2097
2098 #if ETL_USING_CPP17
2099 template <typename T>
2100 inline constexpr bool is_class_v = is_class<T>::value;
2101 #endif
2102
2103 //***************************************************************************
2105 template <typename T>
2106 struct add_lvalue_reference : std::add_lvalue_reference<T>
2107 {
2108 };
2109
2110 #if ETL_USING_CPP11
2111 template <typename T>
2112 using add_lvalue_reference_t = typename std::add_lvalue_reference<T>::type;
2113 #endif
2114
2115 //***************************************************************************
2117 #if ETL_USING_CPP11
2118 template <typename T>
2119 struct add_rvalue_reference : std::add_rvalue_reference<T>
2120 {
2121 };
2122 #endif
2123
2124 #if ETL_USING_CPP11
2125 template <typename T>
2126 using add_rvalue_reference_t = typename std::add_rvalue_reference<T>::type;
2127 #endif
2128
2129 //***************************************************************************
2131 #if ETL_USING_CPP11
2132 template <typename T>
2133 typename std::add_rvalue_reference<T>::type declval() ETL_NOEXCEPT;
2134 #endif
2135
2136 #if ETL_USING_CPP11
2137 //***************************************************************************
2140 template <typename T>
2141 struct is_enum : std::is_enum<T>
2142 {
2143 };
2144
2145 #if ETL_USING_CPP17
2146 template <typename T>
2147 inline constexpr bool is_enum_v = etl::is_enum<T>::value;
2148 #endif
2149
2150 #endif
2151
2152 //***************************************************************************
2155 #if ETL_USING_CPP11
2156 template <typename TFrom, typename TTo>
2157 struct is_convertible : std::is_convertible<TFrom, TTo>
2158 {
2159 };
2160
2161 // Is convertible and the conversion is noexcept.
2162 template <typename TFrom, typename TTo>
2163 struct is_nothrow_convertible
2164 {
2165 private:
2166
2167 // Helper: a function taking TTo to require the conversion.
2168 static void sink(TTo) noexcept;
2169
2170 // Selected only if 'sink(declval<TFrom>())' is a valid expression.
2171 template <typename F>
2172 static auto test(int) -> etl::bool_constant<noexcept(sink(etl::declval<F>()))>;
2173
2174 // Fallback if conversion is not viable.
2175 template <typename>
2176 static etl::false_type test(...);
2177
2178 public:
2179
2180 static ETL_CONSTANT bool value = decltype(test<TFrom>(0))::value;
2181 };
2182 #else
2183 namespace private_type_traits
2184 {
2185 typedef char yes;
2186 struct no
2187 {
2188 char dummy[2];
2189 };
2190
2191 template <typename TFrom, typename TTo>
2192 struct is_convertible_impl
2193 {
2194 static yes test(TTo);
2195 static no test(...);
2196 static TFrom make();
2197 static const bool value = (sizeof(test(make())) == sizeof(yes));
2198 };
2199
2200 template <typename TTo>
2201 struct is_convertible_impl<void, TTo>
2202 {
2203 static const bool value = false;
2204 };
2205
2206 template <typename TFrom>
2207 struct is_convertible_impl<TFrom, void>
2208 {
2209 static const bool value = false;
2210 };
2211
2212 template <>
2213 struct is_convertible_impl<void, void>
2214 {
2215 static const bool value = true;
2216 };
2217 } // namespace private_type_traits
2218
2219 template <typename TFrom, typename TTo>
2220 struct is_convertible : etl::bool_constant< private_type_traits::is_convertible_impl<TFrom, TTo>::value>
2221 {
2222 };
2223 #endif
2224
2225 #if ETL_USING_CPP17
2226 template <typename TFrom, typename TTo>
2227 inline constexpr bool is_convertible_v = std::is_convertible_v<TFrom, TTo>;
2228
2229 template <typename TFrom, typename TTo >
2230 inline constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<TFrom, TTo>::value;
2231 #endif
2232
2233 //***************************************************************************
2236 template <typename T>
2237 struct alignment_of : std::alignment_of<T>
2238 {
2239 };
2240 template <>
2241 struct alignment_of<void> : std::integral_constant<size_t, 0>
2242 {
2243 };
2244 template <>
2245 struct alignment_of<const void> : std::integral_constant<size_t, 0>
2246 {
2247 };
2248
2249 #if ETL_USING_CPP17
2250 template <typename T>
2251 inline constexpr size_t alignment_of_v = std::alignment_of_v<T>;
2252 #endif
2253
2254#endif // Condition = ETL_USING_STL && ETL_USING_CPP11
2255
2256 //***************************************************************************
2257 // ETL extended type traits.
2258 //***************************************************************************
2259
2260#if ETL_USING_CPP11
2261 //***************************************************************************
2263 #if ETL_USING_CPP11
2264 template <typename...>
2265 struct conjunction : public etl::true_type
2266 {
2267 };
2268
2269 template <typename T1, typename... Tn>
2270 struct conjunction<T1, Tn...> : public etl::conditional_t<bool(T1::value), etl::conjunction<Tn...>, T1>
2271 {
2272 };
2273
2274 template <typename T>
2275 struct conjunction<T> : public T
2276 {
2277 };
2278 #endif
2279
2280 #if ETL_USING_CPP17
2281 template <typename... T>
2282 inline constexpr bool conjunction_v = conjunction<T...>::value;
2283 #endif
2284
2285 //***************************************************************************
2287 #if ETL_USING_CPP11
2288 template <typename...>
2289 struct disjunction : public etl::false_type
2290 {
2291 };
2292
2293 template <typename T1, typename... Tn>
2294 struct disjunction<T1, Tn...> : public etl::conditional_t<bool(T1::value), T1, disjunction<Tn...>>
2295 {
2296 };
2297
2298 template <typename T1>
2299 struct disjunction<T1> : public T1
2300 {
2301 };
2302 #endif
2303
2304 #if ETL_USING_CPP17
2305 template <typename... T>
2306 inline constexpr bool disjunction_v = etl::disjunction<T...>::value;
2307 #endif
2308
2309#endif
2310
2311 //***************************************************************************
2313#if ETL_USING_CPP11
2314 template <typename... TTypes>
2315 struct exclusive_disjunction;
2316
2317 template <typename T>
2318 struct exclusive_disjunction<T> : public etl::bool_constant<T::value>
2319 {
2320 };
2321
2322 // Recursive case: XOR the first two values and recurse
2323 template <typename T1, typename T2, typename... TRest>
2324 struct exclusive_disjunction<T1, T2, TRest...>
2325 : public etl::exclusive_disjunction< etl::integral_constant<bool, etl::disjunction<T1, T2>::value && !etl::conjunction<T1, T2>::value>, TRest...>
2326 {
2327 };
2328#endif
2329
2330#if ETL_USING_CPP17
2331 template <typename... T>
2332 inline constexpr bool exclusive_disjunction_v = etl::exclusive_disjunction<T...>::value;
2333#endif
2334
2335 //***************************************************************************
2337 // /\ingroup type_traits
2338 template <bool BValue, typename T, T TRUE_VALUE, T FALSE_VALUE>
2339 struct conditional_integral_constant;
2340
2341 template <typename T, T TRUE_VALUE, T FALSE_VALUE>
2342 struct conditional_integral_constant<true, T, TRUE_VALUE, FALSE_VALUE>
2343 {
2344 ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Not an integral type");
2345 static const T value = TRUE_VALUE;
2346 };
2347
2348 template <typename T, T TRUE_VALUE, T FALSE_VALUE>
2349 struct conditional_integral_constant<false, T, TRUE_VALUE, FALSE_VALUE>
2350 {
2351 ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Not an integral type");
2352 static const T value = FALSE_VALUE;
2353 };
2354
2355#if ETL_USING_CPP11
2356 //***************************************************************************
2360 template <typename T, typename... TRest>
2361 struct is_one_of : etl::disjunction<etl::is_same<T, TRest>...>
2362 {
2363 };
2364#else
2365 #include "private/type_traits_cpp03.h"
2366#endif
2367
2368#if ETL_USING_CPP17
2369 template <typename T, typename... TRest>
2370 inline constexpr bool is_one_of_v = etl::is_one_of<T, TRest...>::value;
2371#endif
2372
2373#if ETL_USING_CPP11
2374 namespace private_type_traits
2375 {
2376 //***************************************************************************
2377 // Helper to count occurrences of a type in a list of types
2378 template <typename T, typename... TTypes>
2379 struct count_type;
2380
2381 // Base case: zero occurrences
2382 template <typename T>
2383 struct count_type<T> : etl::integral_constant<size_t, 0>
2384 {
2385 };
2386
2387 // Recursive case: increment count if head is the same as T, otherwise
2388 // continue with tail
2389 template <typename T, typename THead, typename... TTail>
2390 struct count_type<T, THead, TTail...> : etl::integral_constant<size_t, (etl::is_same<T, THead>::value ? 1 : 0) + count_type<T, TTail...>::value>
2391 {
2392 };
2393 } // namespace private_type_traits
2394
2395 template <typename T, typename... TTypes>
2396 struct has_duplicates_of : etl::integral_constant< bool, (private_type_traits::count_type<T, TTypes...>::value > 1)>
2397 {
2398 };
2399#endif
2400
2401#if ETL_USING_CPP17
2402 template <typename T, typename... TRest>
2403 inline constexpr bool has_duplicates_of_v = etl::has_duplicates_of<T, TRest...>::value;
2404#endif
2405
2406#if ETL_USING_CPP11
2407 //***************************************************************************
2411 template <typename TBase, typename... TDerived>
2412 struct is_base_of_all : etl::conjunction<etl::is_base_of<TBase, TDerived>...>
2413 {
2414 };
2415#endif
2416
2417#if ETL_USING_CPP17
2418 template <typename T, typename... TRest>
2419 inline constexpr bool is_base_of_all_v = etl::is_base_of_all<T, TRest...>::value;
2420#endif
2421
2422#if ETL_USING_CPP11
2423 //***************************************************************************
2426 template <typename TBase, typename... TDerived>
2427 struct is_base_of_any : etl::disjunction<etl::is_base_of<TBase, TDerived>...>
2428 {
2429 };
2430
2431#endif
2432
2433#if ETL_USING_CPP17
2434 template <typename T, typename... TRest>
2435 inline constexpr bool is_base_of_any_v = etl::is_base_of_any<T, TRest...>::value;
2436#endif
2437
2438 //***************************************************************************
2441 //***************************************************************************
2442 // Recursive definition of the type.
2443 template <size_t Index, typename TType>
2444 struct nth_base
2445 {
2446 typedef typename nth_base<Index - 1U, typename TType::base_type>::type type;
2447 };
2448
2449 template <typename TType>
2450 struct nth_base<0, TType>
2451 {
2452 typedef TType type;
2453 };
2454
2455#if ETL_USING_CPP11
2456 template <size_t Index, typename TType>
2457 using nth_base_t = typename nth_base<Index, TType>::type;
2458#endif
2459
2460 //***************************************************************************
2463
2464 // Default.
2465 template <typename T>
2466 struct types
2467 {
2468 private:
2469
2470 typedef typename etl::remove_reference<typename etl::remove_cv<T>::type>::type type_t;
2471
2472 public:
2473
2474 typedef type_t type;
2475 typedef type_t& reference;
2476 typedef const type_t& const_reference;
2477 typedef type_t* pointer;
2478 typedef const type_t* const_pointer;
2479 typedef const type_t* const const_pointer_const;
2480
2481#if ETL_USING_CPP11
2482 typedef type_t&& rvalue_reference;
2483#endif
2484 };
2485
2486 // Pointers.
2487 template <typename T>
2488 struct types<T*>
2489 {
2490 private:
2491
2492 typedef typename etl::remove_reference<typename etl::remove_cv<T>::type>::type type_t;
2493
2494 public:
2495
2496 typedef type_t type;
2497 typedef type_t& reference;
2498 typedef const type_t& const_reference;
2499 typedef type_t* pointer;
2500 typedef const type_t* const_pointer;
2501 typedef const type_t* const const_pointer_const;
2502
2503#if ETL_USING_CPP11
2504 typedef type_t&& rvalue_reference;
2505#endif
2506 };
2507
2508 // Pointers.
2509 template <typename T>
2510 struct types<T* const>
2511 {
2512 private:
2513
2514 typedef typename etl::remove_reference<typename etl::remove_cv<T>::type>::type type_t;
2515
2516 public:
2517
2518 typedef type_t type;
2519 typedef type_t& reference;
2520 typedef const type_t& const_reference;
2521 typedef type_t* pointer;
2522 typedef const type_t* const_pointer;
2523 typedef const type_t* const const_pointer_const;
2524
2525#if ETL_USING_CPP11
2526 typedef type_t&& rvalue_reference;
2527#endif
2528 };
2529
2530 // References.
2531 template <typename T>
2532 struct types<T&>
2533 {
2534 private:
2535
2536 typedef typename etl::remove_reference<typename etl::remove_cv<T>::type>::type type_t;
2537
2538 public:
2539
2540 typedef type_t type;
2541 typedef type_t& reference;
2542 typedef const type_t& const_reference;
2543 typedef type_t* pointer;
2544 typedef const type_t* const_pointer;
2545 typedef const type_t* const const_pointer_const;
2546
2547#if ETL_USING_CPP11
2548 typedef type_t&& rvalue_reference;
2549#endif
2550 };
2551
2552#if ETL_USING_CPP11
2553 // rvalue References.
2554 template <typename T>
2555 struct types<T&&>
2556 {
2557 private:
2558
2559 typedef typename etl::remove_reference<typename etl::remove_cv<T>::type>::type type_t;
2560
2561 public:
2562
2563 typedef type_t type;
2564 typedef type_t& reference;
2565 typedef const type_t& const_reference;
2566 typedef type_t* pointer;
2567 typedef const type_t* const_pointer;
2568 typedef const type_t* const const_pointer_const;
2569
2570 #if ETL_USING_CPP11
2571 typedef type_t&& rvalue_reference;
2572 #endif
2573 };
2574#endif
2575
2576#if ETL_USING_CPP11
2577 template <typename T>
2578 using types_t = typename types<T>::type;
2579
2580 template <typename T>
2581 using types_r = typename types<T>::reference;
2582
2583 template <typename T>
2584 using types_cr = typename types<T>::const_reference;
2585
2586 template <typename T>
2587 using types_rr = typename types<T>::rvalue_reference;
2588
2589 template <typename T>
2590 using types_p = typename types<T>::pointer;
2591
2592 template <typename T>
2593 using types_cp = typename types<T>::const_pointer;
2594
2595 template <typename T>
2596 using types_cpc = typename types<T>::const_pointer_const;
2597#endif
2598
2599 //***************************************************************************
2602 template <typename T>
2603 struct size_of : etl::integral_constant<size_t, sizeof(T)>
2604 {
2605 };
2606 template <>
2607 struct size_of<void> : etl::integral_constant<size_t, 1U>
2608 {
2609 };
2610
2611#if ETL_USING_CPP17
2612 template <typename T>
2613 inline constexpr size_t size_of_v = etl::size_of<T>::value;
2614#endif
2615
2616#if ETL_USING_CPP11
2617 //***************************************************************************
2619 template <typename T, typename... TRest>
2620 struct are_all_same : etl::conjunction<etl::is_same<T, TRest>...>
2621 {
2622 };
2623#endif
2624
2625#if ETL_USING_CPP17
2626 template <typename T, typename... TRest>
2627 inline constexpr bool are_all_same_v = are_all_same<T, TRest...>::value;
2628#endif
2629
2630 //***************************************************************************
2631#if ETL_USING_STL && ETL_USING_CPP11 && !defined(ETL_USE_TYPE_TRAITS_BUILTINS) && !defined(ETL_USER_DEFINED_TYPE_TRAITS) \
2632 && ((!defined(ARDUINO) && ETL_NOT_USING_STLPORT) || defined(ETL_GCC_V5_TYPE_TRAITS_SUPPORTED))
2633
2634 //*********************************************
2635 // Use the STL's definitions.
2636 //*********************************************
2637
2638 //*********************************************
2639 // is_assignable
2640 template <typename T1, typename T2>
2641 using is_assignable = std::is_assignable<T1, T2>;
2642
2643 //*********************************************
2644 // is_constructible
2645 template <typename T, typename... TArgs>
2646 using is_constructible = std::is_constructible<T, TArgs...>;
2647
2648 //*********************************************
2649 // is_copy_constructible
2650 template <typename T>
2651 using is_copy_constructible = std::is_copy_constructible<T>;
2652
2653 //*********************************************
2654 // is_move_constructible
2655 template <typename T>
2656 using is_move_constructible = std::is_move_constructible<T>;
2657
2658 //*********************************************
2659 // is_copy_assignable
2660 template <typename T>
2661 using is_copy_assignable = std::is_copy_assignable<T>;
2662
2663 //*********************************************
2664 // is_move_assignable
2665 template <typename T>
2666 using is_move_assignable = std::is_move_assignable<T>;
2667
2668 //*********************************************
2669 // is_nothrow_constructible
2670 template <typename T, typename... TArgs>
2671 using is_nothrow_constructible = std::is_nothrow_constructible<T, TArgs...>;
2672
2673 //*********************************************
2674 // is_nothrow_default_constructible
2675 template <typename T>
2676 using is_nothrow_default_constructible = std::is_nothrow_default_constructible<T>;
2677
2678 //*********************************************
2679 // is_nothrow_copy_constructible
2680 template <typename T>
2681 using is_nothrow_copy_constructible = std::is_nothrow_copy_constructible<T>;
2682
2683 //*********************************************
2684 // is_nothrow_move_constructible
2685 template <typename T>
2686 using is_nothrow_move_constructible = std::is_nothrow_move_constructible<T>;
2687
2688 //*********************************************
2689 // is_nothrow_assignable
2690 template <typename T, typename U>
2691 using is_nothrow_assignable = std::is_nothrow_assignable<T, U>;
2692
2693 //*********************************************
2694 // is_nothrow_copy_assignable
2695 template <typename T>
2696 using is_nothrow_copy_assignable = std::is_nothrow_copy_assignable<T>;
2697
2698 //*********************************************
2699 // is_nothrow_move_assignable
2700 template <typename T>
2701 using is_nothrow_move_assignable = std::is_nothrow_move_assignable<T>;
2702
2703 //*********************************************
2704 // is_trivially_constructible
2705 #if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED
2706 template <typename T>
2707 using is_trivially_constructible = std::is_trivially_constructible<T>;
2708 #else
2709 template <typename T>
2710 using is_trivially_constructible = etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>;
2711 #endif
2712
2713 //*********************************************
2714 // is_trivially_copy_constructible
2715 #if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED
2716 template <typename T>
2717 using is_trivially_copy_constructible = std::is_trivially_copy_constructible<T>;
2718 #else
2719 template <typename T>
2720 using is_trivially_copy_constructible = etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>;
2721 #endif
2722
2723 //*********************************************
2724 // is_trivially_destructible
2725 #if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED
2726 template <typename T>
2727 using is_trivially_destructible = std::is_trivially_destructible<T>;
2728 #else
2729 template <typename T>
2730 using is_trivially_destructible = etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>;
2731 #endif
2732
2733 //*********************************************
2734 // is_trivially_copy_assignable
2735 #if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED
2736 template <typename T>
2737 using is_trivially_copy_assignable = std::is_trivially_copy_assignable<T>;
2738 #else
2739 template <typename T>
2740 using is_trivially_copy_assignable = etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>;
2741 #endif
2742
2743 //*********************************************
2744 // is_trivially_copyable
2745 #if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED
2746 template <typename T>
2747 using is_trivially_copyable = std::is_trivially_copyable<T>;
2748 #elif ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE
2749 template <typename T>
2750 using is_trivially_copyable = etl::bool_constant<__is_trivially_copyable(T)>;
2751 #else
2752 template <typename T>
2753 using is_trivially_copyable = etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>;
2754 #endif
2755
2756 //*********************************************
2757 // is_trivially_relocatable
2758 #if ETL_HAS_STD_TRIVIALLY_RELOCATABLE && ETL_USING_STL
2759 template <typename T>
2760 using is_trivially_relocatable = std::is_trivially_relocatable<T>;
2761 #elif ETL_USING_BUILTIN_BUILTIN_IS_CPP_TRIVIALLY_RELOCATABLE
2762 template <typename T>
2763 using is_trivially_relocatable = etl::bool_constant<__builtin_is_cpp_trivially_relocatable(T)>;
2764 #elif ETL_USING_BUILTIN_IS_TRIVIALLY_RELOCATABLE
2765 template <typename T>
2766 using is_trivially_relocatable = etl::bool_constant<__is_trivially_relocatable(T)>;
2767 #else
2768 template <typename T>
2769 using is_trivially_relocatable = etl::bool_constant<etl::is_trivially_copyable<T>::value && etl::is_trivially_destructible<T>::value>;
2770 #endif
2771
2772 //*********************************************
2773 // is_nothrow_relocatable
2774 // A type is nothrow relocatable if it is trivially relocatable, or
2775 // if it has a nothrow move constructor and nothrow destructor.
2776 #if ETL_HAS_STD_TRIVIALLY_RELOCATABLE && ETL_USING_STL
2777 template <typename T>
2778 using is_nothrow_relocatable = std::is_nothrow_relocatable<T>;
2779 #elif ETL_USING_STL
2780 template <typename T>
2781 using is_nothrow_relocatable = etl::bool_constant< etl::is_trivially_relocatable<T>::value
2782 || (std::is_nothrow_move_constructible<typename etl::remove_all_extents<T>::type>::value
2783 && std::is_nothrow_destructible<typename etl::remove_all_extents<T>::type>::value)>;
2784 #else
2785 // Fallback: only trivially relocatable types are known to be nothrow relocatable
2786 template <typename T>
2787 using is_nothrow_relocatable = etl::is_trivially_relocatable<T>;
2788 #endif
2789
2790#elif defined(ETL_USE_TYPE_TRAITS_BUILTINS) && !defined(ETL_USER_DEFINED_TYPE_TRAITS)
2791
2792 //*********************************************
2793 // Use the compiler's builtins.
2794 //*********************************************
2795
2796 //*********************************************
2797 // is_assignable
2798 template <typename T1, typename T2>
2799 struct is_assignable
2800 {
2801 static ETL_CONSTANT bool value = __is_assignable(T1, T2);
2802 };
2803
2804 #if ETL_USING_CPP11
2805 //*********************************************
2806 // is_constructible
2807 template <typename T, typename... TArgs>
2808 struct is_constructible
2809 {
2810 static ETL_CONSTANT bool value = __is_constructible(T, TArgs...);
2811 };
2812 #else
2813 //*********************************************
2814 // is_constructible
2815 template <typename T, typename TArgs = void>
2816 struct is_constructible
2817 {
2818 static ETL_CONSTANT bool value = __is_constructible(T, TArgs);
2819 };
2820
2821 //*********************************************
2822 // is_constructible
2823 template <typename T>
2824 struct is_constructible<T, void>
2825 {
2826 static ETL_CONSTANT bool value = __is_constructible(T);
2827 };
2828 #endif
2829
2830 //*********************************************
2831 // is_copy_constructible
2832 template <typename T>
2833 struct is_copy_constructible : public etl::is_constructible< T, typename etl::add_lvalue_reference<const T>::type>
2834 {
2835 };
2836
2837 //*********************************************
2838 // is_move_constructible
2839 template <typename T>
2840 struct is_move_constructible : public etl::is_constructible<T, T>
2841 {
2842 };
2843
2844 //*********************************************
2845 // is_copy_assignable
2846 template <typename T>
2847 struct is_copy_assignable
2848 : public etl::is_assignable< typename etl::add_lvalue_reference<T>::type, typename etl::add_lvalue_reference<const T>::type>
2849 {
2850 };
2851
2852 //*********************************************
2853 // is_move_assignable
2854 #if ETL_USING_CPP11
2855 template <typename T>
2856 struct is_move_assignable : public etl::is_assignable<typename etl::add_lvalue_reference<T>::type, typename etl::add_rvalue_reference<T>::type>
2857 {
2858 };
2859 #else
2860 template <typename T>
2861 struct is_move_assignable : public etl::is_assignable<typename etl::add_lvalue_reference<T>::type, T>
2862 {
2863 };
2864 #endif
2865
2866 #if ETL_USING_CPP11
2867 //*********************************************
2868 // is_nothrow_constructible
2869 template <typename T, typename... TArgs>
2870 struct is_nothrow_constructible
2871 {
2872 #if ETL_USING_BUILTIN_IS_NOTHROW_CONSTRUCTIBLE
2873 static ETL_CONSTANT bool value = __is_nothrow_constructible(T, TArgs...);
2874 #else
2875 static ETL_CONSTANT bool value = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value;
2876 #endif
2877 };
2878
2879 //*********************************************
2880 // is_nothrow_default_constructible
2881 template <typename T>
2882 struct is_nothrow_default_constructible : public etl::is_nothrow_constructible<T>
2883 {
2884 };
2885
2886 //*********************************************
2887 // is_nothrow_copy_constructible
2888 template <typename T>
2889 struct is_nothrow_copy_constructible : public etl::is_nothrow_constructible<T, typename etl::add_lvalue_reference<const T>::type>
2890 {
2891 };
2892
2893 //*********************************************
2894 // is_nothrow_move_constructible
2895 template <typename T>
2896 struct is_nothrow_move_constructible : public etl::is_nothrow_constructible<T, typename etl::add_rvalue_reference<T>::type>
2897 {
2898 };
2899 #endif
2900
2901 #if ETL_USING_CPP11
2902 //*********************************************
2903 // is_nothrow_assignable
2904 template <typename T, typename U>
2905 struct is_nothrow_assignable
2906 {
2907 #if ETL_USING_BUILTIN_IS_NOTHROW_ASSIGNABLE
2908 static ETL_CONSTANT bool value = __is_nothrow_assignable(T, U);
2909 #else
2910 static ETL_CONSTANT bool value = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value;
2911 #endif
2912 };
2913
2914 //*********************************************
2915 // is_nothrow_copy_assignable
2916 template <typename T>
2917 struct is_nothrow_copy_assignable
2918 : public etl::is_nothrow_assignable<typename etl::add_lvalue_reference<T>::type, typename etl::add_lvalue_reference<const T>::type>
2919 {
2920 };
2921
2922 //*********************************************
2923 // is_nothrow_move_assignable
2924 template <typename T>
2925 struct is_nothrow_move_assignable
2926 : public etl::is_nothrow_assignable<typename etl::add_lvalue_reference<T>::type, typename etl::add_rvalue_reference<T>::type>
2927 {
2928 };
2929 #endif
2930
2931 #if ETL_USING_CPP11
2932 //*********************************************
2933 // is_trivially_constructible
2934 template <typename T, typename... TArgs>
2935 struct is_trivially_constructible
2936 {
2937 #if defined(ETL_COMPILER_GCC)
2938 static ETL_CONSTANT bool value = __has_trivial_constructor(T);
2939 #else
2940 static ETL_CONSTANT bool value = __is_trivially_constructible(T, TArgs...);
2941 #endif
2942 };
2943 #else
2944 //*********************************************
2945 // is_trivially_constructible
2946 template <typename T, typename TArgs = void>
2947 struct is_trivially_constructible
2948 {
2949 #if defined(ETL_COMPILER_GCC)
2950 static ETL_CONSTANT bool value = __has_trivial_constructor(T);
2951 #else
2952 static ETL_CONSTANT bool value = __is_trivially_constructible(T, TArgs);
2953 #endif
2954 };
2955
2956 //*********************************************
2957 // is_trivially_constructible
2958 template <typename T>
2959 struct is_trivially_constructible<T, void>
2960 {
2961 #if defined(ETL_COMPILER_GCC)
2962 static ETL_CONSTANT bool value = __has_trivial_constructor(T);
2963 #else
2964 static ETL_CONSTANT bool value = __is_trivially_constructible(T);
2965 #endif
2966 };
2967 #endif
2968
2969 //*********************************************
2970 // is_trivially_copy_constructible
2971 template <typename T>
2972 struct is_trivially_copy_constructible : public is_trivially_constructible< T, typename add_lvalue_reference<const T>::type>
2973 {
2974 };
2975
2976 //*********************************************
2977 // is_trivially_destructible
2978 template <typename T>
2979 struct is_trivially_destructible
2980 {
2981 #if defined(ETL_COMPILER_GCC)
2982 static ETL_CONSTANT bool value = __has_trivial_destructor(T);
2983 #else
2984 static ETL_CONSTANT bool value = __is_trivially_destructible(T);
2985 #endif
2986 };
2987
2988 //*********************************************
2989 // is_trivially_copy_assignable
2990 template <typename T>
2991 struct is_trivially_copy_assignable
2992 {
2993 #if defined(ETL_COMPILER_GCC)
2994 static ETL_CONSTANT bool value = __has_trivial_copy(T);
2995 #else
2996 static ETL_CONSTANT bool value = __is_trivially_copyable(T);
2997 #endif
2998 };
2999
3000 //*********************************************
3001 // is_trivially_copyable
3002 template <typename T>
3003 struct is_trivially_copyable
3004 {
3005 static ETL_CONSTANT bool value = __is_trivially_copyable(T);
3006 };
3007
3008 //*********************************************
3009 // is_trivially_relocatable
3010 template <typename T>
3011 struct is_trivially_relocatable
3012 {
3013 #if ETL_USING_BUILTIN_BUILTIN_IS_CPP_TRIVIALLY_RELOCATABLE
3014 static ETL_CONSTANT bool value = __builtin_is_cpp_trivially_relocatable(T);
3015 #elif ETL_USING_BUILTIN_IS_TRIVIALLY_RELOCATABLE
3016 static ETL_CONSTANT bool value = __is_trivially_relocatable(T);
3017 #else
3018 static ETL_CONSTANT bool value = etl::is_trivially_copyable<T>::value && etl::is_trivially_destructible<T>::value;
3019 #endif
3020 };
3021
3022 //*********************************************
3023 // is_nothrow_relocatable
3024 // A type is nothrow relocatable if it is trivially relocatable, or
3025 // if it has a nothrow move constructor and nothrow destructor.
3026 template <typename T>
3027 struct is_nothrow_relocatable
3028 {
3029 // In builtins mode, conservatively use trivially_relocatable as the definition
3030 static ETL_CONSTANT bool value = etl::is_trivially_relocatable<T>::value;
3031 };
3032
3033#elif defined(ETL_USER_DEFINED_TYPE_TRAITS) && !defined(ETL_USE_TYPE_TRAITS_BUILTINS)
3034
3035 //*********************************************
3036 // Force the user to provide specialisations for
3037 // anything other than arithmetics and pointers.
3038 //*********************************************
3039
3040 //*********************************************
3041 // is_assignable
3042 template <typename T1, typename T2,
3043 bool BValue =
3044 (etl::is_arithmetic<T1>::value || etl::is_pointer<T1>::value) && (etl::is_arithmetic<T2>::value || etl::is_pointer<T2>::value)>
3045 struct is_assignable;
3046
3047 template <typename T1, typename T2>
3048 struct is_assignable<T1, T2, true> : public etl::true_type
3049 {
3050 };
3051
3052 template <typename T1, typename T2>
3053 struct is_assignable<T1, T2, false>;
3054
3055 #if ETL_USING_CPP11
3056 //*********************************************
3057 // is_constructible
3058 template <typename T, bool BValue, typename... TArgs>
3059 struct is_constructible_helper;
3060
3061 template <typename T, typename... TArgs>
3062 struct is_constructible_helper<T, true, TArgs...> : public etl::true_type
3063 {
3064 };
3065
3066 template <typename T, typename... TArgs>
3067 struct is_constructible_helper<T, false, TArgs...>;
3068
3069 template <typename T, typename... TArgs>
3070 struct is_constructible : public is_constructible_helper< T, etl::is_arithmetic<T>::value || etl::is_pointer<T>::value, TArgs...>
3071 {
3072 };
3073 #endif
3074
3075 //*********************************************
3076 // is_copy_constructible
3077 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3078 struct is_copy_constructible;
3079
3080 template <typename T>
3081 struct is_copy_constructible<T, true> : public etl::true_type
3082 {
3083 };
3084
3085 template <typename T>
3086 struct is_copy_constructible<T, false>;
3087
3088 //*********************************************
3089 // is_move_constructible
3090 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3091 struct is_move_constructible;
3092
3093 template <typename T>
3094 struct is_move_constructible<T, true> : public etl::true_type
3095 {
3096 };
3097
3098 template <typename T>
3099 struct is_move_constructible<T, false>;
3100
3101 //*********************************************
3102 // is_copy_assignable
3103 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3104 struct is_copy_assignable;
3105
3106 template <typename T>
3107 struct is_copy_assignable<T, true> : public etl::true_type
3108 {
3109 };
3110
3111 template <typename T>
3112 struct is_copy_assignable<T, false>;
3113
3114 //*********************************************
3115 // is_move_assignable
3116 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3117 struct is_move_assignable;
3118
3119 template <typename T>
3120 struct is_move_assignable<T, true> : public etl::true_type
3121 {
3122 };
3123
3124 template <typename T>
3125 struct is_move_assignable<T, false>;
3126
3127 #if ETL_USING_CPP11
3128 //*********************************************
3129 // is_nothrow_constructible
3130 template <typename T, bool BValue, typename... TArgs>
3131 struct is_nothrow_constructible_helper;
3132
3133 template <typename T, typename... TArgs>
3134 struct is_nothrow_constructible_helper<T, true, TArgs...> : public etl::true_type
3135 {
3136 };
3137
3138 template <typename T, typename... TArgs>
3139 struct is_nothrow_constructible_helper<T, false, TArgs...>;
3140
3141 template <typename T, typename... TArgs>
3142 struct is_nothrow_constructible : public is_nothrow_constructible_helper<T, etl::is_arithmetic<T>::value || etl::is_pointer<T>::value, TArgs...>
3143 {
3144 };
3145
3146 //*********************************************
3147 // is_nothrow_default_constructible
3148 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3149 struct is_nothrow_default_constructible;
3150
3151 template <typename T>
3152 struct is_nothrow_default_constructible<T, true> : public etl::true_type
3153 {
3154 };
3155
3156 template <typename T>
3157 struct is_nothrow_default_constructible<T, false>;
3158
3159 //*********************************************
3160 // is_nothrow_copy_constructible
3161 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3162 struct is_nothrow_copy_constructible;
3163
3164 template <typename T>
3165 struct is_nothrow_copy_constructible<T, true> : public etl::true_type
3166 {
3167 };
3168
3169 template <typename T>
3170 struct is_nothrow_copy_constructible<T, false>;
3171
3172 //*********************************************
3173 // is_nothrow_move_constructible
3174 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3175 struct is_nothrow_move_constructible;
3176
3177 template <typename T>
3178 struct is_nothrow_move_constructible<T, true> : public etl::true_type
3179 {
3180 };
3181
3182 template <typename T>
3183 struct is_nothrow_move_constructible<T, false>;
3184
3185 //*********************************************
3186 // is_nothrow_assignable
3187 template <typename T, typename U, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3188 struct is_nothrow_assignable;
3189
3190 template <typename T, typename U>
3191 struct is_nothrow_assignable<T, U, true> : public etl::true_type
3192 {
3193 };
3194
3195 template <typename T, typename U>
3196 struct is_nothrow_assignable<T, U, false>;
3197
3198 //*********************************************
3199 // is_nothrow_copy_assignable
3200 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3201 struct is_nothrow_copy_assignable;
3202
3203 template <typename T>
3204 struct is_nothrow_copy_assignable<T, true> : public etl::true_type
3205 {
3206 };
3207
3208 template <typename T>
3209 struct is_nothrow_copy_assignable<T, false>;
3210
3211 //*********************************************
3212 // is_nothrow_move_assignable
3213 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3214 struct is_nothrow_move_assignable;
3215
3216 template <typename T>
3217 struct is_nothrow_move_assignable<T, true> : public etl::true_type
3218 {
3219 };
3220
3221 template <typename T>
3222 struct is_nothrow_move_assignable<T, false>;
3223 #endif
3224
3225 //*********************************************
3226 // is_trivially_constructible
3227 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3228 struct is_trivially_constructible;
3229
3230 template <typename T>
3231 struct is_trivially_constructible<T, true> : public etl::true_type
3232 {
3233 };
3234
3235 template <typename T>
3236 struct is_trivially_constructible<T, false>;
3237
3238 //*********************************************
3239 // is_trivially_copy_constructible
3240 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3241 struct is_trivially_copy_constructible;
3242
3243 template <typename T>
3244 struct is_trivially_copy_constructible<T, true> : public etl::true_type
3245 {
3246 };
3247
3248 template <typename T>
3249 struct is_trivially_copy_constructible<T, false>;
3250
3251 //*********************************************
3252 // is_trivially_destructible
3253 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3254 struct is_trivially_destructible;
3255
3256 template <typename T>
3257 struct is_trivially_destructible<T, true> : public etl::true_type
3258 {
3259 };
3260
3261 template <typename T>
3262 struct is_trivially_destructible<T, false>;
3263
3264 //*********************************************
3265 // is_trivially_copy_assignable
3266 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3267 struct is_trivially_copy_assignable;
3268
3269 template <typename T>
3270 struct is_trivially_copy_assignable<T, true> : public etl::true_type
3271 {
3272 };
3273
3274 template <typename T>
3275 struct is_trivially_copy_assignable<T, false>;
3276
3277 //*********************************************
3278 // is_trivially_copyable
3279 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3280 struct is_trivially_copyable;
3281
3282 template <typename T>
3283 struct is_trivially_copyable<T, true> : public etl::true_type
3284 {
3285 };
3286
3287 template <typename T>
3288 struct is_trivially_copyable<T, false>;
3289
3290 //*********************************************
3291 // is_trivially_relocatable
3292 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3293 struct is_trivially_relocatable;
3294
3295 template <typename T>
3296 struct is_trivially_relocatable<T, true> : public etl::true_type
3297 {
3298 };
3299
3300 template <typename T>
3301 struct is_trivially_relocatable<T, false>;
3302
3303 //*********************************************
3304 // is_nothrow_relocatable
3305 // In user-defined mode, users must specialize for non-trivially-relocatable types
3306 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3307 struct is_nothrow_relocatable;
3308
3309 template <typename T>
3310 struct is_nothrow_relocatable<T, true> : public etl::true_type
3311 {
3312 };
3313
3314 template <typename T>
3315 struct is_nothrow_relocatable<T, false>;
3316
3317#else
3318
3319 //*********************************************
3320 // Assume that anything other than arithmetics
3321 // and pointers return false for the traits.
3322 //*********************************************
3323
3324 //*********************************************
3325 // is_assignable
3326 template <typename T1, typename T2>
3327 #if ETL_USING_BUILTIN_IS_ASSIGNABLE
3328 struct is_assignable : public etl::bool_constant<__is_assignable(T1, T2)>
3329 #else
3330 struct is_assignable
3331 : public etl::bool_constant< (etl::is_arithmetic<T1>::value || etl::is_pointer<T1>::value)
3332 && (etl::is_arithmetic<T2>::value || etl::is_pointer<T2>::value)>
3333 #endif
3334 {
3335 };
3336
3337 #if ETL_USING_CPP11
3338 //***************************************************************************
3340 namespace private_type_traits
3341 {
3342 template <class, class T, class... TArgs>
3343 struct is_constructible_ : etl::false_type
3344 {
3345 };
3346
3347 template <class T, class... TArgs>
3348 struct is_constructible_<void_t<decltype(T(etl::declval<TArgs>()...))>, T, TArgs...> : etl::true_type
3349 {
3350 };
3351 } // namespace private_type_traits
3352
3353 //*********************************************
3354 // is_constructible
3355 template <class T, class... TArgs>
3356 using is_constructible = private_type_traits::is_constructible_<void_t<>, T, TArgs...>;
3357
3358 //*********************************************
3359 // is_copy_constructible
3360 template <class T>
3361 struct is_copy_constructible : public is_constructible< T, typename etl::add_lvalue_reference< typename etl::add_const<T>::type>::type>
3362 {
3363 };
3364 template <>
3365 struct is_copy_constructible<void> : public false_type
3366 {
3367 };
3368 template <>
3369 struct is_copy_constructible<void const> : public false_type
3370 {
3371 };
3372 template <>
3373 struct is_copy_constructible<void volatile> : public false_type
3374 {
3375 };
3376 template <>
3377 struct is_copy_constructible<void const volatile> : public false_type
3378 {
3379 };
3380
3381 //*********************************************
3382 // is_move_constructible
3383 template <typename T>
3384 struct is_move_constructible : public is_constructible<T, typename etl::add_rvalue_reference<T>::type>
3385 {
3386 };
3387 template <>
3388 struct is_move_constructible<void> : public false_type
3389 {
3390 };
3391 template <>
3392 struct is_move_constructible<void const> : public false_type
3393 {
3394 };
3395 template <>
3396 struct is_move_constructible<void volatile> : public false_type
3397 {
3398 };
3399 template <>
3400 struct is_move_constructible<void const volatile> : public false_type
3401 {
3402 };
3403
3404 #else
3405
3406 //*********************************************
3407 // is_copy_constructible
3408 template <typename T>
3409 struct is_copy_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3410 {
3411 };
3412
3413 //*********************************************
3414 // is_move_constructible
3415 template <typename T>
3416 struct is_move_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3417 {
3418 };
3419 #endif
3420
3421 //*********************************************
3422 // is_copy_assignable
3423 template <typename T>
3424 struct is_copy_assignable
3425 : public etl::is_assignable< typename etl::add_lvalue_reference<T>::type, typename etl::add_lvalue_reference<const T>::type>
3426 {
3427 };
3428
3429 #if ETL_USING_CPP11
3430 //*********************************************
3431 // is_move_assignable
3432 template <typename T>
3433 struct is_move_assignable : public etl::is_assignable<typename etl::add_lvalue_reference<T>::type, typename etl::add_rvalue_reference<T>::type>
3434 {
3435 };
3436 #else
3437 //*********************************************
3438 // is_move_assignable
3439 template <typename T>
3440 struct is_move_assignable : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3441 {
3442 };
3443 #endif
3444
3445 #if ETL_USING_CPP11
3446 //*********************************************
3447 // is_nothrow_constructible
3448 template <typename T, typename... TArgs>
3449 struct is_nothrow_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3450 {
3451 };
3452
3453 //*********************************************
3454 // is_nothrow_default_constructible
3455 template <typename T>
3456 struct is_nothrow_default_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3457 {
3458 };
3459
3460 //*********************************************
3461 // is_nothrow_copy_constructible
3462 template <typename T>
3463 struct is_nothrow_copy_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3464 {
3465 };
3466
3467 //*********************************************
3468 // is_nothrow_move_constructible
3469 template <typename T>
3470 struct is_nothrow_move_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3471 {
3472 };
3473
3474 //*********************************************
3475 // is_nothrow_assignable
3476 template <typename T, typename U>
3477 struct is_nothrow_assignable : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3478 {
3479 };
3480
3481 //*********************************************
3482 // is_nothrow_copy_assignable
3483 template <typename T>
3484 struct is_nothrow_copy_assignable : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3485 {
3486 };
3487
3488 //*********************************************
3489 // is_nothrow_move_assignable
3490 template <typename T>
3491 struct is_nothrow_move_assignable : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3492 {
3493 };
3494 #endif
3495
3496 //*********************************************
3497 // is_trivially_constructible
3498 template <typename T>
3499 struct is_trivially_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3500 {
3501 };
3502
3503 //*********************************************
3504 // is_trivially_copy_constructible
3505 template <typename T>
3506 struct is_trivially_copy_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3507 {
3508 };
3509
3510 //*********************************************
3511 // is_trivially_destructible
3512 template <typename T>
3513 struct is_trivially_destructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3514 {
3515 };
3516
3517 //*********************************************
3518 // is_trivially_copy_assignable
3519 template <typename T>
3520 struct is_trivially_copy_assignable : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3521 {
3522 };
3523
3524 //*********************************************
3525 // is_trivially_copyable
3526 template <typename T>
3527 #if ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE
3528 struct is_trivially_copyable : public etl::bool_constant<__is_trivially_copyable(T)>
3529 #else
3530 struct is_trivially_copyable : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3531 #endif
3532 {
3533 };
3534
3535 //*********************************************
3536 // is_trivially_relocatable
3537 template <typename T>
3538 #if ETL_USING_BUILTIN_BUILTIN_IS_CPP_TRIVIALLY_RELOCATABLE
3539 struct is_trivially_relocatable : public etl::bool_constant<__builtin_is_cpp_trivially_relocatable(T)>
3540 #elif ETL_USING_BUILTIN_IS_TRIVIALLY_RELOCATABLE
3541 struct is_trivially_relocatable : public etl::bool_constant<__is_trivially_relocatable(T)>
3542 #else
3543 struct is_trivially_relocatable : public etl::bool_constant<etl::is_trivially_copyable<T>::value && etl::is_trivially_destructible<T>::value>
3544 #endif
3545 {
3546 };
3547
3548 //*********************************************
3549 // is_nothrow_relocatable
3550 // Fallback: only trivially relocatable types are known to be nothrow relocatable
3551 template <typename T>
3552 struct is_nothrow_relocatable : public etl::is_trivially_relocatable<T>
3553 {
3554 };
3555
3556#endif
3557
3558 template <typename T1, typename T2>
3559 struct is_lvalue_assignable
3560 : public etl::is_assignable< typename etl::add_lvalue_reference<T1>::type,
3561 typename etl::add_lvalue_reference< typename etl::add_const<T2>::type>::type>
3562 {
3563 };
3564
3565#if ETL_USING_CPP11
3566 //*********************************************
3567 // is_default_constructible
3568 template <typename T, typename = void>
3569 struct is_default_constructible : etl::false_type
3570 {
3571 };
3572
3573 template <typename T>
3574 struct is_default_constructible<T, etl::void_t<decltype(T())>> : etl::true_type
3575 {
3576 };
3577#else
3578 template <typename T>
3579 struct is_default_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3580 {
3581 };
3582#endif
3583
3584#if ETL_USING_CPP17
3585
3586 template <typename T1, typename T2>
3587 inline constexpr bool is_assignable_v = etl::is_assignable<T1, T2>::value;
3588
3589 template <typename T1, typename T2>
3590 inline constexpr bool is_lvalue_assignable_v = etl::is_lvalue_assignable<T1, T2>::value;
3591
3592 template <typename T, typename... TArgs>
3593 inline constexpr bool is_constructible_v = etl::is_constructible<T, TArgs...>::value;
3594
3595 template <typename T, typename... TArgs>
3596 inline constexpr bool is_default_constructible_v = etl::is_default_constructible<T, TArgs...>::value;
3597
3598 template <typename T>
3599 inline constexpr bool is_copy_constructible_v = etl::is_copy_constructible<T>::value;
3600
3601 template <typename T>
3602 inline constexpr bool is_move_constructible_v = etl::is_move_constructible<T>::value;
3603
3604 template <typename T>
3605 inline constexpr bool is_copy_assignable_v = etl::is_copy_assignable<T>::value;
3606
3607 template <typename T>
3608 inline constexpr bool is_move_assignable_v = etl::is_move_assignable<T>::value;
3609
3610 template <typename T, typename... TArgs>
3611 inline constexpr bool is_nothrow_constructible_v = etl::is_nothrow_constructible<T, TArgs...>::value;
3612
3613 template <typename T>
3614 inline constexpr bool is_nothrow_default_constructible_v = etl::is_nothrow_default_constructible<T>::value;
3615
3616 template <typename T>
3617 inline constexpr bool is_nothrow_copy_constructible_v = etl::is_nothrow_copy_constructible<T>::value;
3618
3619 template <typename T>
3620 inline constexpr bool is_nothrow_move_constructible_v = etl::is_nothrow_move_constructible<T>::value;
3621
3622 template <typename T, typename U>
3623 inline constexpr bool is_nothrow_assignable_v = etl::is_nothrow_assignable<T, U>::value;
3624
3625 template <typename T>
3626 inline constexpr bool is_nothrow_copy_assignable_v = etl::is_nothrow_copy_assignable<T>::value;
3627
3628 template <typename T>
3629 inline constexpr bool is_nothrow_move_assignable_v = etl::is_nothrow_move_assignable<T>::value;
3630
3631 template <typename T>
3632 inline constexpr bool is_trivially_constructible_v = etl::is_trivially_constructible<T>::value;
3633
3634 template <typename T>
3635 inline constexpr bool is_trivially_copy_constructible_v = etl::is_trivially_copy_constructible<T>::value;
3636
3637 template <typename T>
3638 inline constexpr bool is_trivially_destructible_v = etl::is_trivially_destructible<T>::value;
3639
3640 template <typename T>
3641 inline constexpr bool is_trivially_copy_assignable_v = etl::is_trivially_copy_assignable<T>::value;
3642
3643 template <typename T>
3644 inline constexpr bool is_trivially_copyable_v = etl::is_trivially_copyable<T>::value;
3645
3646 template <typename T>
3647 inline constexpr bool is_trivially_relocatable_v = etl::is_trivially_relocatable<T>::value;
3648
3649 template <typename T>
3650 inline constexpr bool is_nothrow_relocatable_v = etl::is_nothrow_relocatable<T>::value;
3651
3652#endif
3653
3654#if ETL_USING_CPP11
3655 //*********************************************
3656 // common_type
3657 // Based on the sample implementation detailed on
3658 // https://en.cppreference.com/w/cpp/types/common_type
3659 //*********************************************
3660 //***********************************
3661 // Primary template
3662 template <typename...>
3663 struct common_type
3664 {
3665 };
3666
3667 //***********************************
3668 // One type
3669 template <typename T>
3670 struct common_type<T> : common_type<T, T>
3671 {
3672 };
3673
3674 namespace private_common_type
3675 {
3676 template <typename T1, typename T2>
3677 using conditional_result_t = decltype(false ? declval<T1>() : declval<T2>());
3678
3679 template <typename, typename, typename = void>
3680 struct decay_conditional_result
3681 {
3682 };
3683
3684 template <typename T1, typename T2>
3685 struct decay_conditional_result<T1, T2, void_t<conditional_result_t<T1, T2>>> : etl::decay<conditional_result_t<T1, T2>>
3686 {
3687 };
3688
3689 template <typename T1, typename T2, typename = void>
3690 struct common_type_2_impl : decay_conditional_result<const T1&, const T2&>
3691 {
3692 };
3693
3694 template <typename T1, typename T2>
3695 struct common_type_2_impl<T1, T2, void_t<conditional_result_t<T1, T2>>> : decay_conditional_result<T1, T2>
3696 {
3697 };
3698 } // namespace private_common_type
3699
3700 //***********************************
3701 // Two types
3702 template <typename T1, typename T2>
3703 struct common_type<T1, T2>
3704 : etl::conditional< etl::is_same<T1, typename etl::decay<T1>::type>::value && etl::is_same<T2, typename etl::decay<T2>::type>::value,
3705 private_common_type::common_type_2_impl<T1, T2>,
3706 common_type<typename etl::decay<T2>::type, typename etl::decay<T2>::type>>::type
3707 {
3708 };
3709
3710 //***********************************
3711 // Three or more types
3712 namespace private_common_type
3713 {
3714 template <typename AlwaysVoid, typename T1, typename T2, typename... TRest>
3715 struct common_type_multi_impl
3716 {
3717 };
3718
3719 template <typename T1, typename T2, typename... TRest>
3720 struct common_type_multi_impl<void_t<typename common_type<T1, T2>::type>, T1, T2, TRest...>
3721 : common_type<typename common_type<T1, T2>::type, TRest...>
3722 {
3723 };
3724 } // namespace private_common_type
3725
3726 template <typename T1, typename T2, typename... TRest>
3727 struct common_type<T1, T2, TRest...> : private_common_type::common_type_multi_impl<void, T1, T2, TRest...>
3728 {
3729 };
3730
3731 template <typename... T>
3732 using common_type_t = typename common_type<T...>::type;
3733#endif
3734
3735 //***************************************************************************
3737 //***************************************************************************
3738 template <typename T>
3739 struct unsigned_type
3740 {
3741 typedef typename etl::conditional<
3742 sizeof(T) == sizeof(unsigned char), unsigned char,
3743 typename etl::conditional< sizeof(T) == sizeof(unsigned short), unsigned short,
3744 typename etl::conditional< sizeof(T) == sizeof(unsigned int), unsigned int,
3745 typename etl::conditional<sizeof(T) == sizeof(unsigned long), unsigned long,
3746 unsigned long long>::type>::type>::type>::type type;
3747 };
3748
3749#if ETL_USING_CPP11
3750 template <typename T>
3751 using unsigned_type_t = typename unsigned_type<T>::type;
3752#endif
3753
3754 //***************************************************************************
3756 //***************************************************************************
3757 template <typename T>
3758 struct signed_type
3759 {
3760 typedef typename etl::conditional<
3761 sizeof(T) == sizeof(char), char,
3762 typename etl::conditional<
3763 sizeof(T) == sizeof(short), short,
3764 typename etl::conditional< sizeof(T) == sizeof(int), int,
3765 typename etl::conditional<sizeof(T) == sizeof(long), long, long long>::type>::type>::type>::type type;
3766 };
3767
3768#if ETL_USING_CPP11
3769 template <typename T>
3770 using signed_type_t = typename signed_type<T>::type;
3771#endif
3772
3773 //*********************************************
3774 // type_identity
3775
3776 template <typename T>
3777 struct type_identity
3778 {
3779 typedef T type;
3780 };
3781
3782#if ETL_USING_CPP11
3783 template <typename T>
3784 using type_identity_t = typename type_identity<T>::type;
3785#endif
3786
3787 //*********************************************
3788 // underlying_type
3789#if ETL_USING_BUILTIN_UNDERLYING_TYPE
3790 // Primary template for etl::underlying_type
3791 template <typename T, bool = etl::is_enum<T>::value>
3792 struct underlying_type;
3793
3794 // Specialization for non-enum types (invalid case)
3795 template <typename T>
3796 struct underlying_type<T, false>
3797 {
3798 // Static assertion to ensure this is only used with enums
3799 ETL_STATIC_ASSERT(etl::is_enum<T>::value, "etl::underlying_type can only be used with enumeration types.");
3800 };
3801
3802 template <typename T>
3803 struct underlying_type<T, true>
3804 {
3805 typedef __underlying_type(T) type;
3806 };
3807#else
3810 template <typename T>
3811 struct underlying_type
3812 {
3813 typedef int type;
3814 };
3815#endif
3816
3817#if ETL_USING_CPP11
3818 template <typename T>
3819 using underlying_type_t = typename underlying_type<T>::type;
3820#endif
3821
3822#if ETL_USING_CPP11
3823 //*********************************************
3824 // has_duplicates
3825 template <typename... TTypes>
3826 struct has_duplicates;
3827
3828 template <typename TFirst, typename... TRest>
3829 struct has_duplicates<TFirst, TRest...> : etl::conditional_t<etl::is_one_of<TFirst, TRest...>::value, etl::true_type, has_duplicates<TRest...>>
3830 {
3831 };
3832
3833 template <typename T>
3834 struct has_duplicates<T> : etl::false_type
3835 {
3836 };
3837
3838 template <>
3839 struct has_duplicates<> : etl::false_type
3840 {
3841 };
3842#endif
3843
3844#if ETL_USING_CPP17
3845 template <typename... TTypes>
3846 inline constexpr bool has_duplicates_v = etl::has_duplicates<TTypes...>::value;
3847#endif
3848
3849#if ETL_USING_CPP11
3850 //*********************************************
3851 // count_of
3852 template <typename T, typename... TTypes>
3853 struct count_of;
3854
3855 template <typename T, typename U, typename... URest>
3856 struct count_of<T, U, URest...> : etl::integral_constant<size_t, etl::is_same<T, U>::value + count_of<T, URest...>::value>
3857 {
3858 };
3859
3860 template <typename T>
3861 struct count_of<T> : etl::integral_constant<size_t, 0>
3862 {
3863 };
3864#endif
3865
3866#if ETL_USING_CPP17
3867 template <typename T, typename... TTypes>
3868 inline constexpr size_t count_of_v = etl::count_of<T, TTypes...>::value;
3869#endif
3870
3871#if ETL_USING_CPP11
3872 //*********************************************
3874 template <typename T, template <typename...> class Template>
3875 struct is_specialization : etl::false_type
3876 {
3877 };
3878
3879 template <template <typename...> class Template, typename... TArgs>
3880 struct is_specialization<Template<TArgs...>, Template> : etl::true_type
3881 {
3882 };
3883#endif
3884
3885#if ETL_USING_CPP17
3886 template <typename T, template <typename...> class Template>
3887 inline constexpr bool is_specialization_v = etl::is_specialization<T, Template>::value;
3888#endif
3889
3890 //*********************************************
3891 // is_constant_evaluated
3892 ETL_CONSTEXPR inline bool is_constant_evaluated() ETL_NOEXCEPT
3893 {
3894#if ETL_USING_CPP23
3895 if consteval
3896 {
3897 return true;
3898 }
3899 else
3900 {
3901 return false;
3902 }
3903#elif ETL_USING_BUILTIN_IS_CONSTANT_EVALUATED == 1
3904 // Fallback for C++20 on supported compilers
3905 return __builtin_is_constant_evaluated();
3906#else
3907 // default if unsupported
3908 return false;
3909#endif
3910 }
3911
3912 //***************************************************************************
3914 //***************************************************************************
3915 namespace private_type_traits
3916 {
3917 template <typename T>
3918 struct is_member_pointer_helper : etl::false_type
3919 {
3920 };
3921
3922 template <typename T, typename TObject>
3923 struct is_member_pointer_helper<T TObject::*> : etl::true_type
3924 {
3925 };
3926 } // namespace private_type_traits
3927
3928 template <typename T>
3929 struct is_member_pointer : private_type_traits::is_member_pointer_helper< typename etl::remove_cv<T>::type>
3930 {
3931 };
3932
3933#if ETL_USING_CPP17
3934 template <typename T>
3935 inline constexpr bool is_member_pointer_v = etl::is_member_pointer<T>::value;
3936#endif
3937
3938#if ETL_USING_CPP11
3939 //*********************************
3941 //*********************************
3942 template <typename T>
3943 struct is_function : etl::false_type
3944 {
3945 };
3946
3947 // Plain / cv-qualified
3948 template <typename TReturn, typename... TArgs>
3949 struct is_function<TReturn(TArgs...)> : etl::true_type
3950 {
3951 };
3952
3953 template <typename TReturn, typename... TArgs>
3954 struct is_function<TReturn(TArgs...) const> : etl::true_type
3955 {
3956 };
3957
3958 template <typename TReturn, typename... TArgs>
3959 struct is_function<TReturn(TArgs...) volatile> : etl::true_type
3960 {
3961 };
3962
3963 template <typename TReturn, typename... TArgs>
3964 struct is_function<TReturn(TArgs...) const volatile> : etl::true_type
3965 {
3966 };
3967
3968 // Variadic
3969 template <typename TReturn, typename... TArgs>
3970 struct is_function<TReturn(TArgs..., ...)> : etl::true_type
3971 {
3972 };
3973
3974 template <typename TReturn, typename... TArgs>
3975 struct is_function<TReturn(TArgs..., ...) const> : etl::true_type
3976 {
3977 };
3978
3979 template <typename TReturn, typename... TArgs>
3980 struct is_function<TReturn(TArgs..., ...) volatile> : etl::true_type
3981 {
3982 };
3983
3984 template <typename TReturn, typename... TArgs>
3985 struct is_function<TReturn(TArgs..., ...) const volatile> : etl::true_type
3986 {
3987 };
3988
3989 // noexcept variants (if supported)
3990 #if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
3991 template <typename TReturn, typename... TArgs>
3992 struct is_function<TReturn(TArgs...) noexcept> : etl::true_type
3993 {
3994 };
3995
3996 template <typename TReturn, typename... TArgs>
3997 struct is_function<TReturn(TArgs...) const noexcept> : etl::true_type
3998 {
3999 };
4000
4001 template <typename TReturn, typename... TArgs>
4002 struct is_function<TReturn(TArgs...) volatile noexcept> : etl::true_type
4003 {
4004 };
4005
4006 template <typename TReturn, typename... TArgs>
4007 struct is_function<TReturn(TArgs...) const volatile noexcept> : etl::true_type
4008 {
4009 };
4010
4011 template <typename TReturn, typename... TArgs>
4012 struct is_function<TReturn(TArgs..., ...) noexcept> : etl::true_type
4013 {
4014 };
4015
4016 template <typename TReturn, typename... TArgs>
4017 struct is_function<TReturn(TArgs..., ...) const noexcept> : etl::true_type
4018 {
4019 };
4020
4021 template <typename TReturn, typename... TArgs>
4022 struct is_function<TReturn(TArgs..., ...) volatile noexcept> : etl::true_type
4023 {
4024 };
4025
4026 template <typename TReturn, typename... TArgs>
4027 struct is_function<TReturn(TArgs..., ...) const volatile noexcept> : etl::true_type
4028 {
4029 };
4030 #endif
4031
4032 #if ETL_USING_CPP17
4033 template <typename T>
4034 inline constexpr bool is_function_v = etl::is_function<T>::value;
4035 #endif
4036
4037#else
4038
4039 template <typename T>
4040 struct is_function : etl::bool_constant<!etl::is_member_pointer<T>::value && !etl::is_const<const T>::value && !etl::is_reference<T>::value>
4041 {
4042 };
4043
4044#endif
4045
4046 //***************************************************************************
4048 //***************************************************************************
4049 template <typename T>
4050 struct is_object : etl::bool_constant<!etl::is_function<T>::value && !etl::is_reference<T>::value && !etl::is_void<T>::value>
4051 {
4052 };
4053
4054#if ETL_USING_CPP17
4055 template <typename T>
4056 inline constexpr bool is_object_v = etl::is_object<T>::value;
4057#endif
4058
4059 //***************************************************************************
4061 //***************************************************************************
4062 template <typename T>
4063 struct is_object_pointer : etl::bool_constant<etl::is_pointer<T>::value && etl::is_object<typename etl::remove_pointer<T>::type>::value>
4064 {
4065 };
4066
4067#if ETL_USING_CPP17
4068 template <typename T>
4069 inline constexpr bool is_object_pointer_v = etl::is_object_pointer<T>::value;
4070#endif
4071
4072#if ETL_USING_CPP11
4073 //*********************************
4075 //*********************************
4076 template <typename T, etl::enable_if_t<etl::is_class<etl::decay_t<T>>::value, int> = 0>
4077 struct has_call_operator
4078 {
4079 template <typename U>
4080 static auto test(int) -> decltype(&U::operator(), etl::true_type());
4081
4082 template <typename>
4083 static etl::false_type test(...);
4084
4085 static const bool value = etl::is_same<decltype(test<T>(0)), etl::true_type>::value;
4086 };
4087
4088 #if ETL_USING_CPP17
4089 template <typename T>
4090 inline constexpr bool has_call_operator_v = etl::has_call_operator<T>::value;
4091 #endif
4092#endif
4093
4094#if ETL_USING_CPP11
4095 //***************************************************************************
4097 //***************************************************************************
4098 template <typename T, etl::enable_if_t<etl::is_class<etl::decay_t<T>>::value, int> = 0>
4099 struct has_unique_call_operator
4100 {
4101 //*********************************
4102 // Test for presence of operator()
4103 //*********************************
4104 template <typename U>
4105 static auto test(int) -> decltype(&U::operator(), etl::true_type());
4106
4107 //*********************************
4108 // Fallback
4109 //*********************************
4110 template <typename>
4111 static auto test(...) -> etl::false_type;
4112
4113 //*********************************
4114 // <b>true</b> if operator() exists and is unique
4115 //*********************************
4116 static constexpr bool value = decltype(test<etl::decay_t<T>>(0))::value;
4117 };
4118
4119 #if ETL_USING_CPP17
4120 template <typename T>
4121 inline constexpr bool has_unique_call_operator_v = etl::has_unique_call_operator<T>::value;
4122 #endif
4123#endif
4124
4125#if ETL_USING_CPP11
4126 //***************************************************************************
4128 //***************************************************************************
4129 template <typename T>
4130 struct is_member_function_pointer : etl::false_type
4131 {
4132 };
4133
4134 template <typename TReturn, typename TObject, typename... TArgs>
4135 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...)> : etl::true_type
4136 {
4137 };
4138 template <typename TReturn, typename TObject, typename... TArgs>
4139 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) const> : etl::true_type
4140 {
4141 };
4142 template <typename TReturn, typename TObject, typename... TArgs>
4143 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) volatile> : etl::true_type
4144 {
4145 };
4146 template <typename TReturn, typename TObject, typename... TArgs>
4147 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) const volatile> : etl::true_type
4148 {
4149 };
4150
4151 #if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
4152 template <typename TReturn, typename TObject, typename... TArgs>
4153 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) noexcept> : etl::true_type
4154 {
4155 };
4156 template <typename TReturn, typename TObject, typename... TArgs>
4157 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) const noexcept> : etl::true_type
4158 {
4159 };
4160 template <typename TReturn, typename TObject, typename... TArgs>
4161 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) volatile noexcept> : etl::true_type
4162 {
4163 };
4164 template <typename TReturn, typename TObject, typename... TArgs>
4165 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) const volatile noexcept> : etl::true_type
4166 {
4167 };
4168 #endif
4169
4170 template <typename TReturn, typename TObject, typename... TArgs>
4171 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...)&> : etl::true_type
4172 {
4173 };
4174 template <typename TReturn, typename TObject, typename... TArgs>
4175 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) const&> : etl::true_type
4176 {
4177 };
4178 template <typename TReturn, typename TObject, typename... TArgs>
4179 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) volatile&> : etl::true_type
4180 {
4181 };
4182 template <typename TReturn, typename TObject, typename... TArgs>
4183 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) const volatile&> : etl::true_type
4184 {
4185 };
4186
4187 template <typename TReturn, typename TObject, typename... TArgs>
4188 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) &&> : etl::true_type
4189 {
4190 };
4191 template <typename TReturn, typename TObject, typename... TArgs>
4192 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) const&&> : etl::true_type
4193 {
4194 };
4195 template <typename TReturn, typename TObject, typename... TArgs>
4196 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) volatile&&> : etl::true_type
4197 {
4198 };
4199 template <typename TReturn, typename TObject, typename... TArgs>
4200 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) const volatile&&> : etl::true_type
4201 {
4202 };
4203
4204 #if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
4205 template <typename TReturn, typename TObject, typename... TArgs>
4206 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) & noexcept> : etl::true_type
4207 {
4208 };
4209 template <typename TReturn, typename TObject, typename... TArgs>
4210 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) const & noexcept> : etl::true_type
4211 {
4212 };
4213 template <typename TReturn, typename TObject, typename... TArgs>
4214 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) volatile & noexcept> : etl::true_type
4215 {
4216 };
4217 template <typename TReturn, typename TObject, typename... TArgs>
4218 struct is_member_function_pointer< TReturn (TObject::*)(TArgs...) const volatile & noexcept> : etl::true_type
4219 {
4220 };
4221
4222 template <typename TReturn, typename TObject, typename... TArgs>
4223 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) && noexcept> : etl::true_type
4224 {
4225 };
4226 template <typename TReturn, typename TObject, typename... TArgs>
4227 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) const && noexcept> : etl::true_type
4228 {
4229 };
4230 template <typename TReturn, typename TObject, typename... TArgs>
4231 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) volatile && noexcept> : etl::true_type
4232 {
4233 };
4234 template <typename TReturn, typename TObject, typename... TArgs>
4235 struct is_member_function_pointer< TReturn (TObject::*)(TArgs...) const volatile && noexcept> : etl::true_type
4236 {
4237 };
4238 #endif
4239
4240 template <typename TReturn, typename TObject, typename... TArgs>
4241 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...)> : etl::true_type
4242 {
4243 };
4244 template <typename TReturn, typename TObject, typename... TArgs>
4245 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) const> : etl::true_type
4246 {
4247 };
4248 template <typename TReturn, typename TObject, typename... TArgs>
4249 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) volatile> : etl::true_type
4250 {
4251 };
4252 template <typename TReturn, typename TObject, typename... TArgs>
4253 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) const volatile> : etl::true_type
4254 {
4255 };
4256
4257 #if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
4258 template <typename TReturn, typename TObject, typename... TArgs>
4259 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) noexcept> : etl::true_type
4260 {
4261 };
4262 template <typename TReturn, typename TObject, typename... TArgs>
4263 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) const noexcept> : etl::true_type
4264 {
4265 };
4266 template <typename TReturn, typename TObject, typename... TArgs>
4267 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) volatile noexcept> : etl::true_type
4268 {
4269 };
4270 template <typename TReturn, typename TObject, typename... TArgs>
4271 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) const volatile noexcept> : etl::true_type
4272 {
4273 };
4274 #endif
4275
4276 template <typename TReturn, typename TObject, typename... TArgs>
4277 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...)&> : etl::true_type
4278 {
4279 };
4280 template <typename TReturn, typename TObject, typename... TArgs>
4281 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) const&> : etl::true_type
4282 {
4283 };
4284 template <typename TReturn, typename TObject, typename... TArgs>
4285 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) volatile&> : etl::true_type
4286 {
4287 };
4288 template <typename TReturn, typename TObject, typename... TArgs>
4289 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) const volatile&> : etl::true_type
4290 {
4291 };
4292 template <typename TReturn, typename TObject, typename... TArgs>
4293 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) &&> : etl::true_type
4294 {
4295 };
4296 template <typename TReturn, typename TObject, typename... TArgs>
4297 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) const&&> : etl::true_type
4298 {
4299 };
4300 template <typename TReturn, typename TObject, typename... TArgs>
4301 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) volatile&&> : etl::true_type
4302 {
4303 };
4304 template <typename TReturn, typename TObject, typename... TArgs>
4305 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) const volatile&&> : etl::true_type
4306 {
4307 };
4308
4309 #if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
4310 template <typename TReturn, typename TObject, typename... TArgs>
4311 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) & noexcept> : etl::true_type
4312 {
4313 };
4314 template <typename TReturn, typename TObject, typename... TArgs>
4315 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) const & noexcept> : etl::true_type
4316 {
4317 };
4318 template <typename TReturn, typename TObject, typename... TArgs>
4319 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) volatile & noexcept> : etl::true_type
4320 {
4321 };
4322 template <typename TReturn, typename TObject, typename... TArgs>
4323 struct is_member_function_pointer< TReturn (TObject::*)(TArgs..., ...) const volatile & noexcept> : etl::true_type
4324 {
4325 };
4326
4327 template <typename TReturn, typename TObject, typename... TArgs>
4328 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) && noexcept> : etl::true_type
4329 {
4330 };
4331 template <typename TReturn, typename TObject, typename... TArgs>
4332 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) const && noexcept> : etl::true_type
4333 {
4334 };
4335 template <typename TReturn, typename TObject, typename... TArgs>
4336 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) volatile && noexcept> : etl::true_type
4337 {
4338 };
4339 template <typename TReturn, typename TObject, typename... TArgs>
4340 struct is_member_function_pointer< TReturn (TObject::*)(TArgs..., ...) const volatile && noexcept> : etl::true_type
4341 {
4342 };
4343 #endif
4344#endif
4345
4346#if ETL_USING_CPP17
4347 template <typename T>
4348 inline constexpr bool is_member_function_pointer_v = etl::is_member_function_pointer<T>::value;
4349#endif
4350
4351#if ETL_USING_CPP11
4352 //***************************************************************************
4354 //***************************************************************************
4355 namespace private_type_traits
4356 {
4357 template <typename>
4358 struct is_member_object_pointer_helper : public etl::false_type
4359 {
4360 };
4361
4362 template <typename T, typename TObject>
4363 struct is_member_object_pointer_helper<T TObject::*> : public etl::negation<etl::is_function<T>>
4364 {
4365 };
4366 } // namespace private_type_traits
4367
4368 template <typename T>
4369 struct is_member_object_pointer : public private_type_traits::is_member_object_pointer_helper< etl::remove_cv_t<T>>::type
4370 {
4371 };
4372#endif
4373
4374#if ETL_USING_CPP17
4375 template <typename T>
4376 inline constexpr bool is_member_object_pointer_v = etl::is_member_object_pointer<T>::value;
4377#endif
4378
4379#if ETL_USING_CPP20
4380 template <class... TArgs>
4381 struct common_reference;
4382
4383 template <class... TArgs>
4384 using common_reference_t = typename etl::common_reference<TArgs...>::type;
4385
4386 template <class T, class U, template <class> class TQual, template <class> class UQual>
4387 struct basic_common_reference
4388 {
4389 };
4390
4391 // If sizeof...(T) is 0: no member
4392 template <>
4393 struct common_reference<>
4394 {
4395 };
4396
4397 // If sizeof...(T) is 1
4398 template <class T>
4399 struct common_reference<T>
4400 {
4401 using type = T;
4402 };
4403
4404 namespace private_type_traits
4405 {
4406 template <class T1, class T2>
4407 using cond_res = decltype(false ? etl::declval<T1 (&)()>()() : etl::declval<T2 (&)()>()());
4408
4409 template <class From>
4410 struct copy_cv
4411 {
4412 template <class To>
4413 using apply = To;
4414 };
4415
4416 template <class From>
4417 struct copy_cv<const From>
4418 {
4419 template <class To>
4420 using apply = const To;
4421 };
4422
4423 template <class From>
4424 struct copy_cv<volatile From>
4425 {
4426 template <class To>
4427 using apply = volatile To;
4428 };
4429
4430 template <class From>
4431 struct copy_cv<const volatile From>
4432 {
4433 template <class To>
4434 using apply = const volatile To;
4435 };
4436
4437 template <class From, class To>
4438 using copy_cv_t = typename copy_cv<From>::template apply<To>;
4439
4440 template <class From>
4441 struct copy_cvref
4442 {
4443 template <class To>
4444 using apply = copy_cv_t<From, To>;
4445 };
4446
4447 template <class From>
4448 struct copy_cvref<From&>
4449 {
4450 template <class To>
4451 using apply = add_lvalue_reference_t<copy_cv_t<From, To>>;
4452 };
4453
4454 template <class From>
4455 struct copy_cvref<From&&>
4456 {
4457 template <class To>
4458 using apply = add_lvalue_reference_t<copy_cv_t<From, To>>;
4459 };
4460
4461 template <class From, class To>
4462 using copy_cvref_t = typename copy_cvref<From>::template apply<To>;
4463
4464 template <class T1>
4465 struct xref
4466 {
4467 template <class T2>
4468 using apply = copy_cvref_t<T1, T2>;
4469 };
4470
4471 template <class T1, class T2, class T1_RR = remove_reference_t<T1>, class T2_RR = remove_reference_t<T2>>
4472 struct common_ref;
4473
4474 template <class T1, class T2>
4475 using common_ref_t = typename common_ref<T1, T2>::type;
4476
4477 template <class T1, class T2>
4478 using cv_cond_res = cond_res<copy_cv_t<T1, T2>&, copy_cv_t<T2, T1>&>;
4479
4480 template <class T1, class T2, class T1_RR, class T2_RR>
4481 requires requires { typename cv_cond_res<T1_RR, T2_RR>; } && is_reference_v<cv_cond_res<T1_RR, T2_RR>>
4482 struct common_ref<T1&, T2&, T1_RR, T2_RR>
4483 {
4484 using type = cv_cond_res<T1_RR, T2_RR>;
4485 };
4486
4487 template <class T1, class T2>
4488 using common_ref_rr = remove_reference_t<common_ref_t<T1&, T2&>>&&;
4489
4490 template <class T1, class T2, class T1_R, class T2_R>
4491 requires requires { typename common_ref_rr<T1_R, T2_R>; }
4492 && is_convertible_v<T1&&, common_ref_rr<T1_R, T2_R>> && is_convertible_v<T2&&, common_ref_rr<T1_R, T2_R>>
4493 struct common_ref<T1&&, T2&&, T1_R, T2_R>
4494 {
4495 using type = common_ref_rr<T1_R, T2_R>;
4496 };
4497
4498 template <class T1, class T2>
4499 using common_ref_cr = common_ref_t<const T1&, T2&>;
4500
4501 template <class T1, class T2, class T3, class T4>
4502 requires requires { typename common_ref_cr<T3, T4>; } && is_convertible_v<T1&&, common_ref_cr<T3, T4>>
4503 struct common_ref<T1&&, T2&, T3, T4>
4504 {
4505 using type = common_ref_cr<T3, T4>;
4506 };
4507
4508 template <class T1, class T2, class T3, class T4>
4509 struct common_ref<T1&, T2&&, T3, T4> : common_ref<T2&&, T1&>
4510 {
4511 };
4512
4513 template <class T1, class T2, class T3, class T4>
4514 struct common_ref
4515 {
4516 };
4517
4518 template <class T1, class T2>
4519 struct common_reference_impl3;
4520
4521 template <class T1, class T2>
4522 struct common_reference_impl2 : common_reference_impl3<T1, T2>
4523 {
4524 };
4525
4526 template <class T1, class T2>
4527 struct common_reference_impl1 : common_reference_impl2<T1, T2>
4528 {
4529 };
4530 } // namespace private_type_traits
4531
4532 // If sizeof...(T) is 2
4533 template <class T1, class T2>
4534 struct common_reference<T1, T2> : private_type_traits::common_reference_impl1<T1, T2>
4535 {
4536 };
4537
4538 namespace private_type_traits
4539 {
4540 template <class T1, class T2>
4541 requires is_reference_v<T1> && is_reference_v<T2> && requires { typename common_ref_t<T1, T2>; }
4542 && is_convertible_v<add_pointer_t<T1>, add_pointer_t<common_ref_t<T1, T2>>>
4543 && is_convertible_v<add_pointer_t<T2>, add_pointer_t<common_ref_t<T1, T2>>>
4544 struct common_reference_impl1<T1, T2>
4545 {
4546 using type = common_ref_t<T1, T2>;
4547 };
4548
4549 template <class T1, class T2>
4550 using basic_common_reference_t =
4551 typename basic_common_reference<remove_cvref_t<T1>, remove_cvref_t<T2>, xref<T1>::template apply, xref<T2>::template apply>::type;
4552
4553 template <class T1, class T2>
4554 requires requires { typename basic_common_reference_t<T1, T2>; }
4555 struct common_reference_impl2<T1, T2>
4556 {
4557 using type = basic_common_reference_t<T1, T2>;
4558 };
4559
4560 template <class T1, class T2>
4561 requires requires { typename cond_res<T1, T2>; }
4562 struct common_reference_impl3<T1, T2>
4563 {
4564 using type = cond_res<T1, T2>;
4565 };
4566
4567 template <class T1, class T2>
4568 struct common_reference_impl3 : common_type<T1, T2>
4569 {
4570 };
4571 } // namespace private_type_traits
4572
4573 template <class T1, class T2, class T3, class... TArgs>
4574 requires requires { typename common_reference_t<T1, T2>; }
4575 struct common_reference<T1, T2, T3, TArgs...> : common_reference<common_reference_t<T1, T2>, T3, TArgs...>
4576 {
4577 };
4578
4579 template <class... TArgs>
4580 struct common_reference
4581 {
4582 };
4583
4584#endif
4585
4586#if ETL_USING_CPP11
4587 template <typename, typename = void>
4588 struct has_size : etl::false_type
4589 {
4590 };
4591
4592 template <typename T>
4593 struct has_size<T, void_t<decltype(etl::declval<T>().size())> > : etl::true_type
4594 {
4595 };
4596#else
4597 template <typename T>
4598 struct has_size
4599 {
4600 private:
4601
4602 typedef char yes;
4603 struct no
4604 {
4605 char dummy[2];
4606 };
4607
4608 template <typename U>
4609 static yes test_size(char (*)[sizeof(&U::size)]);
4610
4611 template <typename U>
4612 static no test_size(...);
4613
4614 public:
4615
4616 static const bool value = (sizeof(test_size<T>(0)) == sizeof(yes));
4617 };
4618#endif
4619
4620#if ETL_USING_CPP11
4621 template <typename, typename = void>
4622 struct has_data : etl::false_type
4623 {
4624 };
4625
4626 template <typename T>
4627 struct has_data<T, void_t<decltype(etl::declval<T>().data())> > : etl::true_type
4628 {
4629 };
4630#else
4631 template <typename T>
4632 struct has_data
4633 {
4634 private:
4635
4636 typedef char yes;
4637 struct no
4638 {
4639 char dummy[2];
4640 };
4641
4642 template <typename U>
4643 static yes test_data(char (*)[sizeof(&U::data)]);
4644
4645 template <typename U>
4646 static no test_data(...);
4647
4648 public:
4649
4650 static const bool value = (sizeof(test_data<T>(0)) == sizeof(yes));
4651 };
4652#endif
4653} // namespace etl
4654
4655// Helper macros
4656#define ETL_IS_CHAR_TYPE(type) (etl::is_same<char, type>::value || etl::is_same<signed char, type>::value || etl::is_same<unsigned char, type>::value)
4657#define ETL_IS_NOT_CHAR_TYPE(type) (!ETL_IS_CHAR_TYPE(type))
4658
4659#define ETL_IS_POINTER_TYPE(type) (etl::is_pointer<type>::value)
4660#define ETL_IS_NOT_POINTER_TYPE(type) (!ETL_IS_POINTER_TYPE(type))
4661
4662#define ETL_TARGET_IS_TRIVIALLY_COPYABLE(type) (etl::is_trivially_copyable< typename etl::iterator_traits<type>::value_type>::value)
4663#define ETL_TARGET_IS_NOT_TRIVIALLY_COPYABLE(type) (!ETL_TARGET_IS_TRIVIALLY_COPYABLE(type))
4664
4665#endif // ETL_TYPE_TRAITS_INCLUDED
Definition absolute.h:40
ETL_CONSTEXPR TContainer::pointer data(TContainer &container)
Definition iterator.h:1470
integral_constant< bool, false > false_type
integral_constant specialisations
Definition type_traits.h:80
ETL_CONSTEXPR TContainer::size_type size(const TContainer &container)
Definition iterator.h:1434
add_const
Definition type_traits.h:251
add_cv
Definition type_traits.h:338
add_pointer
Definition type_traits.h:200
add_volatile
Definition type_traits.h:307
Definition type_traits.h:97
integral_constant
Definition type_traits.h:67
is_const
Definition type_traits.h:213
is_integral
Definition type_traits.h:364
is_signed
Definition type_traits.h:458
is_volatile
Definition type_traits.h:269
negation
Definition type_traits.h:110
remove_const
Definition type_traits.h:233
remove_cv
Definition type_traits.h:325
remove_cvref
Definition type_traits.h:351
remove_pointer
Definition type_traits.h:147
remove_reference
Definition type_traits.h:122
remove_volatile
Definition type_traits.h:289