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> : true_type
503 {
504 };
505 #endif
506 #if ETL_HAS_NATIVE_CHAR16_T
507 template <>
508 struct is_signed<char16_t> : true_type
509 {
510 };
511 #endif
512 #if ETL_HAS_NATIVE_CHAR32_T
513 template <>
514 struct is_signed<char32_t> : true_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 template <typename T>
573 struct is_unsigned<const T> : is_unsigned<T>
574 {
575 };
576 template <typename T>
577 struct is_unsigned<volatile T> : is_unsigned<T>
578 {
579 };
580 template <typename T>
581 struct is_unsigned<const volatile T> : is_unsigned<T>
582 {
583 };
584
585 #if ETL_USING_CPP17
586 template <typename T>
587 inline constexpr bool is_unsigned_v = is_unsigned<T>::value;
588 #endif
589
590 //***************************************************************************
592 template <typename T>
593 struct is_floating_point : false_type
594 {
595 };
596 template <>
597 struct is_floating_point<float> : true_type
598 {
599 };
600 template <>
601 struct is_floating_point<double> : true_type
602 {
603 };
604 template <>
605 struct is_floating_point<long double> : true_type
606 {
607 };
608 template <typename T>
609 struct is_floating_point<const T> : is_floating_point<T>
610 {
611 };
612 template <typename T>
613 struct is_floating_point<volatile T> : is_floating_point<T>
614 {
615 };
616 template <typename T>
617 struct is_floating_point<const volatile T> : is_floating_point<T>
618 {
619 };
620
621 #if ETL_USING_CPP17
622 template <typename T>
623 inline constexpr bool is_floating_point_v = is_floating_point<T>::value;
624 #endif
625
626 //***************************************************************************
628 template <typename T1, typename T2>
629 struct is_same : public false_type
630 {
631 };
632 template <typename T>
633 struct is_same<T, T> : public true_type
634 {
635 };
636
637 #if ETL_USING_CPP17
638 template <typename T1, typename T2>
639 inline constexpr bool is_same_v = is_same<T1, T2>::value;
640 #endif
641
642 //***************************************************************************
644 template <typename T>
645 struct is_void : false_type
646 {
647 };
648 template <>
649 struct is_void<void> : true_type
650 {
651 };
652
653 #if ETL_USING_CPP17
654 template <typename T>
655 inline constexpr bool is_void_v = is_void<T>::value;
656 #endif
657
658 //***************************************************************************
660 template <typename T>
661 struct is_arithmetic : etl::bool_constant<is_integral<T>::value || is_floating_point<T>::value>
662 {
663 };
664
665 #if ETL_USING_CPP17
666 template <typename T>
667 inline constexpr bool is_arithmetic_v = is_arithmetic<T>::value;
668 #endif
669
670 //***************************************************************************
672 template <typename T>
673 struct is_fundamental : etl::bool_constant<is_arithmetic<T>::value || is_void<T>::value>
674 {
675 };
676
677 #if ETL_USING_CPP17
678 template <typename T>
679 inline constexpr bool is_fundamental_v = is_fundamental<T>::value;
680 #endif
681
682 //***************************************************************************
684 template <typename T>
685 struct is_compound : etl::bool_constant<!is_fundamental<T>::value>
686 {
687 };
688
689 #if ETL_USING_CPP17
690 template <typename T>
691 inline constexpr bool is_compound_v = is_compound<T>::value;
692 #endif
693
694 //***************************************************************************
696 template <typename T>
697 struct is_array : false_type
698 {
699 };
700 template <typename T>
701 struct is_array<T[]> : true_type
702 {
703 };
704 template <typename T, size_t Size>
705 struct is_array<T[Size]> : true_type
706 {
707 };
708
709 #if ETL_USING_CPP17
710 template <typename T>
711 inline constexpr bool is_array_v = is_array<T>::value;
712 #endif
713
714 //***************************************************************************
716 template <typename T>
717 struct is_pointer_helper : false_type
718 {
719 };
720 template <typename T>
721 struct is_pointer_helper<T*> : true_type
722 {
723 };
724 template <typename T>
725 struct is_pointer_helper<const T*> : is_pointer_helper<T*>
726 {
727 };
728 template <typename T>
729 struct is_pointer_helper<volatile T*> : is_pointer_helper<T*>
730 {
731 };
732 template <typename T>
733 struct is_pointer_helper<const volatile T*> : is_pointer_helper<T*>
734 {
735 };
736 template <typename T>
737 struct is_pointer : is_pointer_helper<typename remove_cv<T>::type>
738 {
739 };
740
741 #if ETL_USING_CPP17
742 template <typename T>
743 inline constexpr bool is_pointer_v = is_pointer<T>::value;
744 #endif
745
746 //***************************************************************************
748 template <typename T>
749 struct is_lvalue_reference_helper : false_type
750 {
751 };
752 template <typename T>
753 struct is_lvalue_reference_helper<T&> : true_type
754 {
755 };
756 template <typename T>
757 struct is_lvalue_reference : is_lvalue_reference_helper<typename remove_cv<T>::type>
758 {
759 };
760
761 #if ETL_USING_CPP17
762 template <typename T>
763 inline constexpr bool is_lvalue_reference_v = etl::is_lvalue_reference<T>::value;
764 #endif
765
766 #if ETL_USING_CPP11
767 //***************************************************************************
769 template <typename T>
770 struct is_rvalue_reference_helper : false_type
771 {
772 };
773 template <typename T>
774 struct is_rvalue_reference_helper<T&&> : true_type
775 {
776 };
777 template <typename T>
778 struct is_rvalue_reference : is_rvalue_reference_helper<typename remove_cv<T>::type>
779 {
780 };
781
782 #if ETL_USING_CPP17
783 template <typename T>
784 inline constexpr bool is_rvalue_reference_v = etl::is_rvalue_reference<T>::value;
785 #endif
786 #endif
787
788 //***************************************************************************
790 // Either lvalue or rvalue (for CPP11)
791 template <typename T>
792 struct is_reference
793 : integral_constant<bool, is_lvalue_reference<T>::value
794 #if ETL_USING_CPP11
795 || is_rvalue_reference<T>::value
796 #endif
797 >
798 {
799 };
800
801 #if ETL_USING_CPP17
802 template <typename T>
803 inline constexpr bool is_reference_v = is_reference<T>::value;
804 #endif
805
806 //***************************************************************************
809 template <typename T>
810 struct is_pod : etl::bool_constant<etl::is_fundamental<T>::value || etl::is_pointer<T>::value>
811 {
812 };
813
814 #if ETL_USING_CPP17
815 template <typename T>
816 inline constexpr bool is_pod_v = etl::is_pod<T>::value;
817 #endif
818
819 //***************************************************************************
821 template <bool BValue, typename T, typename F>
822 struct conditional
823 {
824 typedef T type;
825 };
826 template <typename T, typename F>
827 struct conditional<false, T, F>
828 {
829 typedef F type;
830 };
831
832 #if ETL_USING_CPP11
833 template <bool BValue, typename T, typename F>
834 using conditional_t = typename conditional<BValue, T, F>::type;
835 #endif
836
837 //***************************************************************************
839 template <typename T>
840 struct make_signed
841 {
842 typedef T type;
843 };
844 template <>
845 struct make_signed<char>
846 {
847 typedef signed char type;
848 };
849 template <>
850 struct make_signed<unsigned char>
851 {
852 typedef signed char type;
853 };
854
855 template <>
856 struct make_signed<wchar_t>
857 {
858 typedef etl::conditional< sizeof(wchar_t) == sizeof(int16_t), int16_t,
859 etl::conditional<sizeof(wchar_t) == sizeof(int32_t), int32_t, void>::type>::type type;
860 };
861
862 template <>
863 struct make_signed<unsigned short>
864 {
865 typedef short type;
866 };
867 template <>
868 struct make_signed<unsigned int>
869 {
870 typedef int type;
871 };
872 template <>
873 struct make_signed<unsigned long>
874 {
875 typedef long type;
876 };
877 template <>
878 struct make_signed<unsigned long long>
879 {
880 typedef long long type;
881 };
882 template <typename T>
883 struct make_signed<const T> : add_const<typename make_signed<T>::type>
884 {
885 };
886 template <typename T>
887 struct make_signed<volatile T> : add_volatile<typename make_signed<T>::type>
888 {
889 };
890 template <typename T>
891 struct make_signed<const volatile T> : add_const<typename add_volatile<typename make_signed<T>::type>::type>
892 {
893 };
894
895 #if ETL_USING_CPP11
896 template <typename T>
897 using make_signed_t = typename make_signed<T>::type;
898 #endif
899
900 //***************************************************************************
902 template <typename T>
903 struct make_unsigned
904 {
905 typedef T type;
906 };
907 template <>
908 struct make_unsigned<char>
909 {
910 typedef unsigned char type;
911 };
912 template <>
913 struct make_unsigned<signed char>
914 {
915 typedef unsigned char type;
916 };
917 template <>
918 struct make_unsigned<short>
919 {
920 typedef unsigned short type;
921 };
922
923 template <>
924 struct make_unsigned<wchar_t>
925 {
926 typedef etl::conditional< sizeof(wchar_t) == sizeof(uint16_t), uint16_t,
927 etl::conditional<sizeof(wchar_t) == sizeof(uint32_t), uint32_t, void>::type>::type type;
928 };
929
930 template <>
931 struct make_unsigned<int>
932 {
933 typedef unsigned int type;
934 };
935 template <>
936 struct make_unsigned<long>
937 {
938 typedef unsigned long type;
939 };
940 template <>
941 struct make_unsigned<long long>
942 {
943 typedef unsigned long long type;
944 };
945 template <typename T>
946 struct make_unsigned<const T> : add_const<typename make_unsigned<T>::type>
947 {
948 };
949 template <typename T>
950 struct make_unsigned<volatile T> : add_volatile<typename make_unsigned<T>::type>
951 {
952 };
953 template <typename T>
954 struct make_unsigned<const volatile T> : add_const<typename add_volatile<typename make_unsigned<T>::type>::type>
955 {
956 };
957
958 #if ETL_USING_CPP11
959 template <typename T>
960 using make_unsigned_t = typename make_unsigned<T>::type;
961 #endif
962
963 //***************************************************************************
965 template <bool BValue, typename T = void>
966 struct enable_if
967 {
968 };
969 template <typename T>
970 struct enable_if<true, T>
971 {
972 typedef T type;
973 };
974
975 #if ETL_USING_CPP11
976 template <bool BValue, typename T = void>
977 using enable_if_t = typename enable_if<BValue, T>::type;
978 #endif
979
980 //***************************************************************************
982 template <typename T, unsigned Size = 0U>
983 struct extent : integral_constant<size_t, 0U>
984 {
985 };
986
987 template <typename T>
988 struct extent<T[], 0> : integral_constant<size_t, 0U>
989 {
990 };
991
992 template <typename T, unsigned Size>
993 struct extent<T[], Size> : integral_constant<size_t, extent<T, Size - 1>::value>
994 {
995 };
996
997 template <typename T, unsigned Size>
998 struct extent<T[Size], 0> : integral_constant<size_t, Size>
999 {
1000 };
1001
1002 template <typename T, unsigned I, unsigned Size>
1003 struct extent<T[I], Size> : integral_constant<size_t, extent<T, Size - 1>::value>
1004 {
1005 };
1006
1007 #if ETL_USING_CPP17
1008 template <typename T, unsigned Size = 0U>
1009 inline constexpr size_t extent_v = extent<T, Size>::value;
1010 #endif
1011
1012 //***************************************************************************
1014 template <typename T>
1015 struct remove_extent
1016 {
1017 typedef T type;
1018 };
1019 template <typename T>
1020 struct remove_extent<T[]>
1021 {
1022 typedef T type;
1023 };
1024 template <typename T, size_t Size>
1025 struct remove_extent<T[Size]>
1026 {
1027 typedef T type;
1028 };
1029
1030 #if ETL_USING_CPP11
1031 template <typename T>
1032 using remove_extent_t = typename remove_extent<T>::type;
1033 #endif
1034
1035 //***************************************************************************
1037 template <typename T>
1038 struct remove_all_extents
1039 {
1040 typedef T type;
1041 };
1042 template <typename T>
1043 struct remove_all_extents<T[]>
1044 {
1045 typedef typename remove_all_extents<T>::type type;
1046 };
1047 template <typename T, size_t Size>
1048 struct remove_all_extents<T[Size]>
1049 {
1050 typedef typename remove_all_extents<T>::type type;
1051 };
1052
1053 #if ETL_USING_CPP11
1054 template <typename T>
1055 using remove_all_extents_t = typename remove_all_extents<T>::type;
1056 #endif
1057
1058 //***************************************************************************
1060 template <typename T>
1061 struct rank : integral_constant<size_t, 0>
1062 {
1063 };
1064 template <typename T>
1065 struct rank<T[]> : public integral_constant<size_t, rank<T>::value + 1>
1066 {
1067 };
1068 template <typename T, size_t Size>
1069 struct rank<T[Size]> : public integral_constant<size_t, rank<T>::value + 1>
1070 {
1071 };
1072
1073 #if ETL_USING_CPP17
1074 template <typename T>
1075 inline constexpr size_t rank_v = rank<T>::value;
1076 #endif
1077
1078 //***************************************************************************
1080 template <typename T>
1081 struct decay
1082 {
1083 typedef typename etl::remove_reference<T>::type U;
1084 typedef typename etl::conditional<etl::is_array<U>::value, typename etl::remove_extent<U>::type*, typename etl::remove_cv<U>::type>::type type;
1085 };
1086
1087 #if ETL_USING_CPP11
1088 template <typename T>
1089 using decay_t = typename decay<T>::type;
1090 #endif
1091
1092 //***************************************************************************
1094 namespace private_type_traits
1095 {
1096 template <typename T>
1097 char test(int T::*); // Match for classes.
1098
1099 struct dummy
1100 {
1101 char c[2];
1102 };
1103 template <typename T>
1104 dummy test(...); // Match for non-classes.
1105 } // namespace private_type_traits
1106
1107 template <typename T>
1108 struct is_class : etl::bool_constant<sizeof(private_type_traits::test<T>(0)) == 1U>
1109 {
1110 };
1111
1112 #if ETL_USING_CPP17
1113 template <typename T>
1114 inline constexpr bool is_class_v = is_class<T>::value;
1115 #endif
1116
1117 //***************************************************************************
1119 #if ETL_USING_CPP11
1120 namespace private_type_traits
1121 {
1122 template <typename B>
1123 etl::true_type test_ptr_conv(const volatile B*);
1124 template <typename>
1125 etl::false_type test_ptr_conv(const volatile void*);
1126
1127 template <typename B, typename D>
1128 auto test_is_base_of(int) -> decltype(test_ptr_conv<B>(static_cast<D*>(nullptr)));
1129 template <typename, typename>
1130 auto test_is_base_of(...) -> etl::true_type; // private or ambiguous base
1131 } // namespace private_type_traits
1132
1133 template <typename TBase, typename TDerived>
1134 struct is_base_of
1135 : etl::integral_constant< bool, etl::is_class<TBase>::value
1136 && etl::is_class<TDerived>::value&& decltype(private_type_traits::test_is_base_of< TBase, TDerived>(0))::value >
1137 {
1138 };
1139 #else
1140 template <typename TBase, typename TDerived,
1141 const bool IsFundamental = (etl::is_fundamental<TBase>::value || etl::is_fundamental<TDerived>::value || etl::is_array<TDerived>::value)>
1142 struct is_base_of
1143 {
1144 private:
1145
1146 static TBase* check(TBase*)
1147 {
1148 return (TBase*)0;
1149 }
1150 static char check(...)
1151 {
1152 return 0;
1153 }
1154
1155 public:
1156
1157 static const bool value = (sizeof(check((TDerived*)0)) == sizeof(TBase*));
1158 };
1159
1160 // For when TBase or TDerived is a fundamental type.
1161 template <typename TBase, typename TDerived>
1162 struct is_base_of<TBase, TDerived, true>
1163 {
1164 static const bool value = false;
1165 };
1166 #endif
1167
1168 #if ETL_USING_CPP17
1169 template <typename T1, typename T2>
1170 inline constexpr bool is_base_of_v = is_base_of<T1, T2>::value;
1171 #endif
1172
1173 //***************************************************************************
1175 template <typename T>
1176 struct add_lvalue_reference
1177 {
1178 typedef T& type;
1179 };
1180 template <typename T>
1181 struct add_lvalue_reference<T&>
1182 {
1183 typedef T& type;
1184 };
1185 template <>
1186 struct add_lvalue_reference<void>
1187 {
1188 typedef void type;
1189 };
1190 template <>
1191 struct add_lvalue_reference<const void>
1192 {
1193 typedef const void type;
1194 };
1195 template <>
1196 struct add_lvalue_reference<volatile void>
1197 {
1198 typedef volatile void type;
1199 };
1200 template <>
1201 struct add_lvalue_reference<const volatile void>
1202 {
1203 typedef const volatile void type;
1204 };
1205
1206 #if ETL_USING_CPP11
1207 template <typename T>
1208 using add_lvalue_reference_t = typename etl::add_lvalue_reference<T>::type;
1209 #endif
1210
1211 //***************************************************************************
1213 #if ETL_USING_CPP11
1214 template <typename T>
1215 struct add_rvalue_reference
1216 {
1217 using type = T&&;
1218 };
1219 template <typename T>
1220 struct add_rvalue_reference<T&>
1221 {
1222 using type = T&;
1223 };
1224 template <>
1225 struct add_rvalue_reference<void>
1226 {
1227 using type = void;
1228 };
1229 template <>
1230 struct add_rvalue_reference<const void>
1231 {
1232 using type = const void;
1233 };
1234 template <>
1235 struct add_rvalue_reference<volatile void>
1236 {
1237 using type = volatile void;
1238 };
1239 template <>
1240 struct add_rvalue_reference<const volatile void>
1241 {
1242 using type = const volatile void;
1243 };
1244 #endif
1245
1246 #if ETL_USING_CPP11
1247 template <typename T>
1248 using add_rvalue_reference_t = typename etl::add_rvalue_reference<T>::type;
1249 #endif
1250
1251 //***************************************************************************
1253 #if ETL_USING_CPP11
1254 template <typename T>
1255 typename etl::add_rvalue_reference<T>::type declval() ETL_NOEXCEPT;
1256 #endif
1257
1258 #if ETL_USING_CPP11
1259 //***************************************************************************
1264
1265 namespace private_type_traits
1266 {
1267 // Base case
1268 template <typename T, typename = int>
1269 struct is_convertible_to_int : false_type
1270 {
1271 };
1272
1273 // Selected if `static_cast<int>(declval<T>())` is a valid statement
1274 // 2nd template argument of base case defaults to int to ensure that this
1275 // partial specialization is always tried first
1276 template <typename T>
1277 struct is_convertible_to_int<T, decltype(static_cast<int>(declval<T>()))> : true_type
1278 {
1279 };
1280 } // namespace private_type_traits
1281
1282 template <typename T>
1283 struct is_enum
1284 : integral_constant<bool, private_type_traits::is_convertible_to_int<T>::value && !is_class<T>::value && !is_arithmetic<T>::value
1285 && !is_reference<T>::value>
1286 {
1287 };
1288
1289 #if ETL_USING_CPP17
1290 template <typename T>
1291 inline constexpr bool is_enum_v = etl::is_enum<T>::value;
1292 #endif
1293 #else
1294 namespace private_type_traits
1295 {
1296 // Helper to detect if a type is convertible to an integer
1297 template <typename T>
1298 struct is_convertible_to_int
1299 {
1300 static char test(int); // Match if T is convertible to int
1301 static double test(...); // Fallback for other types
1302
1303 static const bool value = sizeof(test(static_cast<T>(0))) == sizeof(char);
1304 };
1305 } // namespace private_type_traits
1306
1307 // Implementation of is_enum
1308 template <typename T>
1309 struct is_enum
1310 {
1311 static const bool value =
1312 private_type_traits::is_convertible_to_int<T>::value && !is_class<T>::value && !is_arithmetic<T>::value && !is_reference<T>::value;
1313 };
1314 #endif
1315
1316 //***************************************************************************
1319 #if ETL_USING_CPP11
1320 namespace private_type_traits
1321 {
1322 template <typename>
1323 using true_type_for = etl::true_type;
1324
1325 template <typename T>
1326 auto returnable(int) -> true_type_for<T()>;
1327
1328 template <typename>
1329 auto returnable(...) -> etl::false_type;
1330
1331 template <typename TFrom, typename TTo>
1332 auto nonvoid_convertible(int) -> true_type_for< decltype(etl::declval<void (&)(TTo)>()(etl::declval<TFrom>())) >;
1333 template <typename, typename>
1334 auto nonvoid_convertible(...) -> etl::false_type;
1335 } // namespace private_type_traits
1336
1337 #if defined(ETL_COMPILER_ARM5)
1338 template <typename TFrom, typename TTo>
1339 struct is_convertible : etl::bool_constant<__is_convertible_to(TFrom, TTo)>
1340 {
1341 };
1342 #else
1343 template <typename TFrom, typename TTo>
1344 struct is_convertible
1345 : etl::bool_constant< (decltype(private_type_traits::returnable<TTo>(0))::value
1346 && decltype(private_type_traits::nonvoid_convertible<TFrom, TTo>(0))::value)
1347 || (etl::is_void<TFrom>::value && etl::is_void<TTo>::value)>
1348 {
1349 };
1350 #endif
1351
1352 // Is convertible and the conversion is noexcept.
1353 template <typename TFrom, typename TTo>
1354 struct is_nothrow_convertible
1355 {
1356 private:
1357
1358 // Helper: a function taking TTo to require the conversion.
1359 static void sink(TTo) noexcept;
1360
1361 // Selected only if 'sink(declval<TFrom>())' is a valid expression.
1362 template <typename F>
1363 static auto test(int) -> etl::bool_constant<noexcept(sink(etl::declval<F>()))>;
1364
1365 // Fallback if conversion is not viable.
1366 template <typename>
1367 static etl::false_type test(...);
1368
1369 public:
1370
1371 static ETL_CONSTANT bool value = decltype(test<TFrom>(0))::value;
1372 };
1373 #else
1374 namespace private_type_traits
1375 {
1376 typedef char yes;
1377 struct no
1378 {
1379 char dummy[2];
1380 };
1381
1382 template <typename TFrom, typename TTo>
1383 struct is_convertible_impl
1384 {
1385 static yes test(TTo);
1386 static no test(...);
1387 static TFrom make();
1388 static const bool value = (sizeof(test(make())) == sizeof(yes));
1389 };
1390
1391 template <typename TTo>
1392 struct is_convertible_impl<void, TTo>
1393 {
1394 static const bool value = false;
1395 };
1396
1397 template <typename TFrom>
1398 struct is_convertible_impl<TFrom, void>
1399 {
1400 static const bool value = false;
1401 };
1402
1403 template <>
1404 struct is_convertible_impl<void, void>
1405 {
1406 static const bool value = true;
1407 };
1408 } // namespace private_type_traits
1409
1410 template <typename TFrom, typename TTo>
1411 struct is_convertible : etl::bool_constant< private_type_traits::is_convertible_impl<TFrom, TTo>::value>
1412 {
1413 };
1414 #endif
1415
1416 #if ETL_USING_CPP17
1417 template <typename TFrom, typename TTo >
1418 inline constexpr bool is_convertible_v = etl::is_convertible<TFrom, TTo>::value;
1419
1420 template <typename TFrom, typename TTo >
1421 inline constexpr bool is_nothrow_convertible_v = etl::is_nothrow_convertible<TFrom, TTo>::value;
1422 #endif
1423
1424 //***************************************************************************
1427 #if ETL_USING_CPP11 && !defined(ETL_COMPILER_ARM5)
1428 template <typename T>
1429 struct alignment_of : integral_constant<size_t, alignof(T)>
1430 {
1431 };
1432 #elif defined(ETL_COMPILER_MICROSOFT)
1433 template <typename T>
1434 struct alignment_of : integral_constant<size_t, size_t(__alignof(T))>
1435 {
1436 };
1437 #elif defined(ETL_COMPILER_IAR) || defined(ETL_COMPILER_TI)
1438 template <typename T>
1439 struct alignment_of : integral_constant<size_t, size_t(__ALIGNOF__(T))>
1440 {
1441 };
1442 #else
1443 template <typename T>
1444 struct alignment_of : integral_constant<size_t, size_t(__alignof__(T))>
1445 {
1446 };
1447 #endif
1448
1451 template <>
1452 struct alignment_of<void> : integral_constant<size_t, 0>
1453 {
1454 };
1455 template <>
1456 struct alignment_of<const void> : integral_constant<size_t, 0>
1457 {
1458 };
1459
1460 #if ETL_USING_CPP17
1461 template <typename T>
1462 inline constexpr size_t alignment_of_v = etl::alignment_of<T>::value;
1463 #endif
1464
1465#else // Condition = ETL_USING_STL && ETL_USING_CPP11
1466
1467 //*****************************************************************************
1468 // Traits are derived from the STL
1469 //*****************************************************************************
1470
1471 //***************************************************************************
1474 template <typename T, T VALUE>
1475 struct integral_constant : std::integral_constant<T, VALUE>
1476 {
1477 };
1478
1482 typedef integral_constant<bool, true> true_type;
1483
1484 #if ETL_USING_CPP17
1485 template <typename T, T VALUE>
1486 inline constexpr T integral_constant_v = std::integral_constant<T, VALUE>::value;
1487 #endif
1488
1489 #if ETL_USING_CPP17
1490 template <bool BValue>
1491 using bool_constant = std::bool_constant<BValue>;
1492 #else
1493 template <bool BValue>
1494 struct bool_constant : std::integral_constant<bool, BValue>
1495 {
1496 };
1497 #endif
1498
1499 #if ETL_USING_CPP17
1500 template <bool BValue>
1501 inline constexpr bool bool_constant_v = bool_constant<BValue>::value;
1502 #endif
1503
1504 //***************************************************************************
1507 #if ETL_USING_CPP17
1508 template <typename T>
1509 using negation = std::negation<T>;
1510 #else
1511 template <typename T>
1512 struct negation : etl::bool_constant<!bool(T::value)>
1513 {
1514 };
1515 #endif
1516
1517 #if ETL_USING_CPP17
1518 template <typename T>
1519 inline constexpr bool negation_v = std::negation_v<T>;
1520 #endif
1521
1522 //***************************************************************************
1525 template <typename T>
1526 struct remove_reference : std::remove_reference<T>
1527 {
1528 };
1529
1530 #if ETL_USING_CPP11
1531 template <typename T>
1532 using remove_reference_t = typename std::remove_reference<T>::type;
1533 #endif
1534
1535 //***************************************************************************
1538 template <typename T>
1539 struct remove_pointer : std::remove_pointer<T>
1540 {
1541 };
1542
1543 #if ETL_USING_CPP11
1544 template <typename T>
1545 using remove_pointer_t = typename std::remove_pointer<T>::type;
1546 #endif
1547
1548 //***************************************************************************
1551 template <typename T>
1552 struct add_pointer : std::add_pointer<T>
1553 {
1554 };
1555
1556 #if ETL_USING_CPP11
1557 template <typename T>
1558 using add_pointer_t = typename std::add_pointer<T>::type;
1559 #endif
1560
1561 //***************************************************************************
1564 template <typename T>
1565 struct is_const : std::is_const<T>
1566 {
1567 };
1568
1569 #if ETL_USING_CPP17
1570 template <typename T>
1571 inline constexpr bool is_const_v = std::is_const_v<T>;
1572 #endif
1573
1574 //***************************************************************************
1577 template <typename T>
1578 struct remove_const : std::remove_const<T>
1579 {
1580 };
1581
1582 #if ETL_USING_CPP11
1583 template <typename T>
1584 using remove_const_t = typename std::remove_const<T>::type;
1585 #endif
1586
1587 //***************************************************************************
1590 template <typename T>
1591 struct add_const : std::add_const<T>
1592 {
1593 };
1594
1595 #if ETL_USING_CPP11
1596 template <typename T>
1597 using add_const_t = typename std::add_const<T>::type;
1598 #endif
1599
1600 //***************************************************************************
1603 template <typename T>
1604 struct is_volatile : std::is_volatile<T>
1605 {
1606 };
1607
1608 #if ETL_USING_CPP17
1609 template <typename T>
1610 inline constexpr bool is_volatile_v = std::is_volatile_v<T>;
1611 #endif
1612
1613 //***************************************************************************
1616 template <typename T>
1617 struct remove_volatile : std::remove_volatile<T>
1618 {
1619 };
1620
1621 #if ETL_USING_CPP11
1622 template <typename T>
1623 using remove_volatile_t = typename std::remove_volatile<T>::type;
1624 #endif
1625
1626 //***************************************************************************
1629 template <typename T>
1630 struct add_volatile : std::add_volatile<T>
1631 {
1632 };
1633
1634 #if ETL_USING_CPP11
1635 template <typename T>
1636 using add_volatile_t = typename std::add_volatile<T>::type;
1637 #endif
1638
1639 //***************************************************************************
1642 template <typename T>
1643 struct remove_cv : std::remove_cv<T>
1644 {
1645 };
1646
1647 #if ETL_USING_CPP11
1648 template <typename T>
1649 using remove_cv_t = typename std::remove_cv<T>::type;
1650 #endif
1651
1652 //***************************************************************************
1655 template <typename T>
1656 struct add_cv : std::add_cv<T>
1657 {
1658 };
1659
1660 #if ETL_USING_CPP11
1661 template <typename T>
1662 using add_cv_t = typename std::add_cv<T>::type;
1663 #endif
1664
1665 //***************************************************************************
1668 template <typename T>
1669 struct remove_cvref
1670 {
1671 typedef typename std::remove_cv<typename std::remove_reference<T>::type>::type type;
1672 };
1673
1674 #if ETL_USING_CPP11
1675 template <typename T>
1676 using remove_cvref_t = typename etl::remove_cvref<T>::type;
1677 #endif
1678
1679 //***************************************************************************
1682 template <typename T>
1683 struct is_integral : std::is_integral<T>
1684 {
1685 };
1686
1687 #if ETL_USING_CPP17
1688 template <typename T>
1689 inline constexpr bool is_integral_v = std::is_integral_v<T>;
1690 #endif
1691
1692 //***************************************************************************
1695 template <typename T>
1696 struct is_signed : std::is_signed<T>
1697 {
1698 };
1699
1700 #if ETL_USING_CPP17
1701 template <typename T>
1702 inline constexpr bool is_signed_v = std::is_signed_v<T>;
1703 #endif
1704
1705 //***************************************************************************
1708 template <typename T>
1709 struct is_unsigned : std::is_unsigned<T>
1710 {
1711 };
1712
1713 #if ETL_USING_CPP17
1714 template <typename T>
1715 inline constexpr bool is_unsigned_v = std::is_unsigned_v<T>;
1716 #endif
1717
1718 //***************************************************************************
1721 template <typename T>
1722 struct is_floating_point : std::is_floating_point<T>
1723 {
1724 };
1725
1726 #if ETL_USING_CPP17
1727 template <typename T>
1728 inline constexpr bool is_floating_point_v = std::is_floating_point_v<T>;
1729 #endif
1730
1731 //***************************************************************************
1734 template <typename T1, typename T2>
1735 struct is_same : std::is_same<T1, T2>
1736 {
1737 };
1738
1739 #if ETL_USING_CPP17
1740 template <typename T1, typename T2>
1741 inline constexpr bool is_same_v = std::is_same_v<T1, T2>;
1742 #endif
1743
1744 //***************************************************************************
1747 template <typename T>
1748 struct is_void : std::is_void<T>
1749 {
1750 };
1751
1752 #if ETL_USING_CPP17
1753 template <typename T>
1754 inline constexpr bool is_void_v = std::is_void_v<T>;
1755 #endif
1756
1757 //***************************************************************************
1760 template <typename T>
1761 struct is_arithmetic : std::is_arithmetic<T>
1762 {
1763 };
1764
1765 #if ETL_USING_CPP17
1766 template <typename T>
1767 inline constexpr bool is_arithmetic_v = std::is_arithmetic_v<T>;
1768 #endif
1769
1770 //***************************************************************************
1773 template <typename T>
1774 struct is_fundamental : std::is_fundamental<T>
1775 {
1776 };
1777
1778 #if ETL_USING_CPP17
1779 template <typename T>
1780 inline constexpr bool is_fundamental_v = std::is_fundamental_v<T>;
1781 #endif
1782
1783 //***************************************************************************
1786 template <typename T>
1787 struct is_compound : std::is_compound<T>
1788 {
1789 };
1790
1791 #if ETL_USING_CPP17
1792 template <typename T>
1793 inline constexpr bool is_compound_v = std::is_compound_v<T>;
1794 #endif
1795
1796 //***************************************************************************
1799 template <typename T>
1800 struct is_array : std::is_array<T>
1801 {
1802 };
1803
1804 #if ETL_USING_CPP17
1805 template <typename T>
1806 inline constexpr bool is_array_v = std::is_array_v<T>;
1807 #endif
1808
1809 //***************************************************************************
1812 template <typename T>
1813 struct is_pointer : std::is_pointer<T>
1814 {
1815 };
1816
1817 #if ETL_USING_CPP17
1818 template <typename T>
1819 inline constexpr bool is_pointer_v = std::is_pointer_v<T>;
1820 #endif
1821
1822 //***************************************************************************
1825 template <typename T>
1826 struct is_reference : std::is_reference<T>
1827 {
1828 };
1829
1830 #if ETL_USING_CPP17
1831 template <typename T>
1832 inline constexpr bool is_reference_v = std::is_reference_v<T>;
1833 #endif
1834
1835 //***************************************************************************
1838 template <typename T>
1839 struct is_lvalue_reference : std::is_lvalue_reference<T>
1840 {
1841 };
1842
1843 #if ETL_USING_CPP17
1844 template <typename T>
1845 inline constexpr bool is_lvalue_reference_v = std::is_lvalue_reference_v<T>;
1846 #endif
1847
1848 //***************************************************************************
1851 #if ETL_USING_CPP11
1852 template <typename T>
1853 struct is_rvalue_reference : std::is_rvalue_reference<T>
1854 {
1855 };
1856
1857 #if ETL_USING_CPP17
1858 template <typename T>
1859 inline constexpr bool is_rvalue_reference_v = std::is_rvalue_reference_v<T>;
1860 #endif
1861 #endif
1862
1863 //***************************************************************************
1866 template <typename T>
1867 struct is_pod
1868 : std::integral_constant< bool, std::is_standard_layout<T>::value && std::is_trivially_default_constructible<T>::value
1869 && std::is_trivially_copyable<T>::value>
1870 {
1871 };
1872
1873 #if ETL_USING_CPP17
1874 template <typename T>
1875 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>;
1876 #endif
1877
1878 #if defined(ETL_COMPILER_GCC)
1879 #if ETL_COMPILER_VERSION >= 5
1880 #define ETL_GCC_V5_TYPE_TRAITS_SUPPORTED
1881 #endif
1882 #endif
1883
1884 //***************************************************************************
1887 template <bool BValue, typename T, typename F>
1888 struct conditional
1889 {
1890 typedef T type;
1891 };
1892 template <typename T, typename F>
1893 struct conditional<false, T, F>
1894 {
1895 typedef F type;
1896 };
1897
1898 #if ETL_USING_CPP11
1899 template <bool BValue, typename T, typename F>
1900 using conditional_t = typename conditional<BValue, T, F>::type;
1901 #endif
1902
1903 //***************************************************************************
1906 template <typename T>
1907 struct make_signed : std::make_signed<T>
1908 {
1909 };
1910
1911 #if ETL_USING_CPP11
1912 template <typename T>
1913 using make_signed_t = typename std::make_signed<T>::type;
1914 #endif
1915
1916 //***************************************************************************
1919 template <typename T>
1920 struct make_unsigned : std::make_unsigned<T>
1921 {
1922 };
1923
1924 #if ETL_USING_CPP11
1925 template <typename T>
1926 using make_unsigned_t = typename std::make_unsigned<T>::type;
1927 #endif
1928
1929 //***************************************************************************
1932 template <bool BValue, typename T = void>
1933 struct enable_if : std::enable_if<BValue, T>
1934 {
1935 };
1936
1937 #if ETL_USING_CPP11
1938 template <bool BValue, typename T = void>
1939 using enable_if_t = typename std::enable_if<BValue, T>::type;
1940 #endif
1941
1942 //***************************************************************************
1945 template <typename T, unsigned Size = 0U>
1946 struct extent : std::extent<T, Size>
1947 {
1948 };
1949
1950 #if ETL_USING_CPP17
1951 template <typename T, unsigned Size = 0U>
1952 inline constexpr size_t extent_v = std::extent_v<T, Size>;
1953 #endif
1954
1955 //***************************************************************************
1958 template <typename T>
1959 struct remove_extent : std::remove_extent<T>
1960 {
1961 };
1962
1963 #if ETL_USING_CPP11
1964 template <typename T>
1965 using remove_extent_t = typename std::remove_extent<T>::type;
1966 #endif
1967
1968 //***************************************************************************
1971 template <typename T>
1972 struct remove_all_extents : std::remove_all_extents<T>
1973 {
1974 };
1975
1976 #if ETL_USING_CPP11
1977 template <typename T>
1978 using remove_all_extents_t = typename std::remove_all_extents<T>::type;
1979 #endif
1980
1981 //***************************************************************************
1984 template <typename T>
1985 struct rank : std::rank<T>
1986 {
1987 };
1988
1989 #if ETL_USING_CPP17
1990 template <typename T>
1991 inline constexpr size_t rank_v = std::rank_v<T>;
1992 #endif
1993
1994 //***************************************************************************
1997 template <typename T>
1998 struct decay : std::decay<T>
1999 {
2000 };
2001
2002 #if ETL_USING_CPP11
2003 template <typename T>
2004 using decay_t = typename std::decay<T>::type;
2005 #endif
2006
2007 //***************************************************************************
2010 template <typename TBase, typename TDerived>
2011 struct is_base_of : std::is_base_of<TBase, TDerived>
2012 {
2013 };
2014
2015 #if ETL_USING_CPP17
2016 template <typename TBase, typename TDerived>
2017 inline constexpr bool is_base_of_v = std::is_base_of_v<TBase, TDerived>;
2018 #endif
2019
2020 //***************************************************************************
2022 template <typename T>
2023 struct is_class : std::is_class<T>
2024 {
2025 };
2026
2027 #if ETL_USING_CPP17
2028 template <typename T>
2029 inline constexpr bool is_class_v = is_class<T>::value;
2030 #endif
2031
2032 //***************************************************************************
2034 template <typename T>
2035 struct add_lvalue_reference : std::add_lvalue_reference<T>
2036 {
2037 };
2038
2039 #if ETL_USING_CPP11
2040 template <typename T>
2041 using add_lvalue_reference_t = typename std::add_lvalue_reference<T>::type;
2042 #endif
2043
2044 //***************************************************************************
2046 #if ETL_USING_CPP11
2047 template <typename T>
2048 struct add_rvalue_reference : std::add_rvalue_reference<T>
2049 {
2050 };
2051 #endif
2052
2053 #if ETL_USING_CPP11
2054 template <typename T>
2055 using add_rvalue_reference_t = typename std::add_rvalue_reference<T>::type;
2056 #endif
2057
2058 //***************************************************************************
2060 #if ETL_USING_CPP11
2061 template <typename T>
2062 typename std::add_rvalue_reference<T>::type declval() ETL_NOEXCEPT;
2063 #endif
2064
2065 #if ETL_USING_CPP11
2066 //***************************************************************************
2069 template <typename T>
2070 struct is_enum : std::is_enum<T>
2071 {
2072 };
2073
2074 #if ETL_USING_CPP17
2075 template <typename T>
2076 inline constexpr bool is_enum_v = etl::is_enum<T>::value;
2077 #endif
2078
2079 #endif
2080
2081 //***************************************************************************
2084 #if ETL_USING_CPP11
2085 template <typename TFrom, typename TTo>
2086 struct is_convertible : std::is_convertible<TFrom, TTo>
2087 {
2088 };
2089
2090 // Is convertible and the conversion is noexcept.
2091 template <typename TFrom, typename TTo>
2092 struct is_nothrow_convertible
2093 {
2094 private:
2095
2096 // Helper: a function taking TTo to require the conversion.
2097 static void sink(TTo) noexcept;
2098
2099 // Selected only if 'sink(declval<TFrom>())' is a valid expression.
2100 template <typename F>
2101 static auto test(int) -> etl::bool_constant<noexcept(sink(etl::declval<F>()))>;
2102
2103 // Fallback if conversion is not viable.
2104 template <typename>
2105 static etl::false_type test(...);
2106
2107 public:
2108
2109 static ETL_CONSTANT bool value = decltype(test<TFrom>(0))::value;
2110 };
2111 #else
2112 namespace private_type_traits
2113 {
2114 typedef char yes;
2115 struct no
2116 {
2117 char dummy[2];
2118 };
2119
2120 template <typename TFrom, typename TTo>
2121 struct is_convertible_impl
2122 {
2123 static yes test(TTo);
2124 static no test(...);
2125 static TFrom make();
2126 static const bool value = (sizeof(test(make())) == sizeof(yes));
2127 };
2128
2129 template <typename TTo>
2130 struct is_convertible_impl<void, TTo>
2131 {
2132 static const bool value = false;
2133 };
2134
2135 template <typename TFrom>
2136 struct is_convertible_impl<TFrom, void>
2137 {
2138 static const bool value = false;
2139 };
2140
2141 template <>
2142 struct is_convertible_impl<void, void>
2143 {
2144 static const bool value = true;
2145 };
2146 } // namespace private_type_traits
2147
2148 template <typename TFrom, typename TTo>
2149 struct is_convertible : etl::bool_constant< private_type_traits::is_convertible_impl<TFrom, TTo>::value>
2150 {
2151 };
2152 #endif
2153
2154 #if ETL_USING_CPP17
2155 template <typename TFrom, typename TTo>
2156 inline constexpr bool is_convertible_v = std::is_convertible_v<TFrom, TTo>;
2157
2158 template <typename TFrom, typename TTo >
2159 inline constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<TFrom, TTo>::value;
2160 #endif
2161
2162 //***************************************************************************
2165 template <typename T>
2166 struct alignment_of : std::alignment_of<T>
2167 {
2168 };
2169 template <>
2170 struct alignment_of<void> : std::integral_constant<size_t, 0>
2171 {
2172 };
2173 template <>
2174 struct alignment_of<const void> : std::integral_constant<size_t, 0>
2175 {
2176 };
2177
2178 #if ETL_USING_CPP17
2179 template <typename T>
2180 inline constexpr size_t alignment_of_v = std::alignment_of_v<T>;
2181 #endif
2182
2183#endif // Condition = ETL_USING_STL && ETL_USING_CPP11
2184
2185 //***************************************************************************
2186 // ETL extended type traits.
2187 //***************************************************************************
2188
2189#if ETL_USING_CPP11
2190 //***************************************************************************
2192 #if ETL_USING_CPP11
2193 template <typename...>
2194 struct conjunction : public etl::true_type
2195 {
2196 };
2197
2198 template <typename T1, typename... Tn>
2199 struct conjunction<T1, Tn...> : public etl::conditional_t<bool(T1::value), etl::conjunction<Tn...>, T1>
2200 {
2201 };
2202
2203 template <typename T>
2204 struct conjunction<T> : public T
2205 {
2206 };
2207 #endif
2208
2209 #if ETL_USING_CPP17
2210 template <typename... T>
2211 inline constexpr bool conjunction_v = conjunction<T...>::value;
2212 #endif
2213
2214 //***************************************************************************
2216 #if ETL_USING_CPP11
2217 template <typename...>
2218 struct disjunction : public etl::false_type
2219 {
2220 };
2221
2222 template <typename T1, typename... Tn>
2223 struct disjunction<T1, Tn...> : public etl::conditional_t<bool(T1::value), T1, disjunction<Tn...>>
2224 {
2225 };
2226
2227 template <typename T1>
2228 struct disjunction<T1> : public T1
2229 {
2230 };
2231 #endif
2232
2233 #if ETL_USING_CPP17
2234 template <typename... T>
2235 inline constexpr bool disjunction_v = etl::disjunction<T...>::value;
2236 #endif
2237
2238#endif
2239
2240 //***************************************************************************
2242#if ETL_USING_CPP11
2243 template <typename... TTypes>
2244 struct exclusive_disjunction;
2245
2246 template <typename T>
2247 struct exclusive_disjunction<T> : public etl::bool_constant<T::value>
2248 {
2249 };
2250
2251 // Recursive case: XOR the first two values and recurse
2252 template <typename T1, typename T2, typename... TRest>
2253 struct exclusive_disjunction<T1, T2, TRest...>
2254 : public etl::exclusive_disjunction< etl::integral_constant<bool, etl::disjunction<T1, T2>::value && !etl::conjunction<T1, T2>::value>, TRest...>
2255 {
2256 };
2257#endif
2258
2259#if ETL_USING_CPP17
2260 template <typename... T>
2261 inline constexpr bool exclusive_disjunction_v = etl::exclusive_disjunction<T...>::value;
2262#endif
2263
2264 //***************************************************************************
2266 // /\ingroup type_traits
2267 template <bool BValue, typename T, T TRUE_VALUE, T FALSE_VALUE>
2268 struct conditional_integral_constant;
2269
2270 template <typename T, T TRUE_VALUE, T FALSE_VALUE>
2271 struct conditional_integral_constant<true, T, TRUE_VALUE, FALSE_VALUE>
2272 {
2273 ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Not an integral type");
2274 static const T value = TRUE_VALUE;
2275 };
2276
2277 template <typename T, T TRUE_VALUE, T FALSE_VALUE>
2278 struct conditional_integral_constant<false, T, TRUE_VALUE, FALSE_VALUE>
2279 {
2280 ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Not an integral type");
2281 static const T value = FALSE_VALUE;
2282 };
2283
2284#if ETL_USING_CPP11
2285 //***************************************************************************
2289 template <typename T, typename... TRest>
2290 struct is_one_of : etl::disjunction<etl::is_same<T, TRest>...>
2291 {
2292 };
2293#else
2294 #include "private/type_traits_cpp03.h"
2295#endif
2296
2297#if ETL_USING_CPP17
2298 template <typename T, typename... TRest>
2299 inline constexpr bool is_one_of_v = etl::is_one_of<T, TRest...>::value;
2300#endif
2301
2302#if ETL_USING_CPP11
2303 namespace private_type_traits
2304 {
2305 //***************************************************************************
2306 // Helper to count occurrences of a type in a list of types
2307 template <typename T, typename... TTypes>
2308 struct count_type;
2309
2310 // Base case: zero occurrences
2311 template <typename T>
2312 struct count_type<T> : etl::integral_constant<size_t, 0>
2313 {
2314 };
2315
2316 // Recursive case: increment count if head is the same as T, otherwise
2317 // continue with tail
2318 template <typename T, typename THead, typename... TTail>
2319 struct count_type<T, THead, TTail...> : etl::integral_constant<size_t, (etl::is_same<T, THead>::value ? 1 : 0) + count_type<T, TTail...>::value>
2320 {
2321 };
2322 } // namespace private_type_traits
2323
2324 template <typename T, typename... TTypes>
2325 struct has_duplicates_of : etl::integral_constant< bool, (private_type_traits::count_type<T, TTypes...>::value > 1)>
2326 {
2327 };
2328#endif
2329
2330#if ETL_USING_CPP17
2331 template <typename T, typename... TRest>
2332 inline constexpr bool has_duplicates_of_v = etl::has_duplicates_of<T, TRest...>::value;
2333#endif
2334
2335#if ETL_USING_CPP11
2336 //***************************************************************************
2340 template <typename TBase, typename... TDerived>
2341 struct is_base_of_all : etl::conjunction<etl::is_base_of<TBase, TDerived>...>
2342 {
2343 };
2344#endif
2345
2346#if ETL_USING_CPP17
2347 template <typename T, typename... TRest>
2348 inline constexpr bool is_base_of_all_v = etl::is_base_of_all<T, TRest...>::value;
2349#endif
2350
2351#if ETL_USING_CPP11
2352 //***************************************************************************
2355 template <typename TBase, typename... TDerived>
2356 struct is_base_of_any : etl::disjunction<etl::is_base_of<TBase, TDerived>...>
2357 {
2358 };
2359
2360#endif
2361
2362#if ETL_USING_CPP17
2363 template <typename T, typename... TRest>
2364 inline constexpr bool is_base_of_any_v = etl::is_base_of_any<T, TRest...>::value;
2365#endif
2366
2367 //***************************************************************************
2370 //***************************************************************************
2371 // Recursive definition of the type.
2372 template <size_t Index, typename TType>
2373 struct nth_base
2374 {
2375 typedef typename nth_base<Index - 1U, typename TType::base_type>::type type;
2376 };
2377
2378 template <typename TType>
2379 struct nth_base<0, TType>
2380 {
2381 typedef TType type;
2382 };
2383
2384#if ETL_USING_CPP11
2385 template <size_t Index, typename TType>
2386 using nth_base_t = typename nth_base<Index, TType>::type;
2387#endif
2388
2389 //***************************************************************************
2392
2393 // Default.
2394 template <typename T>
2395 struct types
2396 {
2397 private:
2398
2399 typedef typename etl::remove_reference<typename etl::remove_cv<T>::type>::type type_t;
2400
2401 public:
2402
2403 typedef type_t type;
2404 typedef type_t& reference;
2405 typedef const type_t& const_reference;
2406 typedef type_t* pointer;
2407 typedef const type_t* const_pointer;
2408 typedef const type_t* const const_pointer_const;
2409
2410#if ETL_USING_CPP11
2411 typedef type_t&& rvalue_reference;
2412#endif
2413 };
2414
2415 // Pointers.
2416 template <typename T>
2417 struct types<T*>
2418 {
2419 private:
2420
2421 typedef typename etl::remove_reference<typename etl::remove_cv<T>::type>::type type_t;
2422
2423 public:
2424
2425 typedef type_t type;
2426 typedef type_t& reference;
2427 typedef const type_t& const_reference;
2428 typedef type_t* pointer;
2429 typedef const type_t* const_pointer;
2430 typedef const type_t* const const_pointer_const;
2431
2432#if ETL_USING_CPP11
2433 typedef type_t&& rvalue_reference;
2434#endif
2435 };
2436
2437 // Pointers.
2438 template <typename T>
2439 struct types<T* const>
2440 {
2441 private:
2442
2443 typedef typename etl::remove_reference<typename etl::remove_cv<T>::type>::type type_t;
2444
2445 public:
2446
2447 typedef type_t type;
2448 typedef type_t& reference;
2449 typedef const type_t& const_reference;
2450 typedef type_t* pointer;
2451 typedef const type_t* const_pointer;
2452 typedef const type_t* const const_pointer_const;
2453
2454#if ETL_USING_CPP11
2455 typedef type_t&& rvalue_reference;
2456#endif
2457 };
2458
2459 // References.
2460 template <typename T>
2461 struct types<T&>
2462 {
2463 private:
2464
2465 typedef typename etl::remove_reference<typename etl::remove_cv<T>::type>::type type_t;
2466
2467 public:
2468
2469 typedef type_t type;
2470 typedef type_t& reference;
2471 typedef const type_t& const_reference;
2472 typedef type_t* pointer;
2473 typedef const type_t* const_pointer;
2474 typedef const type_t* const const_pointer_const;
2475
2476#if ETL_USING_CPP11
2477 typedef type_t&& rvalue_reference;
2478#endif
2479 };
2480
2481#if ETL_USING_CPP11
2482 // rvalue References.
2483 template <typename T>
2484 struct types<T&&>
2485 {
2486 private:
2487
2488 typedef typename etl::remove_reference<typename etl::remove_cv<T>::type>::type type_t;
2489
2490 public:
2491
2492 typedef type_t type;
2493 typedef type_t& reference;
2494 typedef const type_t& const_reference;
2495 typedef type_t* pointer;
2496 typedef const type_t* const_pointer;
2497 typedef const type_t* const const_pointer_const;
2498
2499 #if ETL_USING_CPP11
2500 typedef type_t&& rvalue_reference;
2501 #endif
2502 };
2503#endif
2504
2505#if ETL_USING_CPP11
2506 template <typename T>
2507 using types_t = typename types<T>::type;
2508
2509 template <typename T>
2510 using types_r = typename types<T>::reference;
2511
2512 template <typename T>
2513 using types_cr = typename types<T>::const_reference;
2514
2515 template <typename T>
2516 using types_rr = typename types<T>::rvalue_reference;
2517
2518 template <typename T>
2519 using types_p = typename types<T>::pointer;
2520
2521 template <typename T>
2522 using types_cp = typename types<T>::const_pointer;
2523
2524 template <typename T>
2525 using types_cpc = typename types<T>::const_pointer_const;
2526#endif
2527
2528 //***************************************************************************
2531 template <typename T>
2532 struct size_of : etl::integral_constant<size_t, sizeof(T)>
2533 {
2534 };
2535 template <>
2536 struct size_of<void> : etl::integral_constant<size_t, 1U>
2537 {
2538 };
2539
2540#if ETL_USING_CPP17
2541 template <typename T>
2542 inline constexpr size_t size_of_v = etl::size_of<T>::value;
2543#endif
2544
2545#if ETL_USING_CPP11
2546 //***************************************************************************
2548 template <typename T, typename... TRest>
2549 struct are_all_same : etl::conjunction<etl::is_same<T, TRest>...>
2550 {
2551 };
2552#endif
2553
2554#if ETL_USING_CPP17
2555 template <typename T, typename... TRest>
2556 inline constexpr bool are_all_same_v = are_all_same<T, TRest...>::value;
2557#endif
2558
2559 //***************************************************************************
2560#if ETL_USING_STL && ETL_USING_CPP11 && !defined(ETL_USE_TYPE_TRAITS_BUILTINS) && !defined(ETL_USER_DEFINED_TYPE_TRAITS) \
2561 && ((!defined(ARDUINO) && ETL_NOT_USING_STLPORT) || defined(ETL_GCC_V5_TYPE_TRAITS_SUPPORTED))
2562
2563 //*********************************************
2564 // Use the STL's definitions.
2565 //*********************************************
2566
2567 //*********************************************
2568 // is_assignable
2569 template <typename T1, typename T2>
2570 using is_assignable = std::is_assignable<T1, T2>;
2571
2572 //*********************************************
2573 // is_constructible
2574 template <typename T, typename... TArgs>
2575 using is_constructible = std::is_constructible<T, TArgs...>;
2576
2577 //*********************************************
2578 // is_copy_constructible
2579 template <typename T>
2580 using is_copy_constructible = std::is_copy_constructible<T>;
2581
2582 //*********************************************
2583 // is_move_constructible
2584 template <typename T>
2585 using is_move_constructible = std::is_move_constructible<T>;
2586
2587 //*********************************************
2588 // is_copy_assignable
2589 template <typename T>
2590 using is_copy_assignable = std::is_copy_assignable<T>;
2591
2592 //*********************************************
2593 // is_move_assignable
2594 template <typename T>
2595 using is_move_assignable = std::is_move_assignable<T>;
2596
2597 //*********************************************
2598 // is_trivially_constructible
2599 #if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED
2600 template <typename T>
2601 using is_trivially_constructible = std::is_trivially_constructible<T>;
2602 #else
2603 template <typename T>
2604 using is_trivially_constructible = etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>;
2605 #endif
2606
2607 //*********************************************
2608 // is_trivially_copy_constructible
2609 #if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED
2610 template <typename T>
2611 using is_trivially_copy_constructible = std::is_trivially_copy_constructible<T>;
2612 #else
2613 template <typename T>
2614 using is_trivially_copy_constructible = etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>;
2615 #endif
2616
2617 //*********************************************
2618 // is_trivially_destructible
2619 #if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED
2620 template <typename T>
2621 using is_trivially_destructible = std::is_trivially_destructible<T>;
2622 #else
2623 template <typename T>
2624 using is_trivially_destructible = etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>;
2625 #endif
2626
2627 //*********************************************
2628 // is_trivially_copy_assignable
2629 #if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED
2630 template <typename T>
2631 using is_trivially_copy_assignable = std::is_trivially_copy_assignable<T>;
2632 #else
2633 template <typename T>
2634 using is_trivially_copy_assignable = etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>;
2635 #endif
2636
2637 //*********************************************
2638 // is_trivially_copyable
2639 #if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED
2640 template <typename T>
2641 using is_trivially_copyable = std::is_trivially_copyable<T>;
2642 #elif ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE
2643 template <typename T>
2644 using is_trivially_copyable = etl::bool_constant<__is_trivially_copyable(T)>;
2645 #else
2646 template <typename T>
2647 using is_trivially_copyable = etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>;
2648 #endif
2649
2650#elif defined(ETL_USE_TYPE_TRAITS_BUILTINS) && !defined(ETL_USER_DEFINED_TYPE_TRAITS)
2651
2652 //*********************************************
2653 // Use the compiler's builtins.
2654 //*********************************************
2655
2656 //*********************************************
2657 // is_assignable
2658 template <typename T1, typename T2>
2659 struct is_assignable
2660 {
2661 static ETL_CONSTANT bool value = __is_assignable(T1, T2);
2662 };
2663
2664 #if ETL_USING_CPP11
2665 //*********************************************
2666 // is_constructible
2667 template <typename T, typename... TArgs>
2668 struct is_constructible
2669 {
2670 static ETL_CONSTANT bool value = __is_constructible(T, TArgs...);
2671 };
2672 #else
2673 //*********************************************
2674 // is_constructible
2675 template <typename T, typename TArgs = void>
2676 struct is_constructible
2677 {
2678 static ETL_CONSTANT bool value = __is_constructible(T, TArgs);
2679 };
2680
2681 //*********************************************
2682 // is_constructible
2683 template <typename T>
2684 struct is_constructible<T, void>
2685 {
2686 static ETL_CONSTANT bool value = __is_constructible(T);
2687 };
2688 #endif
2689
2690 //*********************************************
2691 // is_copy_constructible
2692 template <typename T>
2693 struct is_copy_constructible : public etl::is_constructible< T, typename etl::add_lvalue_reference<const T>::type>
2694 {
2695 };
2696
2697 //*********************************************
2698 // is_move_constructible
2699 template <typename T>
2700 struct is_move_constructible : public etl::is_constructible<T, T>
2701 {
2702 };
2703
2704 //*********************************************
2705 // is_copy_assignable
2706 template <typename T>
2707 struct is_copy_assignable
2708 : public etl::is_assignable< typename etl::add_lvalue_reference<T>::type, typename etl::add_lvalue_reference<const T>::type>
2709 {
2710 };
2711
2712 //*********************************************
2713 // is_move_assignable
2714 #if ETL_USING_CPP11
2715 template <typename T>
2716 struct is_move_assignable : public etl::is_assignable<typename etl::add_lvalue_reference<T>::type, typename etl::add_rvalue_reference<T>::type>
2717 {
2718 };
2719 #else
2720 template <typename T>
2721 struct is_move_assignable : public etl::is_assignable<typename etl::add_lvalue_reference<T>::type, T>
2722 {
2723 };
2724 #endif
2725
2726 #if ETL_USING_CPP11
2727 //*********************************************
2728 // is_trivially_constructible
2729 template <typename T, typename... TArgs>
2730 struct is_trivially_constructible
2731 {
2732 #if defined(ETL_COMPILER_GCC)
2733 static ETL_CONSTANT bool value = __has_trivial_constructor(T);
2734 #else
2735 static ETL_CONSTANT bool value = __is_trivially_constructible(T, TArgs...);
2736 #endif
2737 };
2738 #else
2739 //*********************************************
2740 // is_trivially_constructible
2741 template <typename T, typename TArgs = void>
2742 struct is_trivially_constructible
2743 {
2744 #if defined(ETL_COMPILER_GCC)
2745 static ETL_CONSTANT bool value = __has_trivial_constructor(T);
2746 #else
2747 static ETL_CONSTANT bool value = __is_trivially_constructible(T, TArgs);
2748 #endif
2749 };
2750
2751 //*********************************************
2752 // is_trivially_constructible
2753 template <typename T>
2754 struct is_trivially_constructible<T, void>
2755 {
2756 #if defined(ETL_COMPILER_GCC)
2757 static ETL_CONSTANT bool value = __has_trivial_constructor(T);
2758 #else
2759 static ETL_CONSTANT bool value = __is_trivially_constructible(T);
2760 #endif
2761 };
2762 #endif
2763
2764 //*********************************************
2765 // is_trivially_copy_constructible
2766 template <typename T>
2767 struct is_trivially_copy_constructible : public is_trivially_constructible< T, typename add_lvalue_reference<const T>::type>
2768 {
2769 };
2770
2771 //*********************************************
2772 // is_trivially_destructible
2773 template <typename T>
2774 struct is_trivially_destructible
2775 {
2776 #if defined(ETL_COMPILER_GCC)
2777 static ETL_CONSTANT bool value = __has_trivial_destructor(T);
2778 #else
2779 static ETL_CONSTANT bool value = __is_trivially_destructible(T);
2780 #endif
2781 };
2782
2783 //*********************************************
2784 // is_trivially_copy_assignable
2785 template <typename T>
2786 struct is_trivially_copy_assignable
2787 {
2788 #if defined(ETL_COMPILER_GCC)
2789 static ETL_CONSTANT bool value = __has_trivial_copy(T);
2790 #else
2791 static ETL_CONSTANT bool value = __is_trivially_copyable(T);
2792 #endif
2793 };
2794
2795 //*********************************************
2796 // is_trivially_copyable
2797 template <typename T>
2798 struct is_trivially_copyable
2799 {
2800 static ETL_CONSTANT bool value = __is_trivially_copyable(T);
2801 };
2802
2803#elif defined(ETL_USER_DEFINED_TYPE_TRAITS) && !defined(ETL_USE_TYPE_TRAITS_BUILTINS)
2804
2805 //*********************************************
2806 // Force the user to provide specialisations for
2807 // anything other than arithmetics and pointers.
2808 //*********************************************
2809
2810 //*********************************************
2811 // is_assignable
2812 template <typename T1, typename T2,
2813 bool BValue =
2814 (etl::is_arithmetic<T1>::value || etl::is_pointer<T1>::value) && (etl::is_arithmetic<T2>::value || etl::is_pointer<T2>::value)>
2815 struct is_assignable;
2816
2817 template <typename T1, typename T2>
2818 struct is_assignable<T1, T2, true> : public etl::true_type
2819 {
2820 };
2821
2822 template <typename T1, typename T2>
2823 struct is_assignable<T1, T2, false>;
2824
2825 #if ETL_USING_CPP11
2826 //*********************************************
2827 // is_constructible
2828 template <typename T, bool BValue, typename... TArgs>
2829 struct is_constructible_helper;
2830
2831 template <typename T, typename... TArgs>
2832 struct is_constructible_helper<T, true, TArgs...> : public etl::true_type
2833 {
2834 };
2835
2836 template <typename T, typename... TArgs>
2837 struct is_constructible_helper<T, false, TArgs...>;
2838
2839 template <typename T, typename... TArgs>
2840 struct is_constructible : public is_constructible_helper< T, etl::is_arithmetic<T>::value || etl::is_pointer<T>::value, TArgs...>
2841 {
2842 };
2843 #endif
2844
2845 //*********************************************
2846 // is_copy_constructible
2847 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
2848 struct is_copy_constructible;
2849
2850 template <typename T>
2851 struct is_copy_constructible<T, true> : public etl::true_type
2852 {
2853 };
2854
2855 template <typename T>
2856 struct is_copy_constructible<T, false>;
2857
2858 //*********************************************
2859 // is_move_constructible
2860 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
2861 struct is_move_constructible;
2862
2863 template <typename T>
2864 struct is_move_constructible<T, true> : public etl::true_type
2865 {
2866 };
2867
2868 template <typename T>
2869 struct is_move_constructible<T, false>;
2870
2871 //*********************************************
2872 // is_copy_assignable
2873 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
2874 struct is_copy_assignable;
2875
2876 template <typename T>
2877 struct is_copy_assignable<T, true> : public etl::true_type
2878 {
2879 };
2880
2881 template <typename T>
2882 struct is_copy_assignable<T, false>;
2883
2884 //*********************************************
2885 // is_move_assignable
2886 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
2887 struct is_move_assignable;
2888
2889 template <typename T>
2890 struct is_move_assignable<T, true> : public etl::true_type
2891 {
2892 };
2893
2894 template <typename T>
2895 struct is_move_assignable<T, false>;
2896
2897 //*********************************************
2898 // is_trivially_constructible
2899 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
2900 struct is_trivially_constructible;
2901
2902 template <typename T>
2903 struct is_trivially_constructible<T, true> : public etl::true_type
2904 {
2905 };
2906
2907 template <typename T>
2908 struct is_trivially_constructible<T, false>;
2909
2910 //*********************************************
2911 // is_trivially_copy_constructible
2912 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
2913 struct is_trivially_copy_constructible;
2914
2915 template <typename T>
2916 struct is_trivially_copy_constructible<T, true> : public etl::true_type
2917 {
2918 };
2919
2920 template <typename T>
2921 struct is_trivially_copy_constructible<T, false>;
2922
2923 //*********************************************
2924 // is_trivially_destructible
2925 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
2926 struct is_trivially_destructible;
2927
2928 template <typename T>
2929 struct is_trivially_destructible<T, true> : public etl::true_type
2930 {
2931 };
2932
2933 template <typename T>
2934 struct is_trivially_destructible<T, false>;
2935
2936 //*********************************************
2937 // is_trivially_copy_assignable
2938 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
2939 struct is_trivially_copy_assignable;
2940
2941 template <typename T>
2942 struct is_trivially_copy_assignable<T, true> : public etl::true_type
2943 {
2944 };
2945
2946 template <typename T>
2947 struct is_trivially_copy_assignable<T, false>;
2948
2949 //*********************************************
2950 // is_trivially_copyable
2951 template <typename T, bool BValue = etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
2952 struct is_trivially_copyable;
2953
2954 template <typename T>
2955 struct is_trivially_copyable<T, true> : public etl::true_type
2956 {
2957 };
2958
2959 template <typename T>
2960 struct is_trivially_copyable<T, false>;
2961
2962#else
2963
2964 //*********************************************
2965 // Assume that anything other than arithmetics
2966 // and pointers return false for the traits.
2967 //*********************************************
2968
2969 //*********************************************
2970 // is_assignable
2971 template <typename T1, typename T2>
2972 #if ETL_USING_BUILTIN_IS_ASSIGNABLE
2973 struct is_assignable : public etl::bool_constant<__is_assignable(T1, T2)>
2974 #else
2975 struct is_assignable
2976 : public etl::bool_constant< (etl::is_arithmetic<T1>::value || etl::is_pointer<T1>::value)
2977 && (etl::is_arithmetic<T2>::value || etl::is_pointer<T2>::value)>
2978 #endif
2979 {
2980 };
2981
2982 #if ETL_USING_CPP11
2983 //***************************************************************************
2985 namespace private_type_traits
2986 {
2987 template <class, class T, class... TArgs>
2988 struct is_constructible_ : etl::false_type
2989 {
2990 };
2991
2992 template <class T, class... TArgs>
2993 struct is_constructible_<void_t<decltype(T(etl::declval<TArgs>()...))>, T, TArgs...> : etl::true_type
2994 {
2995 };
2996 } // namespace private_type_traits
2997
2998 //*********************************************
2999 // is_constructible
3000 template <class T, class... TArgs>
3001 using is_constructible = private_type_traits::is_constructible_<void_t<>, T, TArgs...>;
3002
3003 //*********************************************
3004 // is_copy_constructible
3005 template <class T>
3006 struct is_copy_constructible : public is_constructible< T, typename etl::add_lvalue_reference< typename etl::add_const<T>::type>::type>
3007 {
3008 };
3009 template <>
3010 struct is_copy_constructible<void> : public false_type
3011 {
3012 };
3013 template <>
3014 struct is_copy_constructible<void const> : public false_type
3015 {
3016 };
3017 template <>
3018 struct is_copy_constructible<void volatile> : public false_type
3019 {
3020 };
3021 template <>
3022 struct is_copy_constructible<void const volatile> : public false_type
3023 {
3024 };
3025
3026 //*********************************************
3027 // is_move_constructible
3028 template <typename T>
3029 struct is_move_constructible : public is_constructible<T, typename etl::add_rvalue_reference<T>::type>
3030 {
3031 };
3032 template <>
3033 struct is_move_constructible<void> : public false_type
3034 {
3035 };
3036 template <>
3037 struct is_move_constructible<void const> : public false_type
3038 {
3039 };
3040 template <>
3041 struct is_move_constructible<void volatile> : public false_type
3042 {
3043 };
3044 template <>
3045 struct is_move_constructible<void const volatile> : public false_type
3046 {
3047 };
3048
3049 #else
3050
3051 //*********************************************
3052 // is_copy_constructible
3053 template <typename T>
3054 struct is_copy_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3055 {
3056 };
3057
3058 //*********************************************
3059 // is_move_constructible
3060 template <typename T>
3061 struct is_move_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3062 {
3063 };
3064 #endif
3065
3066 //*********************************************
3067 // is_copy_assignable
3068 template <typename T>
3069 struct is_copy_assignable
3070 : public etl::is_assignable< typename etl::add_lvalue_reference<T>::type, typename etl::add_lvalue_reference<const T>::type>
3071 {
3072 };
3073
3074 #if ETL_USING_CPP11
3075 //*********************************************
3076 // is_move_assignable
3077 template <typename T>
3078 struct is_move_assignable : public etl::is_assignable<typename etl::add_lvalue_reference<T>::type, typename etl::add_rvalue_reference<T>::type>
3079 {
3080 };
3081 #else
3082 //*********************************************
3083 // is_move_assignable
3084 template <typename T>
3085 struct is_move_assignable : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3086 {
3087 };
3088 #endif
3089
3090 //*********************************************
3091 // is_trivially_constructible
3092 template <typename T>
3093 struct is_trivially_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3094 {
3095 };
3096
3097 //*********************************************
3098 // is_trivially_copy_constructible
3099 template <typename T>
3100 struct is_trivially_copy_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3101 {
3102 };
3103
3104 //*********************************************
3105 // is_trivially_destructible
3106 template <typename T>
3107 struct is_trivially_destructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3108 {
3109 };
3110
3111 //*********************************************
3112 // is_trivially_copy_assignable
3113 template <typename T>
3114 struct is_trivially_copy_assignable : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3115 {
3116 };
3117
3118 //*********************************************
3119 // is_trivially_copyable
3120 template <typename T>
3121 #if ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE
3122 struct is_trivially_copyable : public etl::bool_constant<__is_trivially_copyable(T)>
3123 #else
3124 struct is_trivially_copyable : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3125 #endif
3126 {
3127 };
3128
3129#endif
3130
3131 template <typename T1, typename T2>
3132 struct is_lvalue_assignable
3133 : public etl::is_assignable< typename etl::add_lvalue_reference<T1>::type,
3134 typename etl::add_lvalue_reference< typename etl::add_const<T2>::type>::type>
3135 {
3136 };
3137
3138#if ETL_USING_CPP11
3139 //*********************************************
3140 // is_default_constructible
3141 template <typename T, typename = void>
3142 struct is_default_constructible : etl::false_type
3143 {
3144 };
3145
3146 template <typename T>
3147 struct is_default_constructible<T, etl::void_t<decltype(T())>> : etl::true_type
3148 {
3149 };
3150#else
3151 template <typename T>
3152 struct is_default_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
3153 {
3154 };
3155#endif
3156
3157#if ETL_USING_CPP17
3158
3159 template <typename T1, typename T2>
3160 inline constexpr bool is_assignable_v = etl::is_assignable<T1, T2>::value;
3161
3162 template <typename T1, typename T2>
3163 inline constexpr bool is_lvalue_assignable_v = etl::is_lvalue_assignable<T1, T2>::value;
3164
3165 template <typename T, typename... TArgs>
3166 inline constexpr bool is_constructible_v = etl::is_constructible<T, TArgs...>::value;
3167
3168 template <typename T, typename... TArgs>
3169 inline constexpr bool is_default_constructible_v = etl::is_default_constructible<T, TArgs...>::value;
3170
3171 template <typename T>
3172 inline constexpr bool is_copy_constructible_v = etl::is_copy_constructible<T>::value;
3173
3174 template <typename T>
3175 inline constexpr bool is_move_constructible_v = etl::is_move_constructible<T>::value;
3176
3177 template <typename T>
3178 inline constexpr bool is_copy_assignable_v = etl::is_copy_assignable<T>::value;
3179
3180 template <typename T>
3181 inline constexpr bool is_move_assignable_v = etl::is_move_assignable<T>::value;
3182
3183 template <typename T>
3184 inline constexpr bool is_trivially_constructible_v = etl::is_trivially_constructible<T>::value;
3185
3186 template <typename T>
3187 inline constexpr bool is_trivially_copy_constructible_v = etl::is_trivially_copy_constructible<T>::value;
3188
3189 template <typename T>
3190 inline constexpr bool is_trivially_destructible_v = etl::is_trivially_destructible<T>::value;
3191
3192 template <typename T>
3193 inline constexpr bool is_trivially_copy_assignable_v = etl::is_trivially_copy_assignable<T>::value;
3194
3195 template <typename T>
3196 inline constexpr bool is_trivially_copyable_v = etl::is_trivially_copyable<T>::value;
3197
3198#endif
3199
3200#if ETL_USING_CPP11
3201 //*********************************************
3202 // common_type
3203 // Based on the sample implementation detailed on
3204 // https://en.cppreference.com/w/cpp/types/common_type
3205 //*********************************************
3206 //***********************************
3207 // Primary template
3208 template <typename...>
3209 struct common_type
3210 {
3211 };
3212
3213 //***********************************
3214 // One type
3215 template <typename T>
3216 struct common_type<T> : common_type<T, T>
3217 {
3218 };
3219
3220 namespace private_common_type
3221 {
3222 template <typename T1, typename T2>
3223 using conditional_result_t = decltype(false ? declval<T1>() : declval<T2>());
3224
3225 template <typename, typename, typename = void>
3226 struct decay_conditional_result
3227 {
3228 };
3229
3230 template <typename T1, typename T2>
3231 struct decay_conditional_result<T1, T2, void_t<conditional_result_t<T1, T2>>> : etl::decay<conditional_result_t<T1, T2>>
3232 {
3233 };
3234
3235 template <typename T1, typename T2, typename = void>
3236 struct common_type_2_impl : decay_conditional_result<const T1&, const T2&>
3237 {
3238 };
3239
3240 template <typename T1, typename T2>
3241 struct common_type_2_impl<T1, T2, void_t<conditional_result_t<T1, T2>>> : decay_conditional_result<T1, T2>
3242 {
3243 };
3244 } // namespace private_common_type
3245
3246 //***********************************
3247 // Two types
3248 template <typename T1, typename T2>
3249 struct common_type<T1, T2>
3250 : etl::conditional< etl::is_same<T1, typename etl::decay<T1>::type>::value && etl::is_same<T2, typename etl::decay<T2>::type>::value,
3251 private_common_type::common_type_2_impl<T1, T2>,
3252 common_type<typename etl::decay<T2>::type, typename etl::decay<T2>::type>>::type
3253 {
3254 };
3255
3256 //***********************************
3257 // Three or more types
3258 namespace private_common_type
3259 {
3260 template <typename AlwaysVoid, typename T1, typename T2, typename... TRest>
3261 struct common_type_multi_impl
3262 {
3263 };
3264
3265 template <typename T1, typename T2, typename... TRest>
3266 struct common_type_multi_impl<void_t<typename common_type<T1, T2>::type>, T1, T2, TRest...>
3267 : common_type<typename common_type<T1, T2>::type, TRest...>
3268 {
3269 };
3270 } // namespace private_common_type
3271
3272 template <typename T1, typename T2, typename... TRest>
3273 struct common_type<T1, T2, TRest...> : private_common_type::common_type_multi_impl<void, T1, T2, TRest...>
3274 {
3275 };
3276
3277 template <typename... T>
3278 using common_type_t = typename common_type<T...>::type;
3279#endif
3280
3281 //***************************************************************************
3283 //***************************************************************************
3284 template <typename T>
3285 struct unsigned_type
3286 {
3287 typedef typename etl::conditional<
3288 sizeof(T) == sizeof(unsigned char), unsigned char,
3289 typename etl::conditional< sizeof(T) == sizeof(unsigned short), unsigned short,
3290 typename etl::conditional< sizeof(T) == sizeof(unsigned int), unsigned int,
3291 typename etl::conditional<sizeof(T) == sizeof(unsigned long), unsigned long,
3292 unsigned long long>::type>::type>::type>::type type;
3293 };
3294
3295#if ETL_USING_CPP11
3296 template <typename T>
3297 using unsigned_type_t = typename unsigned_type<T>::type;
3298#endif
3299
3300 //***************************************************************************
3302 //***************************************************************************
3303 template <typename T>
3304 struct signed_type
3305 {
3306 typedef typename etl::conditional<
3307 sizeof(T) == sizeof(char), char,
3308 typename etl::conditional<
3309 sizeof(T) == sizeof(short), short,
3310 typename etl::conditional< sizeof(T) == sizeof(int), int,
3311 typename etl::conditional<sizeof(T) == sizeof(long), long, long long>::type>::type>::type>::type type;
3312 };
3313
3314#if ETL_USING_CPP11
3315 template <typename T>
3316 using signed_type_t = typename signed_type<T>::type;
3317#endif
3318
3319 //*********************************************
3320 // type_identity
3321
3322 template <typename T>
3323 struct type_identity
3324 {
3325 typedef T type;
3326 };
3327
3328#if ETL_USING_CPP11
3329 template <typename T>
3330 using type_identity_t = typename type_identity<T>::type;
3331#endif
3332
3333 //*********************************************
3334 // underlying_type
3335#if ETL_USING_BUILTIN_UNDERLYING_TYPE
3336 // Primary template for etl::underlying_type
3337 template <typename T, bool = etl::is_enum<T>::value>
3338 struct underlying_type;
3339
3340 // Specialization for non-enum types (invalid case)
3341 template <typename T>
3342 struct underlying_type<T, false>
3343 {
3344 // Static assertion to ensure this is only used with enums
3345 ETL_STATIC_ASSERT(etl::is_enum<T>::value, "etl::underlying_type can only be used with enumeration types.");
3346 };
3347
3348 template <typename T>
3349 struct underlying_type<T, true>
3350 {
3351 typedef __underlying_type(T) type;
3352 };
3353#else
3356 template <typename T>
3357 struct underlying_type
3358 {
3359 typedef int type;
3360 };
3361#endif
3362
3363#if ETL_USING_CPP11
3364 template <typename T>
3365 using underlying_type_t = typename underlying_type<T>::type;
3366#endif
3367
3368#if ETL_USING_CPP11
3369 //*********************************************
3370 // has_duplicates
3371 template <typename... TTypes>
3372 struct has_duplicates;
3373
3374 template <typename TFirst, typename... TRest>
3375 struct has_duplicates<TFirst, TRest...> : etl::conditional_t<etl::is_one_of<TFirst, TRest...>::value, etl::true_type, has_duplicates<TRest...>>
3376 {
3377 };
3378
3379 template <typename T>
3380 struct has_duplicates<T> : etl::false_type
3381 {
3382 };
3383
3384 template <>
3385 struct has_duplicates<> : etl::false_type
3386 {
3387 };
3388#endif
3389
3390#if ETL_USING_CPP17
3391 template <typename... TTypes>
3392 inline constexpr bool has_duplicates_v = etl::has_duplicates<TTypes...>::value;
3393#endif
3394
3395#if ETL_USING_CPP11
3396 //*********************************************
3397 // count_of
3398 template <typename T, typename... TTypes>
3399 struct count_of;
3400
3401 template <typename T, typename U, typename... URest>
3402 struct count_of<T, U, URest...> : etl::integral_constant<size_t, etl::is_same<T, U>::value + count_of<T, URest...>::value>
3403 {
3404 };
3405
3406 template <typename T>
3407 struct count_of<T> : etl::integral_constant<size_t, 0>
3408 {
3409 };
3410#endif
3411
3412#if ETL_USING_CPP17
3413 template <typename T, typename... TTypes>
3414 inline constexpr size_t count_of_v = etl::count_of<T, TTypes...>::value;
3415#endif
3416
3417#if ETL_USING_CPP11
3418 //*********************************************
3420 template <typename T, template <typename...> class Template>
3421 struct is_specialization : etl::false_type
3422 {
3423 };
3424
3425 template <template <typename...> class Template, typename... TArgs>
3426 struct is_specialization<Template<TArgs...>, Template> : etl::true_type
3427 {
3428 };
3429#endif
3430
3431#if ETL_USING_CPP17
3432 template <typename T, template <typename...> class Template>
3433 inline constexpr bool is_specialization_v = etl::is_specialization<T, Template>::value;
3434#endif
3435
3436 //*********************************************
3437 // is_constant_evaluated
3438 ETL_CONSTEXPR inline bool is_constant_evaluated() ETL_NOEXCEPT
3439 {
3440#if ETL_USING_CPP23
3441 if consteval
3442 {
3443 return true;
3444 }
3445 else
3446 {
3447 return false;
3448 }
3449#elif ETL_USING_BUILTIN_IS_CONSTANT_EVALUATED == 1
3450 // Fallback for C++20 on supported compilers
3451 return __builtin_is_constant_evaluated();
3452#else
3453 // default if unsupported
3454 return false;
3455#endif
3456 }
3457
3458#if ETL_USING_CPP11
3459 //*********************************
3461 //*********************************
3462 template <typename T>
3463 struct is_function : etl::false_type
3464 {
3465 };
3466
3467 // Plain / cv-qualified
3468 template <typename TReturn, typename... TArgs>
3469 struct is_function<TReturn(TArgs...)> : etl::true_type
3470 {
3471 };
3472
3473 template <typename TReturn, typename... TArgs>
3474 struct is_function<TReturn(TArgs...) const> : etl::true_type
3475 {
3476 };
3477
3478 template <typename TReturn, typename... TArgs>
3479 struct is_function<TReturn(TArgs...) volatile> : etl::true_type
3480 {
3481 };
3482
3483 template <typename TReturn, typename... TArgs>
3484 struct is_function<TReturn(TArgs...) const volatile> : etl::true_type
3485 {
3486 };
3487
3488 // Variadic
3489 template <typename TReturn, typename... TArgs>
3490 struct is_function<TReturn(TArgs..., ...)> : etl::true_type
3491 {
3492 };
3493
3494 template <typename TReturn, typename... TArgs>
3495 struct is_function<TReturn(TArgs..., ...) const> : etl::true_type
3496 {
3497 };
3498
3499 template <typename TReturn, typename... TArgs>
3500 struct is_function<TReturn(TArgs..., ...) volatile> : etl::true_type
3501 {
3502 };
3503
3504 template <typename TReturn, typename... TArgs>
3505 struct is_function<TReturn(TArgs..., ...) const volatile> : etl::true_type
3506 {
3507 };
3508
3509 // noexcept variants (if supported)
3510 #if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
3511 template <typename TReturn, typename... TArgs>
3512 struct is_function<TReturn(TArgs...) noexcept> : etl::true_type
3513 {
3514 };
3515
3516 template <typename TReturn, typename... TArgs>
3517 struct is_function<TReturn(TArgs...) const noexcept> : etl::true_type
3518 {
3519 };
3520
3521 template <typename TReturn, typename... TArgs>
3522 struct is_function<TReturn(TArgs...) volatile noexcept> : etl::true_type
3523 {
3524 };
3525
3526 template <typename TReturn, typename... TArgs>
3527 struct is_function<TReturn(TArgs...) const volatile noexcept> : etl::true_type
3528 {
3529 };
3530
3531 template <typename TReturn, typename... TArgs>
3532 struct is_function<TReturn(TArgs..., ...) noexcept> : etl::true_type
3533 {
3534 };
3535
3536 template <typename TReturn, typename... TArgs>
3537 struct is_function<TReturn(TArgs..., ...) const noexcept> : etl::true_type
3538 {
3539 };
3540
3541 template <typename TReturn, typename... TArgs>
3542 struct is_function<TReturn(TArgs..., ...) volatile noexcept> : etl::true_type
3543 {
3544 };
3545
3546 template <typename TReturn, typename... TArgs>
3547 struct is_function<TReturn(TArgs..., ...) const volatile noexcept> : etl::true_type
3548 {
3549 };
3550 #endif
3551
3552 #if ETL_USING_CPP17
3553 template <typename T>
3554 inline constexpr bool is_function_v = etl::is_function<T>::value;
3555 #endif
3556#endif
3557
3558#if ETL_USING_CPP11
3559 //*********************************
3561 //*********************************
3562 template <typename T, etl::enable_if_t<etl::is_class<etl::decay_t<T>>::value, int> = 0>
3563 struct has_call_operator
3564 {
3565 template <typename U>
3566 static auto test(int) -> decltype(&U::operator(), etl::true_type());
3567
3568 template <typename>
3569 static etl::false_type test(...);
3570
3571 static const bool value = etl::is_same<decltype(test<T>(0)), etl::true_type>::value;
3572 };
3573
3574 #if ETL_USING_CPP17
3575 template <typename T>
3576 inline constexpr bool has_call_operator_v = etl::has_call_operator<T>::value;
3577 #endif
3578#endif
3579
3580#if ETL_USING_CPP11
3581 //***************************************************************************
3583 //***************************************************************************
3584 template <typename T, etl::enable_if_t<etl::is_class<etl::decay_t<T>>::value, int> = 0>
3585 struct has_unique_call_operator
3586 {
3587 //*********************************
3588 // Test for presence of operator()
3589 //*********************************
3590 template <typename U>
3591 static auto test(int) -> decltype(&U::operator(), etl::true_type());
3592
3593 //*********************************
3594 // Fallback
3595 //*********************************
3596 template <typename>
3597 static auto test(...) -> etl::false_type;
3598
3599 //*********************************
3600 // <b>true</b> if operator() exists and is unique
3601 //*********************************
3602 static constexpr bool value = decltype(test<etl::decay_t<T>>(0))::value;
3603 };
3604
3605 #if ETL_USING_CPP17
3606 template <typename T>
3607 inline constexpr bool has_unique_call_operator_v = etl::has_unique_call_operator<T>::value;
3608 #endif
3609#endif
3610
3611 //***************************************************************************
3613 //***************************************************************************
3614 namespace private_type_traits
3615 {
3616 template <typename T>
3617 struct is_member_pointer_helper : etl::false_type
3618 {
3619 };
3620
3621 template <typename T, typename TObject>
3622 struct is_member_pointer_helper<T TObject::*> : etl::true_type
3623 {
3624 };
3625 } // namespace private_type_traits
3626
3627 template <typename T>
3628 struct is_member_pointer : private_type_traits::is_member_pointer_helper< typename etl::remove_cv<T>::type>
3629 {
3630 };
3631
3632#if ETL_USING_CPP17
3633 template <typename T>
3634 inline constexpr bool is_member_pointer_v = etl::is_member_pointer<T>::value;
3635#endif
3636
3637#if ETL_USING_CPP11
3638 //***************************************************************************
3640 //***************************************************************************
3641 template <typename T>
3642 struct is_member_function_pointer : etl::false_type
3643 {
3644 };
3645
3646 template <typename TReturn, typename TObject, typename... TArgs>
3647 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...)> : etl::true_type
3648 {
3649 };
3650 template <typename TReturn, typename TObject, typename... TArgs>
3651 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) const> : etl::true_type
3652 {
3653 };
3654 template <typename TReturn, typename TObject, typename... TArgs>
3655 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) volatile> : etl::true_type
3656 {
3657 };
3658 template <typename TReturn, typename TObject, typename... TArgs>
3659 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) const volatile> : etl::true_type
3660 {
3661 };
3662
3663 #if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
3664 template <typename TReturn, typename TObject, typename... TArgs>
3665 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) noexcept> : etl::true_type
3666 {
3667 };
3668 template <typename TReturn, typename TObject, typename... TArgs>
3669 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) const noexcept> : etl::true_type
3670 {
3671 };
3672 template <typename TReturn, typename TObject, typename... TArgs>
3673 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) volatile noexcept> : etl::true_type
3674 {
3675 };
3676 template <typename TReturn, typename TObject, typename... TArgs>
3677 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) const volatile noexcept> : etl::true_type
3678 {
3679 };
3680 #endif
3681
3682 template <typename TReturn, typename TObject, typename... TArgs>
3683 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...)&> : etl::true_type
3684 {
3685 };
3686 template <typename TReturn, typename TObject, typename... TArgs>
3687 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) const&> : etl::true_type
3688 {
3689 };
3690 template <typename TReturn, typename TObject, typename... TArgs>
3691 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) volatile&> : etl::true_type
3692 {
3693 };
3694 template <typename TReturn, typename TObject, typename... TArgs>
3695 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) const volatile&> : etl::true_type
3696 {
3697 };
3698
3699 template <typename TReturn, typename TObject, typename... TArgs>
3700 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) &&> : etl::true_type
3701 {
3702 };
3703 template <typename TReturn, typename TObject, typename... TArgs>
3704 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) const&&> : etl::true_type
3705 {
3706 };
3707 template <typename TReturn, typename TObject, typename... TArgs>
3708 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) volatile&&> : etl::true_type
3709 {
3710 };
3711 template <typename TReturn, typename TObject, typename... TArgs>
3712 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) const volatile&&> : etl::true_type
3713 {
3714 };
3715
3716 #if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
3717 template <typename TReturn, typename TObject, typename... TArgs>
3718 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) & noexcept> : etl::true_type
3719 {
3720 };
3721 template <typename TReturn, typename TObject, typename... TArgs>
3722 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) const & noexcept> : etl::true_type
3723 {
3724 };
3725 template <typename TReturn, typename TObject, typename... TArgs>
3726 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) volatile & noexcept> : etl::true_type
3727 {
3728 };
3729 template <typename TReturn, typename TObject, typename... TArgs>
3730 struct is_member_function_pointer< TReturn (TObject::*)(TArgs...) const volatile & noexcept> : etl::true_type
3731 {
3732 };
3733
3734 template <typename TReturn, typename TObject, typename... TArgs>
3735 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) && noexcept> : etl::true_type
3736 {
3737 };
3738 template <typename TReturn, typename TObject, typename... TArgs>
3739 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) const && noexcept> : etl::true_type
3740 {
3741 };
3742 template <typename TReturn, typename TObject, typename... TArgs>
3743 struct is_member_function_pointer<TReturn (TObject::*)(TArgs...) volatile && noexcept> : etl::true_type
3744 {
3745 };
3746 template <typename TReturn, typename TObject, typename... TArgs>
3747 struct is_member_function_pointer< TReturn (TObject::*)(TArgs...) const volatile && noexcept> : etl::true_type
3748 {
3749 };
3750 #endif
3751
3752 template <typename TReturn, typename TObject, typename... TArgs>
3753 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...)> : etl::true_type
3754 {
3755 };
3756 template <typename TReturn, typename TObject, typename... TArgs>
3757 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) const> : etl::true_type
3758 {
3759 };
3760 template <typename TReturn, typename TObject, typename... TArgs>
3761 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) volatile> : etl::true_type
3762 {
3763 };
3764 template <typename TReturn, typename TObject, typename... TArgs>
3765 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) const volatile> : etl::true_type
3766 {
3767 };
3768
3769 #if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
3770 template <typename TReturn, typename TObject, typename... TArgs>
3771 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) noexcept> : etl::true_type
3772 {
3773 };
3774 template <typename TReturn, typename TObject, typename... TArgs>
3775 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) const noexcept> : etl::true_type
3776 {
3777 };
3778 template <typename TReturn, typename TObject, typename... TArgs>
3779 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) volatile noexcept> : etl::true_type
3780 {
3781 };
3782 template <typename TReturn, typename TObject, typename... TArgs>
3783 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) const volatile noexcept> : etl::true_type
3784 {
3785 };
3786 #endif
3787
3788 template <typename TReturn, typename TObject, typename... TArgs>
3789 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...)&> : etl::true_type
3790 {
3791 };
3792 template <typename TReturn, typename TObject, typename... TArgs>
3793 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) const&> : etl::true_type
3794 {
3795 };
3796 template <typename TReturn, typename TObject, typename... TArgs>
3797 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) volatile&> : etl::true_type
3798 {
3799 };
3800 template <typename TReturn, typename TObject, typename... TArgs>
3801 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) const volatile&> : etl::true_type
3802 {
3803 };
3804 template <typename TReturn, typename TObject, typename... TArgs>
3805 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) &&> : etl::true_type
3806 {
3807 };
3808 template <typename TReturn, typename TObject, typename... TArgs>
3809 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) const&&> : etl::true_type
3810 {
3811 };
3812 template <typename TReturn, typename TObject, typename... TArgs>
3813 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) volatile&&> : etl::true_type
3814 {
3815 };
3816 template <typename TReturn, typename TObject, typename... TArgs>
3817 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) const volatile&&> : etl::true_type
3818 {
3819 };
3820
3821 #if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
3822 template <typename TReturn, typename TObject, typename... TArgs>
3823 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) & noexcept> : etl::true_type
3824 {
3825 };
3826 template <typename TReturn, typename TObject, typename... TArgs>
3827 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) const & noexcept> : etl::true_type
3828 {
3829 };
3830 template <typename TReturn, typename TObject, typename... TArgs>
3831 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) volatile & noexcept> : etl::true_type
3832 {
3833 };
3834 template <typename TReturn, typename TObject, typename... TArgs>
3835 struct is_member_function_pointer< TReturn (TObject::*)(TArgs..., ...) const volatile & noexcept> : etl::true_type
3836 {
3837 };
3838
3839 template <typename TReturn, typename TObject, typename... TArgs>
3840 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) && noexcept> : etl::true_type
3841 {
3842 };
3843 template <typename TReturn, typename TObject, typename... TArgs>
3844 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) const && noexcept> : etl::true_type
3845 {
3846 };
3847 template <typename TReturn, typename TObject, typename... TArgs>
3848 struct is_member_function_pointer<TReturn (TObject::*)(TArgs..., ...) volatile && noexcept> : etl::true_type
3849 {
3850 };
3851 template <typename TReturn, typename TObject, typename... TArgs>
3852 struct is_member_function_pointer< TReturn (TObject::*)(TArgs..., ...) const volatile && noexcept> : etl::true_type
3853 {
3854 };
3855 #endif
3856#endif
3857
3858#if ETL_USING_CPP17
3859 template <typename T>
3860 inline constexpr bool is_member_function_pointer_v = etl::is_member_function_pointer<T>::value;
3861#endif
3862
3863#if ETL_USING_CPP11
3864 //***************************************************************************
3866 //***************************************************************************
3867 namespace private_type_traits
3868 {
3869 template <typename>
3870 struct is_member_object_pointer_helper : public etl::false_type
3871 {
3872 };
3873
3874 template <typename T, typename TObject>
3875 struct is_member_object_pointer_helper<T TObject::*> : public etl::negation<etl::is_function<T>>
3876 {
3877 };
3878 } // namespace private_type_traits
3879
3880 template <typename T>
3881 struct is_member_object_pointer : public private_type_traits::is_member_object_pointer_helper< etl::remove_cv_t<T>>::type
3882 {
3883 };
3884#endif
3885
3886#if ETL_USING_CPP17
3887 template <typename T>
3888 inline constexpr bool is_member_object_pointer_v = etl::is_member_object_pointer<T>::value;
3889#endif
3890
3891#if ETL_USING_CPP20
3892 template <class... TArgs>
3893 struct common_reference;
3894
3895 template <class... TArgs>
3896 using common_reference_t = typename etl::common_reference<TArgs...>::type;
3897
3898 template <class T, class U, template <class> class TQual, template <class> class UQual>
3899 struct basic_common_reference
3900 {
3901 };
3902
3903 // If sizeof...(T) is 0: no member
3904 template <>
3905 struct common_reference<>
3906 {
3907 };
3908
3909 // If sizeof...(T) is 1
3910 template <class T>
3911 struct common_reference<T>
3912 {
3913 using type = T;
3914 };
3915
3916 namespace private_type_traits
3917 {
3918 template <class T1, class T2>
3919 using cond_res = decltype(false ? etl::declval<T1 (&)()>()() : etl::declval<T2 (&)()>()());
3920
3921 template <class From>
3922 struct copy_cv
3923 {
3924 template <class To>
3925 using apply = To;
3926 };
3927
3928 template <class From>
3929 struct copy_cv<const From>
3930 {
3931 template <class To>
3932 using apply = const To;
3933 };
3934
3935 template <class From>
3936 struct copy_cv<volatile From>
3937 {
3938 template <class To>
3939 using apply = volatile To;
3940 };
3941
3942 template <class From>
3943 struct copy_cv<const volatile From>
3944 {
3945 template <class To>
3946 using apply = const volatile To;
3947 };
3948
3949 template <class From, class To>
3950 using copy_cv_t = typename copy_cv<From>::template apply<To>;
3951
3952 template <class From>
3953 struct copy_cvref
3954 {
3955 template <class To>
3956 using apply = copy_cv_t<From, To>;
3957 };
3958
3959 template <class From>
3960 struct copy_cvref<From&>
3961 {
3962 template <class To>
3963 using apply = add_lvalue_reference_t<copy_cv_t<From, To>>;
3964 };
3965
3966 template <class From>
3967 struct copy_cvref<From&&>
3968 {
3969 template <class To>
3970 using apply = add_lvalue_reference_t<copy_cv_t<From, To>>;
3971 };
3972
3973 template <class From, class To>
3974 using copy_cvref_t = typename copy_cvref<From>::template apply<To>;
3975
3976 template <class T1>
3977 struct xref
3978 {
3979 template <class T2>
3980 using apply = copy_cvref_t<T1, T2>;
3981 };
3982
3983 template <class T1, class T2, class T1_RR = remove_reference_t<T1>, class T2_RR = remove_reference_t<T2>>
3984 struct common_ref;
3985
3986 template <class T1, class T2>
3987 using common_ref_t = typename common_ref<T1, T2>::type;
3988
3989 template <class T1, class T2>
3990 using cv_cond_res = cond_res<copy_cv_t<T1, T2>&, copy_cv_t<T2, T1>&>;
3991
3992 template <class T1, class T2, class T1_RR, class T2_RR>
3993 requires requires { typename cv_cond_res<T1_RR, T2_RR>; } && is_reference_v<cv_cond_res<T1_RR, T2_RR>>
3994 struct common_ref<T1&, T2&, T1_RR, T2_RR>
3995 {
3996 using type = cv_cond_res<T1_RR, T2_RR>;
3997 };
3998
3999 template <class T1, class T2>
4000 using common_ref_rr = remove_reference_t<common_ref_t<T1&, T2&>>&&;
4001
4002 template <class T1, class T2, class T1_R, class T2_R>
4003 requires requires { typename common_ref_rr<T1_R, T2_R>; }
4004 && is_convertible_v<T1&&, common_ref_rr<T1_R, T2_R>> && is_convertible_v<T2&&, common_ref_rr<T1_R, T2_R>>
4005 struct common_ref<T1&&, T2&&, T1_R, T2_R>
4006 {
4007 using type = common_ref_rr<T1_R, T2_R>;
4008 };
4009
4010 template <class T1, class T2>
4011 using common_ref_cr = common_ref_t<const T1&, T2&>;
4012
4013 template <class T1, class T2, class T3, class T4>
4014 requires requires { typename common_ref_cr<T3, T4>; } && is_convertible_v<T1&&, common_ref_cr<T3, T4>>
4015 struct common_ref<T1&&, T2&, T3, T4>
4016 {
4017 using type = common_ref_cr<T3, T4>;
4018 };
4019
4020 template <class T1, class T2, class T3, class T4>
4021 struct common_ref<T1&, T2&&, T3, T4> : common_ref<T2&&, T1&>
4022 {
4023 };
4024
4025 template <class T1, class T2, class T3, class T4>
4026 struct common_ref
4027 {
4028 };
4029
4030 template <class T1, class T2>
4031 struct common_reference_impl3;
4032
4033 template <class T1, class T2>
4034 struct common_reference_impl2 : common_reference_impl3<T1, T2>
4035 {
4036 };
4037
4038 template <class T1, class T2>
4039 struct common_reference_impl1 : common_reference_impl2<T1, T2>
4040 {
4041 };
4042 } // namespace private_type_traits
4043
4044 // If sizeof...(T) is 2
4045 template <class T1, class T2>
4046 struct common_reference<T1, T2> : private_type_traits::common_reference_impl1<T1, T2>
4047 {
4048 };
4049
4050 namespace private_type_traits
4051 {
4052 template <class T1, class T2>
4053 requires is_reference_v<T1> && is_reference_v<T2> && requires { typename common_ref_t<T1, T2>; }
4054 && is_convertible_v<add_pointer_t<T1>, add_pointer_t<common_ref_t<T1, T2>>>
4055 && is_convertible_v<add_pointer_t<T2>, add_pointer_t<common_ref_t<T1, T2>>>
4056 struct common_reference_impl1<T1, T2>
4057 {
4058 using type = common_ref_t<T1, T2>;
4059 };
4060
4061 template <class T1, class T2>
4062 using basic_common_reference_t =
4063 typename basic_common_reference<remove_cvref_t<T1>, remove_cvref_t<T2>, xref<T1>::template apply, xref<T2>::template apply>::type;
4064
4065 template <class T1, class T2>
4066 requires requires { typename basic_common_reference_t<T1, T2>; }
4067 struct common_reference_impl2<T1, T2>
4068 {
4069 using type = basic_common_reference_t<T1, T2>;
4070 };
4071
4072 template <class T1, class T2>
4073 requires requires { typename cond_res<T1, T2>; }
4074 struct common_reference_impl3<T1, T2>
4075 {
4076 using type = cond_res<T1, T2>;
4077 };
4078
4079 template <class T1, class T2>
4080 struct common_reference_impl3 : common_type<T1, T2>
4081 {
4082 };
4083 } // namespace private_type_traits
4084
4085 template <class T1, class T2, class T3, class... TArgs>
4086 requires requires { typename common_reference_t<T1, T2>; }
4087 struct common_reference<T1, T2, T3, TArgs...> : common_reference<common_reference_t<T1, T2>, T3, TArgs...>
4088 {
4089 };
4090
4091 template <class... TArgs>
4092 struct common_reference
4093 {
4094 };
4095
4096#endif
4097
4098#if ETL_USING_CPP11
4099 template <typename, typename = void>
4100 struct has_size : etl::false_type
4101 {
4102 };
4103
4104 template <typename T>
4105 struct has_size<T, void_t<decltype(etl::declval<T>().size())> > : etl::true_type
4106 {
4107 };
4108#else
4109 template <typename T>
4110 struct has_size
4111 {
4112 private:
4113
4114 typedef char yes;
4115 struct no
4116 {
4117 char dummy[2];
4118 };
4119
4120 template <typename U>
4121 static yes test_size(char (*)[sizeof(&U::size)]);
4122
4123 template <typename U>
4124 static no test_size(...);
4125
4126 public:
4127
4128 static const bool value = (sizeof(test_size<T>(0)) == sizeof(yes));
4129 };
4130#endif
4131
4132#if ETL_USING_CPP11
4133 template <typename, typename = void>
4134 struct has_data : etl::false_type
4135 {
4136 };
4137
4138 template <typename T>
4139 struct has_data<T, void_t<decltype(etl::declval<T>().data())> > : etl::true_type
4140 {
4141 };
4142#else
4143 template <typename T>
4144 struct has_data
4145 {
4146 private:
4147
4148 typedef char yes;
4149 struct no
4150 {
4151 char dummy[2];
4152 };
4153
4154 template <typename U>
4155 static yes test_data(char (*)[sizeof(&U::data)]);
4156
4157 template <typename U>
4158 static no test_data(...);
4159
4160 public:
4161
4162 static const bool value = (sizeof(test_data<T>(0)) == sizeof(yes));
4163 };
4164#endif
4165} // namespace etl
4166
4167// Helper macros
4168#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)
4169#define ETL_IS_NOT_CHAR_TYPE(type) (!ETL_IS_CHAR_TYPE(type))
4170
4171#define ETL_IS_POINTER_TYPE(type) (etl::is_pointer<type>::value)
4172#define ETL_IS_NOT_POINTER_TYPE(type) (!ETL_IS_POINTER_TYPE(type))
4173
4174#define ETL_TARGET_IS_TRIVIALLY_COPYABLE(type) (etl::is_trivially_copyable< typename etl::iterator_traits<type>::value_type>::value)
4175#define ETL_TARGET_IS_NOT_TRIVIALLY_COPYABLE(type) (!ETL_TARGET_IS_TRIVIALLY_COPYABLE(type))
4176
4177#endif // ETL_TYPE_TRAITS_INCLUDED
bitset_ext
Definition absolute.h:40
ETL_CONSTEXPR TContainer::pointer data(TContainer &container)
Definition iterator.h:1228
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:1192
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