Embedded Template Library 1.0
Loading...
Searching...
No Matches
type_traits_generator.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/*[[[cog
32import cog
33cog.outl("#if 0")
34]]]*/
35/*[[[end]]]*/
36#error THIS HEADER IS A GENERATOR. DO NOT INCLUDE.
37/*[[[cog
38import cog
39cog.outl("#endif")
40]]]*/
41/*[[[end]]]*/
42
43/*[[[cog
44import cog
45cog.outl("//***************************************************************************")
46cog.outl("// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE.")
47cog.outl("//***************************************************************************")
48]]]*/
49/*[[[end]]]*/
50
51//***************************************************************************
52// To generate to header file, run this at the command line.
53// Note: You will need Python and COG installed.
54//
55// cog -d -e -otypes.h -DHandlers=<n> types_generator.h
56// Where <n> is the number of types to support.
57//
58// e.g.
59// To generate handlers for up to 16 types...
60// cog -d -e -otype_traits.h -DIsOneOf=16 type_traits_generator.h
61//
62// See generate.bat
63//***************************************************************************
64
65#ifndef ETL_TYPE_TRAITS_INCLUDED
66#define ETL_TYPE_TRAITS_INCLUDED
67
68#include "platform.h"
69#include "nullptr.h"
70#include "static_assert.h"
71
72#include <stddef.h>
73#include <stdint.h>
74
79
80#if ETL_USING_STL && ETL_USING_CPP11
81 #include <type_traits>
82#endif
83
84namespace etl
85{
86#if ETL_USING_CPP11
87 template <typename...>
88 using void_t = void;
89#endif
90
91#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED
92
93 //*****************************************************************************
94 // Traits are defined by the ETL
95 //*****************************************************************************
96
97 //***************************************************************************
99 template <typename T, T VALUE>
100 struct integral_constant
101 {
102 static const T value = VALUE;
103
104 typedef T value_type;
105 typedef integral_constant<T, VALUE> type;
106
107 operator value_type() const
108 {
109 return value;
110 }
111 };
112
115 typedef integral_constant<bool, true> true_type;
116
117 template <typename T, T VALUE>
118 const T integral_constant<T, VALUE>::value;
119
120#if ETL_USING_CPP17
121 template <typename T, T VALUE>
123#endif
124
125#if ETL_USING_CPP11
126 template <bool B>
127 using bool_constant = integral_constant<bool, B>;
128#else
129 template <bool B>
130 struct bool_constant : etl::integral_constant<bool, B> { };
131#endif
132
133#if ETL_USING_CPP17
134 template <bool B>
135 inline constexpr bool bool_constant_v = bool_constant<B>::value;
136#endif
137
138 //***************************************************************************
140 template <typename T>
141 struct negation : etl::bool_constant<!bool(T::value)>
142 {
143 };
144
145#if ETL_USING_CPP17
146 template <typename T>
147 inline constexpr bool negation_v = negation<T>::value;
148#endif
149
150 //***************************************************************************
152 template <typename T> struct remove_reference { typedef T type; };
153 template <typename T> struct remove_reference<T&> { typedef T type; };
154#if ETL_USING_CPP11
155 template <typename T> struct remove_reference<T&&> { typedef T type; };
156#endif
157
158#if ETL_USING_CPP11
159 template <typename T>
160 using remove_reference_t = typename remove_reference<T>::type;
161#endif
162
163 //***************************************************************************
165 template <typename T> struct remove_pointer { typedef T type; };
166 template <typename T> struct remove_pointer<T*> { typedef T type; };
167 template <typename T> struct remove_pointer<const T*> { typedef const T type; };
168 template <typename T> struct remove_pointer<volatile T*> { typedef volatile T type; };
169 template <typename T> struct remove_pointer<const volatile T*> { typedef const volatile T type; };
170 template <typename T> struct remove_pointer<T* const> { typedef T type; };
171 template <typename T> struct remove_pointer<const T* const> { typedef const T type; };
172 template <typename T> struct remove_pointer<volatile T* const> { typedef volatile T type; };
173 template <typename T> struct remove_pointer<const volatile T* const> { typedef const volatile T type; };
174
175#if ETL_USING_CPP11
176 template <typename T>
177 using remove_pointer_t = typename remove_pointer<T>::type;
178#endif
179
180 //***************************************************************************
182 template <typename T> struct add_pointer { typedef typename remove_reference<T>::type* type; };
183
184#if ETL_USING_CPP11
185 template <typename T>
186 using add_pointer_t = typename add_pointer<T>::type;
187#endif
188
189 //***************************************************************************
191 template <typename T> struct is_const : false_type {};
192 template <typename T> struct is_const<const T> : true_type {};
193 template <typename T> struct is_const<const volatile T> : true_type {};
194
195#if ETL_USING_CPP17
196 template <typename T>
197 inline constexpr bool is_const_v = is_const<T>::value;
198#endif
199
200 //***************************************************************************
202 template <typename T> struct remove_const { typedef T type; };
203 template <typename T> struct remove_const<const T> { typedef T type; };
204
205#if ETL_USING_CPP11
206 template <typename T>
207 using remove_const_t = typename remove_const<T>::type;
208#endif
209
210 //***************************************************************************
212 template <typename T> struct add_const { typedef const T type; };
213 template <typename T> struct add_const<const T> { typedef const T type; };
214
215#if ETL_USING_CPP11
216 template <typename T>
217 using add_const_t = typename add_const<T>::type;
218#endif
219
220 //***************************************************************************
222 template <typename T> struct is_volatile : false_type {};
223 template <typename T> struct is_volatile<volatile T> : true_type {};
224 template <typename T> struct is_volatile<const volatile T> : true_type {};
225
226#if ETL_USING_CPP17
227 template <typename T>
228 inline constexpr bool is_volatile_v = is_volatile<T>::value;
229#endif
230
231 //***************************************************************************
233 template <typename T> struct remove_volatile { typedef T type; };
234 template <typename T> struct remove_volatile<volatile T> { typedef T type; };
235
236#if ETL_USING_CPP11
237 template <typename T>
238 using remove_volatile_t = typename remove_volatile<T>::type;
239#endif
240
241 //***************************************************************************
243 template <typename T> struct add_volatile { typedef volatile T type; };
244 template <typename T> struct add_volatile<volatile T> { typedef volatile T type; };
245
246#if ETL_USING_CPP11
247 template <typename T>
248 using add_volatile_t = typename add_volatile<T>::type;
249#endif
250
251 //***************************************************************************
253 template <typename T> struct remove_cv
254 {
255 typedef typename remove_volatile<typename remove_const<T>::type>::type type;
256 };
257
258#if ETL_USING_CPP11
259 template <typename T>
260 using remove_cv_t = typename remove_cv<T>::type;
261#endif
262
263 //***************************************************************************
265 template <typename T> struct add_cv
266 {
267 typedef typename add_volatile<typename add_const<T>::type>::type type;
268 };
269
270#if ETL_USING_CPP11
271 template <typename T>
272 using add_cv_t = typename add_cv<T>::type;
273#endif
274
275 //***************************************************************************
277 template <typename T> struct remove_cvref
278 {
279 typedef typename remove_cv<typename remove_reference<T>::type>::type type;
280 };
281
282#if ETL_USING_CPP11
283 template <typename T>
284 using remove_cvref_t = typename remove_cvref<T>::type;
285#endif
286
287 //***************************************************************************
289 template <typename T> struct is_integral : false_type {};
290 template <> struct is_integral<bool> : true_type {};
291 template <> struct is_integral<char> : true_type {};
292 template <> struct is_integral<unsigned char> : true_type {};
293 template <> struct is_integral<signed char> : true_type {};
294 template <> struct is_integral<wchar_t> : true_type {};
295 template <> struct is_integral<short> : true_type {};
296 template <> struct is_integral<unsigned short> : true_type {};
297 template <> struct is_integral<int> : true_type {};
298 template <> struct is_integral<unsigned int> : true_type {};
299 template <> struct is_integral<long> : true_type {};
300 template <> struct is_integral<unsigned long> : true_type {};
301 template <> struct is_integral<long long> : true_type {};
302 template <> struct is_integral<unsigned long long> : true_type {};
303#if ETL_HAS_NATIVE_CHAR8_T
304 template <> struct is_integral<char8_t> : true_type {};
305#endif
306#if ETL_HAS_NATIVE_CHAR16_T
307 template <> struct is_integral<char16_t> : true_type {};
308#endif
309#if ETL_HAS_NATIVE_CHAR32_T
310 template <> struct is_integral<char32_t> : true_type {};
311#endif
312 template <typename T> struct is_integral<const T> : is_integral<T> {};
313 template <typename T> struct is_integral<volatile T> : is_integral<T> {};
314 template <typename T> struct is_integral<const volatile T> : is_integral<T> {};
315
316#if ETL_USING_CPP17
317 template <typename T>
318 inline constexpr bool is_integral_v = is_integral<T>::value;
319#endif
320
321 //***************************************************************************
323 template <typename T> struct is_signed : false_type {};
324 template <> struct is_signed<char> : etl::bool_constant<(char(255) < 0)> {};
325 template <> struct is_signed<wchar_t> : public etl::bool_constant<wchar_t(-1) < wchar_t(0)> {};
326 template <> struct is_signed<signed char> : true_type {};
327 template <> struct is_signed<short> : true_type {};
328 template <> struct is_signed<int> : true_type {};
329 template <> struct is_signed<long> : true_type {};
330 template <> struct is_signed<long long> : true_type {};
331 template <> struct is_signed<float> : true_type {};
332 template <> struct is_signed<double> : true_type {};
333 template <> struct is_signed<long double> : true_type {};
334#if ETL_HAS_NATIVE_CHAR8_T
335 template <> struct is_signed<char8_t> : true_type {};
336#endif
337#if ETL_HAS_NATIVE_CHAR16_T
338 template <> struct is_signed<char16_t> : true_type {};
339#endif
340#if ETL_HAS_NATIVE_CHAR32_T
341 template <> struct is_signed<char32_t> : true_type {};
342#endif
343 template <typename T> struct is_signed<const T> : is_signed<T> {};
344 template <typename T> struct is_signed<volatile T> : is_signed<T> {};
345 template <typename T> struct is_signed<const volatile T> : is_signed<T> {};
346
347#if ETL_USING_CPP17
348 template <typename T>
349 inline constexpr bool is_signed_v = is_signed<T>::value;
350#endif
351
352 //***************************************************************************
354 template <typename T> struct is_unsigned : false_type {};
355 template <> struct is_unsigned<bool> : true_type {};
356 template <> struct is_unsigned<char> : etl::bool_constant<(char(255) > 0)> {};
357 template <> struct is_unsigned<unsigned char> : true_type {};
358 template <> struct is_unsigned<wchar_t> : public etl::bool_constant<(wchar_t(-1) > wchar_t(0))> {};
359 template <> struct is_unsigned<unsigned short> : true_type {};
360 template <> struct is_unsigned<unsigned int> : true_type {};
361 template <> struct is_unsigned<unsigned long> : true_type {};
362 template <> struct is_unsigned<unsigned long long> : true_type {};
363 template <typename T> struct is_unsigned<const T> : is_unsigned<T> {};
364 template <typename T> struct is_unsigned<volatile T> : is_unsigned<T> {};
365 template <typename T> struct is_unsigned<const volatile T> : is_unsigned<T> {};
366
367#if ETL_USING_CPP17
368 template <typename T>
369 inline constexpr bool is_unsigned_v = is_unsigned<T>::value;
370#endif
371
372 //***************************************************************************
374 template <typename T> struct is_floating_point : false_type {};
375 template <> struct is_floating_point<float> : true_type {};
376 template <> struct is_floating_point<double> : true_type {};
377 template <> struct is_floating_point<long double> : true_type {};
378 template <typename T> struct is_floating_point<const T> : is_floating_point<T> {};
379 template <typename T> struct is_floating_point<volatile T> : is_floating_point<T> {};
380 template <typename T> struct is_floating_point<const volatile T> : is_floating_point<T> {};
381
382#if ETL_USING_CPP17
383 template <typename T>
384 inline constexpr bool is_floating_point_v = is_floating_point<T>::value;
385#endif
386
387 //***************************************************************************
389 template <typename T1, typename T2> struct is_same : public false_type {};
390 template <typename T> struct is_same<T, T> : public true_type {};
391
392#if ETL_USING_CPP17
393 template <typename T1, typename T2>
394 inline constexpr bool is_same_v = is_same<T1, T2>::value;
395#endif
396
397 //***************************************************************************
399 template<typename T> struct is_void : false_type {};
400 template<> struct is_void<void> : true_type {};
401
402#if ETL_USING_CPP17
403 template <typename T>
404 inline constexpr bool is_void_v = is_void<T>::value;
405#endif
406
407 //***************************************************************************
409 template<typename T> struct is_arithmetic : etl::bool_constant<is_integral<T>::value || is_floating_point<T>::value> {};
410
411#if ETL_USING_CPP17
412 template <typename T>
413 inline constexpr bool is_arithmetic_v = is_arithmetic<T>::value;
414#endif
415
416 //***************************************************************************
418 template <typename T> struct is_fundamental : etl::bool_constant<is_arithmetic<T>::value || is_void<T>::value> {};
419
420#if ETL_USING_CPP17
421 template <typename T>
422 inline constexpr bool is_fundamental_v = is_fundamental<T>::value;
423#endif
424
425 //***************************************************************************
427 template <typename T> struct is_compound : etl::bool_constant<!is_fundamental<T>::value> {};
428
429#if ETL_USING_CPP17
430 template <typename T>
431 inline constexpr bool is_compound_v = is_compound<T>::value;
432#endif
433
434 //***************************************************************************
436 template <typename T> struct is_array : false_type {};
437 template <typename T> struct is_array<T[]> : true_type {};
438 template <typename T, size_t MAXN> struct is_array<T[MAXN]> : true_type {};
439
440#if ETL_USING_CPP17
441 template <typename T>
442 inline constexpr bool is_array_v = is_array<T>::value;
443#endif
444
445 //***************************************************************************
447 template<typename T> struct is_pointer_helper : false_type {};
448 template<typename T> struct is_pointer_helper<T*> : true_type {};
449 template<typename T> struct is_pointer_helper<const T*> : is_pointer_helper<T*> {};
450 template<typename T> struct is_pointer_helper<volatile T*> : is_pointer_helper<T*> {};
451 template<typename T> struct is_pointer_helper<const volatile T*> : is_pointer_helper<T*> {};
452 template<typename T> struct is_pointer : is_pointer_helper<typename remove_cv<T>::type> {};
453
454#if ETL_USING_CPP17
455 template <typename T>
456 inline constexpr bool is_pointer_v = is_pointer<T>::value;
457#endif
458
459 //***************************************************************************
461 template<typename T> struct is_lvalue_reference_helper : false_type {};
462 template<typename T> struct is_lvalue_reference_helper<T&> : true_type {};
463 template<typename T> struct is_lvalue_reference : is_lvalue_reference_helper<typename remove_cv<T>::type> {};
464
465#if ETL_USING_CPP17
466 template <typename T>
468#endif
469
470#if ETL_USING_CPP11
471 //***************************************************************************
473 template<typename T> struct is_rvalue_reference_helper : false_type {};
474 template<typename T> struct is_rvalue_reference_helper<T&&> : true_type {};
475 template<typename T> struct is_rvalue_reference : is_rvalue_reference_helper<typename remove_cv<T>::type> {};
476
477#if ETL_USING_CPP17
478 template <typename T>
479 inline constexpr bool is_rvalue_reference_v = etl::is_rvalue_reference<T>::value;
480#endif
481#endif
482
483 //***************************************************************************
485 // Either lvalue or rvalue (for CPP11)
486 template<typename T> struct is_reference : integral_constant<bool,
487 is_lvalue_reference<T>::value
488 #if ETL_USING_CPP11
489 || is_rvalue_reference<T>::value
490 #endif
491 >{};
492
493#if ETL_USING_CPP17
494 template <typename T>
495 inline constexpr bool is_reference_v = is_reference<T>::value;
496#endif
497
498 //***************************************************************************
501 template <typename T> struct is_pod : etl::bool_constant<etl::is_fundamental<T>::value || etl::is_pointer<T>::value> {};
502
503#if ETL_USING_CPP17
504 template <typename T>
505 inline constexpr bool is_pod_v = etl::is_pod<T>::value;
506#endif
507
508 //***************************************************************************
510 template <bool B, typename T, typename F> struct conditional { typedef T type; };
511 template <typename T, typename F> struct conditional<false, T, F> { typedef F type; };
512
513#if ETL_USING_CPP11
514 template <bool B, typename T, typename F>
515 using conditional_t = typename conditional<B, T, F>::type;
516#endif
517
518 //***************************************************************************
520 template <typename T> struct make_signed { typedef T type; };
521 template <> struct make_signed<char> { typedef signed char type; };
522 template <> struct make_signed<unsigned char> { typedef signed char type; };
523
524 template <> struct make_signed<wchar_t>
525 {
526 typedef etl::conditional<sizeof(wchar_t) == sizeof(int16_t),
527 int16_t,
528 etl::conditional<sizeof(wchar_t) == sizeof(int32_t),
529 int32_t,
530 void>::type>::type type;
531 };
532
533 template <> struct make_signed<unsigned short> { typedef short type; };
534 template <> struct make_signed<unsigned int> { typedef int type; };
535 template <> struct make_signed<unsigned long> { typedef long type; };
536 template <> struct make_signed<unsigned long long> { typedef long long type; };
537 template <typename T> struct make_signed<const T> : add_const<typename make_signed<T>::type> {};
538 template <typename T> struct make_signed<volatile T> : add_volatile<typename make_signed<T>::type> {};
539 template <typename T> struct make_signed<const volatile T> : add_const<typename add_volatile<typename make_signed<T>::type>::type> {};
540
541#if ETL_USING_CPP11
542 template <typename T>
543 using make_signed_t = typename make_signed<T>::type;
544#endif
545
546 //***************************************************************************
548 template <typename T> struct make_unsigned { typedef T type; };
549 template <> struct make_unsigned<char> { typedef unsigned char type; };
550 template <> struct make_unsigned<signed char> { typedef unsigned char type; };
551 template <> struct make_unsigned<short> { typedef unsigned short type; };
552
553 template <> struct make_unsigned<wchar_t>
554 {
555 typedef etl::conditional<sizeof(wchar_t) == sizeof(uint16_t),
556 uint16_t,
557 etl::conditional<sizeof(wchar_t) == sizeof(uint32_t),
558 uint32_t,
559 void>::type>::type type;
560 };
561
562 template <> struct make_unsigned<int> { typedef unsigned int type; };
563 template <> struct make_unsigned<long> { typedef unsigned long type; };
564 template <> struct make_unsigned<long long> { typedef unsigned long long type; };
565 template <typename T> struct make_unsigned<const T> : add_const<typename make_unsigned<T>::type> {};
566 template <typename T> struct make_unsigned<volatile T> : add_volatile<typename make_unsigned<T>::type> {};
567 template <typename T> struct make_unsigned<const volatile T> : add_const<typename add_volatile<typename make_unsigned<T>::type>::type> {};
568
569#if ETL_USING_CPP11
570 template <typename T>
571 using make_unsigned_t = typename make_unsigned<T>::type;
572#endif
573
574 //***************************************************************************
576 template <bool B, typename T = void> struct enable_if {};
577 template <typename T> struct enable_if<true, T> { typedef T type; };
578
579#if ETL_USING_CPP11
580 template <bool B, typename T = void>
581 using enable_if_t = typename enable_if<B, T>::type;
582#endif
583
584 //***************************************************************************
586 template <typename T, unsigned MAXN = 0U>
587 struct extent : integral_constant<size_t, 0U> {};
588
589 template <typename T>
590 struct extent<T[], 0> : integral_constant<size_t, 0U> {};
591
592 template <typename T, unsigned MAXN>
593 struct extent<T[], MAXN> : integral_constant<size_t, extent<T, MAXN - 1>::value> {};
594
595 template <typename T, unsigned MAXN>
596 struct extent<T[MAXN], 0> : integral_constant<size_t, MAXN> {};
597
598 template <typename T, unsigned I, unsigned MAXN>
599 struct extent<T[I], MAXN> : integral_constant<size_t, extent<T, MAXN - 1>::value> {};
600
601#if ETL_USING_CPP17
602 template <typename T, unsigned N = 0U>
603 inline constexpr size_t extent_v = extent<T, N>::value;
604#endif
605
606 //***************************************************************************
608 template <typename T> struct remove_extent { typedef T type; };
609 template <typename T> struct remove_extent<T[]> { typedef T type; };
610 template <typename T, size_t MAXN> struct remove_extent<T[MAXN]> { typedef T type; };
611
612#if ETL_USING_CPP11
613 template <typename T>
614 using remove_extent_t = typename remove_extent<T>::type;
615#endif
616
617 //***************************************************************************
619 template <typename T> struct remove_all_extents { typedef T type; };
620 template <typename T> struct remove_all_extents<T[]> { typedef typename remove_all_extents<T>::type type; };
621 template <typename T, size_t MAXN> struct remove_all_extents<T[MAXN]> { typedef typename remove_all_extents<T>::type type; };
622
623#if ETL_USING_CPP11
624 template <typename T>
625 using remove_all_extents_t = typename remove_all_extents<T>::type;
626#endif
627
628 //***************************************************************************
630 template <typename T>struct rank : integral_constant<size_t, 0> {};
631 template <typename T> struct rank<T[]> : public integral_constant<size_t, rank<T>::value + 1> {};
632 template <typename T, size_t MAXN> struct rank<T[MAXN]> : public integral_constant<size_t, rank<T>::value + 1> {};
633
634#if ETL_USING_CPP17
635 template <typename T>
636 inline constexpr size_t rank_v = rank<T>::value;
637#endif
638
639 //***************************************************************************
641 template <typename T>
642 struct decay
643 {
644 typedef typename etl::remove_reference<T>::type U;
647 typename etl::remove_cv<U>::type>::type type;
648 };
649
650#if ETL_USING_CPP11
651 template <typename T>
652 using decay_t = typename decay<T>::type;
653#endif
654
655 //***************************************************************************
657 template<typename TBase,
658 typename TDerived,
660 struct is_base_of
661 {
662 private:
663
664 static TBase* check(TBase*) { return (TBase*)0; }
665 static char check(...) { return 0; }
666
667 public:
668
669 static const bool value = (sizeof(check((TDerived*)0)) == sizeof(TBase*));
670 };
671
672 // For when TBase or TDerived is a fundamental type.
673 template<typename TBase, typename TDerived>
675 {
676 static const bool value = false;
677 };
678
679#if ETL_USING_CPP17
680 template <typename T1, typename T2>
681 inline constexpr bool is_base_of_v = is_base_of<T1, T2>::value;
682#endif
683
684 //***************************************************************************
686 namespace private_type_traits
687 {
688 template <typename T> char test(int T::*); // Match for classes.
689
690 struct dummy { char c[2]; };
691 template <typename T> dummy test(...); // Match for non-classes.
692 }
693
694 template <typename T>
695 struct is_class : etl::bool_constant<sizeof(private_type_traits::test<T>(0)) == 1U> {};
696
697#if ETL_USING_CPP17
698 template <typename T>
699 inline constexpr bool is_class_v = is_class<T>::value;
700#endif
701
702 //***************************************************************************
704 template <typename T> struct add_lvalue_reference { typedef T& type; };
705 template <typename T> struct add_lvalue_reference<T&> { typedef T& type; };
706 template <> struct add_lvalue_reference<void> { typedef void type; };
707 template <> struct add_lvalue_reference<const void> { typedef const void type; };
708 template <> struct add_lvalue_reference<volatile void> { typedef volatile void type; };
709 template <> struct add_lvalue_reference<const volatile void> { typedef const volatile void type; };
710
711#if ETL_USING_CPP11
712 template <typename T>
714#endif
715
716 //***************************************************************************
718#if ETL_USING_CPP11
719 template <typename T> struct add_rvalue_reference { using type = T && ; };
720 template <typename T> struct add_rvalue_reference<T&> { using type = T & ; };
721 template <> struct add_rvalue_reference<void> { using type = void; };
722 template <> struct add_rvalue_reference<const void> { using type = const void; };
723 template <> struct add_rvalue_reference<volatile void> { using type = volatile void; };
724 template <> struct add_rvalue_reference<const volatile void> { using type = const volatile void; };
725#endif
726
727#if ETL_USING_CPP11
728 template <typename T>
729 using add_rvalue_reference_t = typename etl::add_rvalue_reference<T>::type;
730#endif
731
732 //***************************************************************************
734#if ETL_USING_CPP11
735 template <typename T>
736 typename etl::add_rvalue_reference<T>::type declval() ETL_NOEXCEPT;
737#endif
738
739#if ETL_USING_CPP11
740 //***************************************************************************
744
745 namespace private_type_traits
746 {
747 // Base case
748 template <typename T, typename = int>
750 : false_type
751 {
752 };
753
754 // Selected if `static_cast<int>(declval<T>())` is a valid statement
755 // 2nd template argument of base case defaults to int to ensure that this partial specialization is always tried first
756 template <typename T>
758 : true_type
759 {
760 };
761 }
762
763 template <typename T>
764 struct is_enum
766 !is_class<T>::value &&
767 !is_arithmetic<T>::value &&
768 !is_reference<T>::value>
769 {
770 };
771
772#if ETL_USING_CPP17
773 template <typename T>
774 inline constexpr bool is_enum_v = etl::is_enum<T>::value;
775#endif
776#else
777 namespace private_type_traits
778 {
779 // Helper to detect if a type is convertible to an integer
780 template <typename T>
782 {
783 static char test(int); // Match if T is convertible to int
784 static double test(...); // Fallback for other types
785
786 static const bool value = sizeof(test(static_cast<T>(0))) == sizeof(char);
787 };
788 }
789
790 // Implementation of is_enum
791 template <typename T>
792 struct is_enum
793 {
794 static const bool value = private_type_traits::is_convertible_to_int<T>::value &&
795 !is_class<T>::value &&
796 !is_arithmetic<T>::value &&
797 !is_reference<T>::value;
798 };
799#endif
800
801 //***************************************************************************
803#if ETL_USING_CPP11
804 namespace private_type_traits
805 {
806 template <typename>
808
809 template <typename T>
810 auto returnable(int)->true_type_for<T()>;
811
812 template <typename>
813 auto returnable(...)->etl::false_type;
814
815 template <typename TFrom, typename TTo>
816 auto nonvoid_convertible(int)->true_type_for<decltype(etl::declval<void(&)(TTo)>()(etl::declval<TFrom>()))
817 >;
818 template <typename, typename>
819 auto nonvoid_convertible(...)->etl::false_type;
820 }
821
822#if defined(ETL_COMPILER_ARM5)
823 template <typename TFrom, typename TTo>
824 struct is_convertible : etl::bool_constant<__is_convertible_to(TFrom, TTo)> {};
825#else
826 template <typename TFrom, typename TTo>
827 struct is_convertible : etl::bool_constant<(decltype(private_type_traits::returnable<TTo>(0))::value &&
828 decltype(private_type_traits::nonvoid_convertible<TFrom, TTo>(0))::value) ||
829 (etl::is_void<TFrom>::value && etl::is_void<TTo>::value)> {};
830#endif
831#endif
832
833#if ETL_USING_CPP17
834 template <typename TFrom, typename TTo >
835 inline constexpr bool is_convertible_v = etl::is_convertible<TFrom, TTo>::value;
836#endif
837
838 //***************************************************************************
841#if ETL_USING_CPP11 && !defined(ETL_COMPILER_ARM5)
842 template <typename T> struct alignment_of : integral_constant<size_t, alignof(T)> { };
843#elif defined(ETL_COMPILER_MICROSOFT)
844 template <typename T> struct alignment_of : integral_constant<size_t, size_t(__alignof(T))> {};
845#elif defined(ETL_COMPILER_IAR) || defined(ETL_COMPILER_TI)
846 template <typename T> struct alignment_of : integral_constant<size_t, size_t(__ALIGNOF__(T))> {};
847#else
848 template <typename T> struct alignment_of : integral_constant<size_t, size_t(__alignof__(T))> {};
849#endif
850
853 template <> struct alignment_of<void> : integral_constant <size_t, 0> {};
854 template <> struct alignment_of<const void> : integral_constant <size_t, 0> {};
855
856#if ETL_USING_CPP17
857 template <typename T>
858 inline constexpr size_t alignment_of_v = etl::alignment_of<T>::value;
859#endif
860
861#else // Condition = ETL_USING_STL && ETL_USING_CPP11
862
863//*****************************************************************************
864// Traits are derived from the STL
865//*****************************************************************************
866
867 //***************************************************************************
870 template <typename T, T VALUE>
871 struct integral_constant : std::integral_constant<T, VALUE> {};
872
877
878#if ETL_USING_CPP17
879 template <typename T, T VALUE>
880 inline constexpr T integral_constant_v = std::integral_constant<T, VALUE>::value;
881#endif
882
883#if ETL_USING_CPP17
884 template <bool B>
885 using bool_constant = std::bool_constant<B>;
886#else
887 template <bool B>
888 struct bool_constant : std::integral_constant<bool, B> { };
889#endif
890
891#if ETL_USING_CPP17
892 template <bool B>
893 inline constexpr bool bool_constant_v = bool_constant<B>::value;
894#endif
895
896 //***************************************************************************
899#if ETL_USING_CPP17
900 template <typename T>
901 using negation = std::negation<T>;
902#else
903 template <typename T>
904 struct negation : etl::bool_constant<!bool(T::value)>
905 {
906 };
907#endif
908
909#if ETL_USING_CPP17
910 template <typename T>
911 inline constexpr bool negation_v = std::negation_v<T>;
912#endif
913
914 //***************************************************************************
917 template <typename T> struct remove_reference : std::remove_reference<T> {};
918
919#if ETL_USING_CPP11
920 template <typename T>
921 using remove_reference_t = typename std::remove_reference<T>::type;
922#endif
923
924 //***************************************************************************
927 template <typename T> struct remove_pointer : std::remove_pointer<T> {};
928
929#if ETL_USING_CPP11
930 template <typename T>
931 using remove_pointer_t = typename std::remove_pointer<T>::type;
932#endif
933
934 //***************************************************************************
937 template <typename T> struct add_pointer : std::add_pointer<T> {};
938
939#if ETL_USING_CPP11
940 template <typename T>
941 using add_pointer_t = typename std::add_pointer<T>::type;
942#endif
943
944 //***************************************************************************
947 template <typename T> struct is_const : std::is_const<T> {};
948
949#if ETL_USING_CPP17
950 template <typename T>
951 inline constexpr bool is_const_v = std::is_const_v<T>;
952#endif
953
954 //***************************************************************************
957 template <typename T> struct remove_const : std::remove_const<T> {};
958
959#if ETL_USING_CPP11
960 template <typename T>
961 using remove_const_t = typename std::remove_const<T>::type;
962#endif
963
964 //***************************************************************************
967 template <typename T> struct add_const : std::add_const<T> {};
968
969#if ETL_USING_CPP11
970 template <typename T>
971 using add_const_t = typename std::add_const<T>::type;
972#endif
973
974 //***************************************************************************
977 template <typename T> struct is_volatile : std::is_volatile<T> {};
978
979#if ETL_USING_CPP17
980 template <typename T>
981 inline constexpr bool is_volatile_v = std::is_volatile_v<T>;
982#endif
983
984 //***************************************************************************
987 template <typename T> struct remove_volatile : std::remove_volatile<T> {};
988
989#if ETL_USING_CPP11
990 template <typename T>
991 using remove_volatile_t = typename std::remove_volatile<T>::type;
992#endif
993
994 //***************************************************************************
997 template <typename T> struct add_volatile : std::add_volatile<T> {};
998
999#if ETL_USING_CPP11
1000 template <typename T>
1001 using add_volatile_t = typename std::add_volatile<T>::type;
1002#endif
1003
1004 //***************************************************************************
1007 template <typename T> struct remove_cv : std::remove_cv<T> {};
1008
1009#if ETL_USING_CPP11
1010 template <typename T>
1011 using remove_cv_t = typename std::remove_cv<T>::type;
1012#endif
1013
1014 //***************************************************************************
1017 template <typename T> struct add_cv : std::add_cv<T> {};
1018
1019#if ETL_USING_CPP11
1020 template <typename T>
1021 using add_cv_t = typename std::add_cv<T>::type;
1022#endif
1023
1024 //***************************************************************************
1027 template <typename T> struct remove_cvref
1028 {
1029 typedef typename std::remove_cv<typename std::remove_reference<T>::type>::type type;
1030 };
1031
1032#if ETL_USING_CPP11
1033 template <typename T>
1034 using remove_cvref_t = typename etl::remove_cvref<T>::type;
1035#endif
1036
1037 //***************************************************************************
1040 template <typename T> struct is_integral : std::is_integral<T> {};
1041
1042#if ETL_USING_CPP17
1043 template <typename T>
1044 inline constexpr bool is_integral_v = std::is_integral_v<T>;
1045#endif
1046
1047 //***************************************************************************
1050 template <typename T> struct is_signed : std::is_signed<T> {};
1051
1052#if ETL_USING_CPP17
1053 template <typename T>
1054 inline constexpr bool is_signed_v = std::is_signed_v<T>;
1055#endif
1056
1057 //***************************************************************************
1060 template <typename T> struct is_unsigned : std::is_unsigned<T> {};
1061
1062#if ETL_USING_CPP17
1063 template <typename T>
1064 inline constexpr bool is_unsigned_v = std::is_unsigned_v<T>;
1065#endif
1066
1067 //***************************************************************************
1070 template <typename T> struct is_floating_point : std::is_floating_point<T> {};
1071
1072#if ETL_USING_CPP17
1073 template <typename T>
1074 inline constexpr bool is_floating_point_v = std::is_floating_point_v<T>;
1075#endif
1076
1077 //***************************************************************************
1080 template <typename T1, typename T2> struct is_same : std::is_same<T1, T2> {};
1081
1082#if ETL_USING_CPP17
1083 template <typename T1, typename T2>
1084 inline constexpr bool is_same_v = std::is_same_v<T1, T2>;
1085#endif
1086
1087 //***************************************************************************
1090 template<typename T> struct is_void : std::is_void<T> {};
1091
1092#if ETL_USING_CPP17
1093 template <typename T>
1094 inline constexpr bool is_void_v = std::is_void_v<T>;
1095#endif
1096
1097 //***************************************************************************
1100 template<typename T> struct is_arithmetic : std::is_arithmetic<T> {};
1101
1102#if ETL_USING_CPP17
1103 template <typename T>
1104 inline constexpr bool is_arithmetic_v = std::is_arithmetic_v<T>;
1105#endif
1106
1107 //***************************************************************************
1110 template <typename T> struct is_fundamental : std::is_fundamental<T> {};
1111
1112#if ETL_USING_CPP17
1113 template <typename T>
1114 inline constexpr bool is_fundamental_v = std::is_fundamental_v<T>;
1115#endif
1116
1117 //***************************************************************************
1120 template <typename T> struct is_compound : std::is_compound<T> {};
1121
1122#if ETL_USING_CPP17
1123 template <typename T>
1124 inline constexpr bool is_compound_v = std::is_compound_v<T>;
1125#endif
1126
1127 //***************************************************************************
1130 template <typename T> struct is_array : std::is_array<T> {};
1131
1132#if ETL_USING_CPP17
1133 template <typename T>
1134 inline constexpr bool is_array_v = std::is_array_v<T>;
1135#endif
1136
1137 //***************************************************************************
1140 template<typename T> struct is_pointer : std::is_pointer<T> {};
1141
1142#if ETL_USING_CPP17
1143 template <typename T>
1144 inline constexpr bool is_pointer_v = std::is_pointer_v<T>;
1145#endif
1146
1147 //***************************************************************************
1150 template<typename T> struct is_reference : std::is_reference<T> {};
1151
1152#if ETL_USING_CPP17
1153 template <typename T>
1154 inline constexpr bool is_reference_v = std::is_reference_v<T>;
1155#endif
1156
1157 //***************************************************************************
1160 template<typename T> struct is_lvalue_reference : std::is_lvalue_reference<T> {};
1161
1162#if ETL_USING_CPP17
1163 template <typename T>
1164 inline constexpr bool is_lvalue_reference_v = std::is_lvalue_reference_v<T>;
1165#endif
1166
1167 //***************************************************************************
1170#if ETL_USING_CPP11
1171 template<typename T> struct is_rvalue_reference : std::is_rvalue_reference<T> {};
1172
1173#if ETL_USING_CPP17
1174 template <typename T>
1175 inline constexpr bool is_rvalue_reference_v = std::is_rvalue_reference_v<T>;
1176#endif
1177#endif
1178
1179 //***************************************************************************
1182 template <typename T>
1183 struct is_pod : std::integral_constant<bool, std::is_standard_layout<T>::value && std::is_trivial<T>::value> {};
1184
1185#if ETL_USING_CPP17
1186 template <typename T>
1187 inline constexpr bool is_pod_v = std::is_standard_layout_v<T> && std::is_trivial_v<T>;
1188#endif
1189
1190#if defined(ETL_COMPILER_GCC)
1191 #if ETL_COMPILER_VERSION >= 5
1192 #define ETL_GCC_V5_TYPE_TRAITS_SUPPORTED
1193 #endif
1194#endif
1195
1196 //***************************************************************************
1199 template <bool B, typename T, typename F> struct conditional { typedef T type; };
1200 template <typename T, typename F> struct conditional<false, T, F> { typedef F type; };
1201
1202#if ETL_USING_CPP11
1203 template <bool B, typename T, typename F>
1204 using conditional_t = typename conditional<B, T, F>::type;
1205#endif
1206
1207 //***************************************************************************
1210 template <typename T> struct make_signed : std::make_signed<T> {};
1211
1212#if ETL_USING_CPP11
1213 template <typename T>
1214 using make_signed_t = typename std::make_signed<T>::type;
1215#endif
1216
1217 //***************************************************************************
1220 template <typename T> struct make_unsigned : std::make_unsigned<T> {};
1221
1222#if ETL_USING_CPP11
1223 template <typename T>
1224 using make_unsigned_t = typename std::make_unsigned<T>::type;
1225#endif
1226
1227 //***************************************************************************
1230 template <bool B, typename T = void> struct enable_if : std::enable_if<B, T> {};
1231
1232#if ETL_USING_CPP11
1233 template <bool B, typename T = void>
1234 using enable_if_t = typename std::enable_if<B, T>::type;
1235#endif
1236
1237 //***************************************************************************
1240 template <typename T, unsigned MAXN = 0U>
1241 struct extent : std::extent<T, MAXN> {};
1242
1243#if ETL_USING_CPP17
1244 template <typename T, unsigned MAXN = 0U>
1245 inline constexpr size_t extent_v = std::extent_v<T, MAXN>;
1246#endif
1247
1248 //***************************************************************************
1251 template <typename T> struct remove_extent : std::remove_extent<T> { };
1252
1253#if ETL_USING_CPP11
1254 template <typename T>
1255 using remove_extent_t = typename std::remove_extent<T>::type;
1256#endif
1257
1258 //***************************************************************************
1261 template <typename T> struct remove_all_extents : std::remove_all_extents<T> { };
1262
1263#if ETL_USING_CPP11
1264 template <typename T>
1265 using remove_all_extents_t = typename std::remove_all_extents<T>::type;
1266#endif
1267
1268 //***************************************************************************
1271 template <typename T>struct rank : std::rank<T> {};
1272
1273#if ETL_USING_CPP17
1274 template <typename T>
1275 inline constexpr size_t rank_v = std::rank_v<T>;
1276#endif
1277
1278 //***************************************************************************
1281 template <typename T> struct decay : std::decay<T> {};
1282
1283#if ETL_USING_CPP11
1284 template <typename T>
1285 using decay_t = typename std::decay<T>::type;
1286#endif
1287
1288 //***************************************************************************
1291 template<typename TBase, typename TDerived> struct is_base_of : std::is_base_of<TBase, TDerived> {};
1292
1293#if ETL_USING_CPP17
1294 template <typename TBase, typename TDerived>
1295 inline constexpr bool is_base_of_v = std::is_base_of_v<TBase, TDerived>;
1296#endif
1297
1298 //***************************************************************************
1300 template <typename T> struct is_class : std::is_class<T>{};
1301
1302#if ETL_USING_CPP17
1303 template <typename T>
1304 inline constexpr bool is_class_v = is_class<T>::value;
1305#endif
1306
1307 //***************************************************************************
1309 template <typename T> struct add_lvalue_reference : std::add_lvalue_reference<T> {};
1310
1311#if ETL_USING_CPP11
1312 template <typename T>
1313 using add_lvalue_reference_t = typename std::add_lvalue_reference<T>::type;
1314#endif
1315
1316 //***************************************************************************
1318#if ETL_USING_CPP11
1319 template <typename T> struct add_rvalue_reference : std::add_rvalue_reference<T> {};
1320#endif
1321
1322#if ETL_USING_CPP11
1323 template <typename T>
1324 using add_rvalue_reference_t = typename std::add_rvalue_reference<T>::type;
1325#endif
1326
1327 //***************************************************************************
1329#if ETL_USING_CPP11
1330 template <typename T>
1331 typename std::add_rvalue_reference<T>::type declval() ETL_NOEXCEPT;
1332#endif
1333
1334#if ETL_USING_CPP11
1335 //***************************************************************************
1338 template <typename T>
1339 struct is_enum : std::is_enum<T>
1340 {
1341 };
1342
1343#if ETL_USING_CPP17
1344 template <typename T>
1345 inline constexpr bool is_enum_v = etl::is_enum<T>::value;
1346#endif
1347
1348#endif
1349
1350 //***************************************************************************
1353#if ETL_USING_CPP11
1354 template <typename TFrom, typename TTo>
1355 struct is_convertible : std::is_convertible<TFrom, TTo> {};
1356#endif
1357
1358#if ETL_USING_CPP17
1359 template <typename TFrom, typename TTo>
1360 inline constexpr bool is_convertible_v = std::is_convertible_v<TFrom, TTo>;
1361#endif
1362
1363 //***************************************************************************
1366 template <typename T> struct alignment_of : std::alignment_of<T> {};
1367 template <> struct alignment_of<void> : std::integral_constant<size_t, 0> {};
1368 template <> struct alignment_of<const void> : std::integral_constant <size_t, 0> {};
1369
1370#if ETL_USING_CPP17
1371 template <typename T>
1372 inline constexpr size_t alignment_of_v = std::alignment_of_v<T>;
1373#endif
1374
1375#endif // Condition = ETL_USING_STL && ETL_USING_CPP11
1376
1377 //***************************************************************************
1378 // ETL extended type traits.
1379 //***************************************************************************
1380
1381#if ETL_USING_CPP11
1382 //***************************************************************************
1384#if ETL_USING_CPP11
1385 template <typename...>
1386 struct conjunction : public etl::true_type
1387 {
1388 };
1389
1390 template <typename T1, typename... Tn>
1391 struct conjunction<T1, Tn...> : public etl::conditional_t<bool(T1::value), etl::conjunction<Tn...>, T1>
1392 {
1393 };
1394
1395 template <typename T>
1396 struct conjunction<T> : public T
1397 {
1398 };
1399#endif
1400
1401#if ETL_USING_CPP17
1402 template <typename... T>
1403 inline constexpr bool conjunction_v = conjunction<T...>::value;
1404#endif
1405
1406 //***************************************************************************
1408#if ETL_USING_CPP11
1409 template <typename...>
1410 struct disjunction : public etl::false_type
1411 {
1412 };
1413
1414 template <typename T1, typename... Tn>
1415 struct disjunction<T1, Tn...> : public etl::conditional_t<bool(T1::value), T1, disjunction<Tn...>>
1416 {
1417 };
1418
1419 template <typename T1> struct disjunction<T1> : public T1
1420 {
1421 };
1422#endif
1423
1424#if ETL_USING_CPP17
1425 template <typename... T>
1426 inline constexpr bool disjunction_v = etl::disjunction<T...>::value;
1427#endif
1428
1429#endif
1430
1431 //***************************************************************************
1433#if ETL_USING_CPP11
1434 template <typename... TTypes>
1435 struct exclusive_disjunction;
1436
1437 template <typename T>
1438 struct exclusive_disjunction<T> : public etl::bool_constant<T::value>
1439 {
1440 };
1441
1442 // Recursive case: XOR the first two values and recurse
1443 template <typename T1, typename T2, typename... TRest>
1444 struct exclusive_disjunction<T1, T2, TRest...> : public etl::exclusive_disjunction<etl::integral_constant<bool, etl::disjunction<T1, T2>::value && !etl::conjunction<T1, T2>::value>, TRest...>
1445 {
1446 };
1447#endif
1448
1449#if ETL_USING_CPP17
1450 template <typename... T>
1451 inline constexpr bool exclusive_disjunction_v = etl::exclusive_disjunction<T...>::value;
1452#endif
1453
1454 //***************************************************************************
1456 // /\ingroup type_traits
1457 template <bool B, typename T, T TRUE_VALUE, T FALSE_VALUE>
1459
1460 template <typename T, T TRUE_VALUE, T FALSE_VALUE>
1462 {
1463 ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Not an integral type");
1464 static const T value = TRUE_VALUE;
1465 };
1466
1467 template <typename T, T TRUE_VALUE, T FALSE_VALUE>
1469 {
1470 ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Not an integral type");
1471 static const T value = FALSE_VALUE;
1472 };
1473
1474#if ETL_USING_CPP11
1475 //***************************************************************************
1478 template <typename T, typename... TRest>
1479 struct is_one_of : etl::disjunction<etl::is_same<T, TRest>...>
1480 {
1481 };
1482#else
1483 /*[[[cog
1484 import cog
1485 cog.outl("//***************************************************************************")
1486 cog.outl("/// Template to determine if a type is one of a specified list.")
1487 cog.outl("///\\ingroup types")
1488 cog.outl("template <typename T,")
1489 cog.out(" ")
1490 cog.out("typename T1, ")
1491 for n in range(2, int(IsOneOf)):
1492 cog.out("typename T%s = void, " % n)
1493 if n % 4 == 0:
1494 cog.outl("")
1495 cog.out(" ")
1496 cog.outl("typename T%s = void>" % IsOneOf)
1497 cog.outl("struct is_one_of")
1498 cog.outl("{")
1499 cog.outl(" static const bool value = ")
1500 for n in range(1, int(IsOneOf)):
1501 cog.outl(" etl::is_same<T, T%s>::value ||" % n)
1502 cog.outl(" etl::is_same<T, T%s>::value;" % IsOneOf)
1503 cog.outl("};")
1504 ]]]*/
1505 /*[[[end]]]*/
1506#endif
1507
1508#if ETL_USING_CPP17
1509 template <typename T, typename... TRest>
1510 inline constexpr bool is_one_of_v = etl::is_one_of<T, TRest...>::value;
1511#endif
1512
1513#if ETL_USING_CPP11
1514 namespace private_type_traits
1515 {
1516 //***************************************************************************
1517 // Helper to count occurrences of a type in a list of types
1518 template<typename T, typename... TTypes>
1519 struct count_type;
1520
1521 // Base case: zero occurrences
1522 template<typename T>
1523 struct count_type<T> : etl::integral_constant<size_t, 0>
1524 {
1525 };
1526
1527 // Recursive case: increment count if head is the same as T, otherwise continue with tail
1528 template<typename T, typename THead, typename... TTail>
1529 struct count_type<T, THead, TTail...> : etl::integral_constant<size_t, (etl::is_same<T, THead>::value ? 1 : 0) + count_type<T, TTail...>::value>
1530 {
1531 };
1532 }
1533
1534 template<typename T, typename... TTypes>
1535 struct has_duplicates_of
1536 : etl::integral_constant<bool, (private_type_traits::count_type<T, TTypes...>::value > 1)>
1537 {
1538 };
1539#endif
1540
1541#if ETL_USING_CPP17
1542 template <typename T, typename... TRest>
1543 inline constexpr bool has_duplicates_of_v = etl::has_duplicates_of<T, TRest...>::value;
1544#endif
1545
1546#if ETL_USING_CPP11
1547 //***************************************************************************
1550 template <typename TBase, typename... TDerived>
1551 struct is_base_of_all : etl::conjunction<etl::is_base_of<TBase, TDerived>...>
1552 {
1553 };
1554#endif
1555
1556#if ETL_USING_CPP17
1557 template <typename T, typename... TRest>
1558 inline constexpr bool is_base_of_all_v = etl::is_base_of_all<T, TRest...>::value;
1559#endif
1560
1561#if ETL_USING_CPP11
1562 //***************************************************************************
1565 template <typename TBase, typename... TDerived>
1566 struct is_base_of_any : etl::disjunction<etl::is_base_of<TBase, TDerived>...>
1567 {
1568 };
1569
1570#endif
1571
1572#if ETL_USING_CPP17
1573 template <typename T, typename... TRest>
1574 inline constexpr bool is_base_of_any_v = etl::is_base_of_any<T, TRest...>::value;
1575#endif
1576
1577 //***************************************************************************
1580 //***************************************************************************
1581 // Recursive definition of the type.
1582 template <size_t N, typename TType>
1584 {
1585 typedef typename nth_base<N - 1U, typename TType::base_type>::type type;
1586 };
1587
1588 template <typename TType>
1589 struct nth_base<0, TType>
1590 {
1591 typedef TType type;
1592 };
1593
1594#if ETL_USING_CPP11
1595 template <size_t N, typename TType>
1596 using nth_base_t = typename nth_base<N, TType>::type;
1597#endif
1598
1599 //***************************************************************************
1602
1603 // Default.
1604 template <typename T>
1605 struct types
1606 {
1607 private:
1608
1609 typedef typename etl::remove_reference<typename etl::remove_cv<T>::type>::type type_t;
1610
1611 public:
1612
1613 typedef type_t type;
1614 typedef type_t& reference;
1615 typedef const type_t& const_reference;
1616 typedef type_t* pointer;
1617 typedef const type_t* const_pointer;
1618 typedef const type_t* const const_pointer_const;
1619
1620#if ETL_USING_CPP11
1621 typedef type_t&& rvalue_reference;
1622#endif
1623 };
1624
1625 // Pointers.
1626 template <typename T>
1627 struct types<T*>
1628 {
1629 private:
1630
1631 typedef typename etl::remove_reference<typename etl::remove_cv<T>::type>::type type_t;
1632
1633 public:
1634
1635 typedef type_t type;
1636 typedef type_t& reference;
1637 typedef const type_t& const_reference;
1638 typedef type_t* pointer;
1639 typedef const type_t* const_pointer;
1640 typedef const type_t* const const_pointer_const;
1641
1642#if ETL_USING_CPP11
1643 typedef type_t&& rvalue_reference;
1644#endif
1645 };
1646
1647 // Pointers.
1648 template <typename T>
1649 struct types<T* const>
1650 {
1651 private:
1652
1653 typedef typename etl::remove_reference<typename etl::remove_cv<T>::type>::type type_t;
1654
1655 public:
1656
1657 typedef type_t type;
1658 typedef type_t& reference;
1659 typedef const type_t& const_reference;
1660 typedef type_t* pointer;
1661 typedef const type_t* const_pointer;
1662 typedef const type_t* const const_pointer_const;
1663
1664#if ETL_USING_CPP11
1665 typedef type_t&& rvalue_reference;
1666#endif
1667 };
1668
1669 // References.
1670 template <typename T>
1671 struct types<T&>
1672 {
1673 private:
1674
1675 typedef typename etl::remove_reference<typename etl::remove_cv<T>::type>::type type_t;
1676
1677 public:
1678
1679 typedef type_t type;
1680 typedef type_t& reference;
1681 typedef const type_t& const_reference;
1682 typedef type_t* pointer;
1683 typedef const type_t* const_pointer;
1684 typedef const type_t* const const_pointer_const;
1685
1686#if ETL_USING_CPP11
1687 typedef type_t&& rvalue_reference;
1688#endif
1689 };
1690
1691#if ETL_USING_CPP11
1692 // rvalue References.
1693 template <typename T>
1694 struct types<T&&>
1695 {
1696 private:
1697
1698 typedef typename etl::remove_reference<typename etl::remove_cv<T>::type>::type type_t;
1699
1700 public:
1701
1702 typedef type_t type;
1703 typedef type_t& reference;
1704 typedef const type_t& const_reference;
1705 typedef type_t* pointer;
1706 typedef const type_t* const_pointer;
1707 typedef const type_t* const const_pointer_const;
1708
1709#if ETL_USING_CPP11
1710 typedef type_t&& rvalue_reference;
1711#endif
1712 };
1713#endif
1714
1715#if ETL_USING_CPP11
1716 template <typename T>
1717 using types_t = typename types<T>::type;
1718
1719 template <typename T>
1720 using types_r = typename types<T>::reference;
1721
1722 template <typename T>
1723 using types_cr = typename types<T>::const_reference;
1724
1725 template <typename T>
1726 using types_rr = typename types<T>::rvalue_reference;
1727
1728 template <typename T>
1729 using types_p = typename types<T>::pointer;
1730
1731 template <typename T>
1732 using types_cp = typename types<T>::const_pointer;
1733
1734 template <typename T>
1735 using types_cpc = typename types<T>::const_pointer_const;
1736#endif
1737
1738 //***************************************************************************
1741 template <typename T> struct size_of : etl::integral_constant<size_t, sizeof(T)> {};
1742 template <> struct size_of<void> : etl::integral_constant<size_t, 1U> {};
1743
1744#if ETL_USING_CPP17
1745 template <typename T>
1746 inline constexpr size_t size_of_v = etl::size_of<T>::value;
1747#endif
1748
1749#if ETL_USING_CPP11
1750 //***************************************************************************
1752 template <typename T, typename... TRest>
1753 struct are_all_same : etl::conjunction<etl::is_same<T, TRest>...>
1754 {
1755 };
1756#endif
1757
1758#if ETL_USING_CPP17
1759 template <typename T, typename... TRest>
1760 inline constexpr bool are_all_same_v = are_all_same<T, TRest...>::value;
1761#endif
1762
1763 //***************************************************************************
1764#if ETL_USING_STL && ETL_USING_CPP11 && !defined(ETL_USE_TYPE_TRAITS_BUILTINS) && !defined(ETL_USER_DEFINED_TYPE_TRAITS) && ((!defined(ARDUINO) && ETL_NOT_USING_STLPORT) || defined(ETL_GCC_V5_TYPE_TRAITS_SUPPORTED))
1765
1766 //*********************************************
1767 // Use the STL's definitions.
1768 //*********************************************
1769
1770 //*********************************************
1771 // is_assignable
1772 template<typename T1, typename T2>
1773 using is_assignable = std::is_assignable<T1, T2>;
1774
1775 //*********************************************
1776 // is_constructible
1777 template<typename T, typename... TArgs>
1778 using is_constructible = std::is_constructible<T, TArgs...>;
1779
1780 //*********************************************
1781 // is_copy_constructible
1782 template <typename T>
1783 using is_copy_constructible = std::is_copy_constructible<T>;
1784
1785 //*********************************************
1786 // is_move_constructible
1787 template <typename T>
1788 using is_move_constructible = std::is_move_constructible<T>;
1789
1790 //*********************************************
1791 // is_trivially_constructible
1792#if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED
1793 template <typename T>
1794 using is_trivially_constructible = std::is_trivially_constructible<T>;
1795#else
1796 template <typename T>
1798#endif
1799
1800 //*********************************************
1801 // is_trivially_copy_constructible
1802#if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED
1803 template <typename T>
1804 using is_trivially_copy_constructible = std::is_trivially_copy_constructible<T>;
1805#else
1806 template <typename T>
1807 using is_trivially_copy_constructible = etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>;
1808#endif
1809
1810 //*********************************************
1811 // is_trivially_destructible
1812#if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED
1813 template <typename T>
1814 using is_trivially_destructible = std::is_trivially_destructible<T>;
1815#else
1816 template <typename T>
1818#endif
1819
1820 //*********************************************
1821 // is_trivially_copy_assignable
1822#if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED
1823 template <typename T>
1824 using is_trivially_copy_assignable = std::is_trivially_copy_assignable<T>;
1825#else
1826 template <typename T>
1827 using is_trivially_copy_assignable = etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>;
1828#endif
1829
1830 //*********************************************
1831 // is_trivially_copyable
1832#if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED
1833 template <typename T>
1834 using is_trivially_copyable = std::is_trivially_copyable<T>;
1835#else
1836 template <typename T>
1838#endif
1839
1840#elif defined(ETL_USE_TYPE_TRAITS_BUILTINS) && !defined(ETL_USER_DEFINED_TYPE_TRAITS)
1841
1842 //*********************************************
1843 // Use the compiler's builtins.
1844 //*********************************************
1845
1846 //*********************************************
1847 // is_assignable
1848 template<typename T1, typename T2>
1849 struct is_assignable
1850 {
1851 static ETL_CONSTANT bool value = __is_assignable(T1, T2);
1852 };
1853
1854#if ETL_USING_CPP11
1855 //*********************************************
1856 // is_constructible
1857 template<typename T, typename... TArgs>
1858 struct is_constructible
1859 {
1860 static ETL_CONSTANT bool value = __is_constructible(T, TArgs...);
1861 };
1862#else
1863 //*********************************************
1864 // is_constructible
1865 template<typename T, typename TArgs = void>
1866 struct is_constructible
1867 {
1868 static ETL_CONSTANT bool value = __is_constructible(T, TArgs);
1869 };
1870
1871 //*********************************************
1872 // is_constructible
1873 template<typename T>
1874 struct is_constructible<T, void>
1875 {
1876 static ETL_CONSTANT bool value = __is_constructible(T);
1877 };
1878#endif
1879
1880 //*********************************************
1881 // is_copy_constructible
1882 template <typename T>
1883 struct is_copy_constructible : public etl::is_constructible<T, typename etl::add_lvalue_reference<const T>::type>
1884 {
1885 };
1886
1887 //*********************************************
1888 // is_move_constructible
1889 template <typename T>
1890 struct is_move_constructible : public etl::is_constructible<T, T>
1891 {
1892 };
1893
1894#if ETL_USING_CPP11
1895 //*********************************************
1896 // is_trivially_constructible
1897 template <typename T, typename... TArgs>
1898 struct is_trivially_constructible
1899 {
1900#if defined(ETL_COMPILER_GCC)
1901 static ETL_CONSTANT bool value = __has_trivial_constructor(T);
1902#else
1903 static ETL_CONSTANT bool value = __is_trivially_constructible(T, TArgs...);
1904#endif
1905 };
1906#else
1907 //*********************************************
1908 // is_trivially_constructible
1909 template <typename T, typename TArgs = void>
1910 struct is_trivially_constructible
1911 {
1912#if defined(ETL_COMPILER_GCC)
1913 static ETL_CONSTANT bool value = __has_trivial_constructor(T);
1914#else
1915 static ETL_CONSTANT bool value = __is_trivially_constructible(T, TArgs);
1916#endif
1917 };
1918
1919 //*********************************************
1920 // is_trivially_constructible
1921 template <typename T>
1922 struct is_trivially_constructible<T, void>
1923 {
1924#if defined(ETL_COMPILER_GCC)
1925 static ETL_CONSTANT bool value = __has_trivial_constructor(T);
1926#else
1927 static ETL_CONSTANT bool value = __is_trivially_constructible(T);
1928#endif
1929 };
1930#endif
1931
1932 //*********************************************
1933 // is_trivially_copy_constructible
1934 template <typename T>
1935 struct is_trivially_copy_constructible : public is_trivially_constructible<T, typename add_lvalue_reference<const T>::type>
1936 {
1937 };
1938
1939 //*********************************************
1940 // is_trivially_destructible
1941 template <typename T>
1942 struct is_trivially_destructible
1943 {
1944#if defined(ETL_COMPILER_GCC)
1945 static ETL_CONSTANT bool value = __has_trivial_destructor(T);
1946#else
1947 static ETL_CONSTANT bool value = __is_trivially_destructible(T);
1948#endif
1949 };
1950
1951 //*********************************************
1952 // is_trivially_copy_assignable
1953 template <typename T>
1954 struct is_trivially_copy_assignable
1955 {
1956#if defined(ETL_COMPILER_GCC)
1957 static ETL_CONSTANT bool value = __has_trivial_copy(T);
1958#else
1959 static ETL_CONSTANT bool value = __is_trivially_copyable(T);
1960#endif
1961 };
1962
1963 //*********************************************
1964 // is_trivially_copyable
1965 template <typename T>
1966 struct is_trivially_copyable
1967 {
1968#if defined(ETL_COMPILER_GCC)
1969 static ETL_CONSTANT bool value = __has_trivial_copy(T);
1970#else
1971 static ETL_CONSTANT bool value = __is_trivially_copyable(T);
1972#endif
1973 };
1974
1975#elif defined(ETL_USER_DEFINED_TYPE_TRAITS) && !defined(ETL_USE_TYPE_TRAITS_BUILTINS)
1976
1977 //*********************************************
1978 // Force the user to provide specialisations for
1979 // anything other than arithmetics and pointers.
1980 //*********************************************
1981
1982 //*********************************************
1983 // is_assignable
1984 template <typename T1,
1985 typename T2,
1987 struct is_assignable;
1988
1989 template <typename T1, typename T2>
1990 struct is_assignable<T1, T2, true> : public etl::true_type
1991 {
1992 };
1993
1994 template <typename T1, typename T2>
1995 struct is_assignable<T1, T2, false>;
1996
1997#if ETL_USING_CPP11
1998 //*********************************************
1999 // is_constructible
2000 template <typename T, bool B, typename... TArgs>
2002
2003 template <typename T, typename... TArgs>
2004 struct is_constructible_helper<T, true, TArgs...> : public etl::true_type
2005 {
2006 };
2007
2008 template <typename T, typename... TArgs>
2009 struct is_constructible_helper<T, false, TArgs...>;
2010
2011 template <typename T, typename... TArgs>
2012 struct is_constructible : public is_constructible_helper<T, etl::is_arithmetic<T>::value || etl::is_pointer<T>::value, TArgs...>
2013 {
2014 };
2015#endif
2016
2017 //*********************************************
2018 // is_copy_constructible
2020 struct is_copy_constructible;
2021
2022 template <typename T>
2023 struct is_copy_constructible<T, true> : public etl::true_type
2024 {
2025 };
2026
2027 template <typename T>
2028 struct is_copy_constructible<T, false>;
2029
2030 //*********************************************
2031 // is_move_constructible
2033 struct is_move_constructible;
2034
2035 template <typename T>
2036 struct is_move_constructible<T, true> : public etl::true_type
2037 {
2038 };
2039
2040 template <typename T>
2041 struct is_move_constructible<T, false>;
2042
2043 //*********************************************
2044 // is_trivially_constructible
2046 struct is_trivially_constructible;
2047
2048 template <typename T>
2049 struct is_trivially_constructible<T, true> : public etl::true_type
2050 {
2051 };
2052
2053 template <typename T>
2054 struct is_trivially_constructible<T, false>;
2055
2056 //*********************************************
2057 // is_trivially_copy_constructible
2059 struct is_trivially_copy_constructible;
2060
2061 template <typename T>
2062 struct is_trivially_copy_constructible<T, true> : public etl::true_type
2063 {
2064 };
2065
2066 template <typename T>
2067 struct is_trivially_copy_constructible<T, false>;
2068
2069 //*********************************************
2070 // is_trivially_destructible
2072 struct is_trivially_destructible;
2073
2074 template <typename T>
2075 struct is_trivially_destructible<T, true> : public etl::true_type
2076 {
2077 };
2078
2079 template <typename T>
2080 struct is_trivially_destructible<T, false>;
2081
2082 //*********************************************
2083 // is_trivially_copy_assignable
2085 struct is_trivially_copy_assignable;
2086
2087 template <typename T>
2088 struct is_trivially_copy_assignable<T, true> : public etl::true_type
2089 {
2090 };
2091
2092 template <typename T>
2093 struct is_trivially_copy_assignable<T, false>;
2094
2095 //*********************************************
2096 // is_trivially_copyable
2098 struct is_trivially_copyable;
2099
2100 template <typename T>
2101 struct is_trivially_copyable<T, true> : public etl::true_type
2102 {
2103 };
2104
2105 template <typename T>
2106 struct is_trivially_copyable<T, false>;
2107
2108#else
2109
2110 //*********************************************
2111 // Assume that anything other than arithmetics
2112 // and pointers return false for the traits.
2113 //*********************************************
2114
2115 //*********************************************
2116 // is_assignable
2117 template <typename T1, typename T2>
2118 struct is_assignable : public etl::bool_constant<(etl::is_arithmetic<T1>::value || etl::is_pointer<T1>::value) && (etl::is_arithmetic<T2>::value || etl::is_pointer<T2>::value)>
2119 {
2120 };
2121
2122#if ETL_USING_CPP11
2123 //***************************************************************************
2125 namespace private_type_traits
2126 {
2127 template <class, class T, class... Args>
2129
2130 template <class T, class... Args>
2131 struct is_constructible_<void_t<decltype(T(etl::declval<Args>()...))>, T, Args...> : etl::true_type {};
2132 }
2133
2134 //*********************************************
2135 // is_constructible
2136 template <class T, class... Args>
2137 using is_constructible = private_type_traits::is_constructible_<void_t<>, T, Args...>;
2138
2139 //*********************************************
2140 // is_copy_constructible
2141 template <class T> struct is_copy_constructible : public is_constructible<T, typename etl::add_lvalue_reference<typename etl::add_const<T>::type>::type>{};
2142 template <> struct is_copy_constructible<void> : public false_type{};
2143 template <> struct is_copy_constructible<void const> : public false_type{};
2144 template <> struct is_copy_constructible<void volatile> : public false_type{};
2145 template <> struct is_copy_constructible<void const volatile> : public false_type{};
2146
2147 //*********************************************
2148 // is_move_constructible
2149 template <typename T> struct is_move_constructible: public is_constructible<T, typename etl::add_rvalue_reference<T>::type>{};
2150 template <> struct is_move_constructible<void> : public false_type{};
2151 template <> struct is_move_constructible<void const> : public false_type{};
2152 template <> struct is_move_constructible<void volatile> : public false_type{};
2153 template <> struct is_move_constructible<void const volatile> : public false_type{};
2154
2155#else
2156
2157 //*********************************************
2158 // is_copy_constructible
2159 template <typename T>
2160 struct is_copy_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
2161 {
2162 };
2163
2164 //*********************************************
2165 // is_move_constructible
2166 template <typename T>
2167 struct is_move_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
2168 {
2169 };
2170#endif
2171
2172 //*********************************************
2173 // is_trivially_constructible
2174 template <typename T>
2175 struct is_trivially_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
2176 {
2177 };
2178
2179 //*********************************************
2180 // is_trivially_copy_constructible
2181 template <typename T>
2182 struct is_trivially_copy_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
2183 {
2184 };
2185
2186 //*********************************************
2187 // is_trivially_destructible
2188 template <typename T>
2189 struct is_trivially_destructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
2190 {
2191 };
2192
2193 //*********************************************
2194 // is_trivially_copy_assignable
2195 template <typename T>
2196 struct is_trivially_copy_assignable : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
2197 {
2198 };
2199
2200 //*********************************************
2201 // is_trivially_copyable
2202 template <typename T>
2203 struct is_trivially_copyable : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
2204 {
2205 };
2206
2207#endif
2208
2209 template <typename T1, typename T2>
2210 struct is_lvalue_assignable : public etl::is_assignable<typename etl::add_lvalue_reference<T1>::type,
2211 typename etl::add_lvalue_reference<typename etl::add_const<T2>::type>::type>
2212 {
2213 };
2214
2215#if ETL_USING_CPP11
2216 //*********************************************
2217 // is_default_constructible
2218 template<typename T, typename = void>
2220
2221 template<typename T>
2222 struct is_default_constructible<T, etl::void_t<decltype(T())>> : etl::true_type { };
2223#else
2224 template <typename T>
2225 struct is_default_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
2226 {
2227 };
2228#endif
2229
2230#if ETL_USING_CPP17
2231
2232 template <typename T1, typename T2>
2233 inline constexpr bool is_assignable_v = etl::is_assignable<T1, T2>::value;
2234
2235 template <typename T1, typename T2>
2237
2238 template<typename T, typename... TArgs>
2239 inline constexpr bool is_constructible_v = etl::is_constructible<T, TArgs...>::value;
2240
2241 template<typename T, typename... TArgs>
2242 inline constexpr bool is_default_constructible_v = etl::is_default_constructible<T, TArgs...>::value;
2243
2244 template<typename T>
2246
2247 template<typename T>
2249
2250 template <typename T>
2252
2253 template <typename T>
2255
2256 template <typename T>
2258
2259 template <typename T>
2261
2262 template <typename T>
2264
2265#endif
2266
2267#if ETL_USING_CPP11
2268 //*********************************************
2269 // common_type
2270 // Based on the sample implementation detailed on
2271 // https://en.cppreference.com/w/cpp/types/common_type
2272 //*********************************************
2273 //***********************************
2274 // Primary template
2275 template<typename...>
2276 struct common_type
2277 {
2278 };
2279
2280 //***********************************
2281 // One type
2282 template <typename T>
2284 {
2285 };
2286
2287 namespace private_common_type
2288 {
2289 template <typename T1, typename T2>
2290 using conditional_result_t = decltype(false ? declval<T1>() : declval<T2>());
2291
2292 template <typename, typename, typename = void>
2294 {
2295 };
2296
2297 template <typename T1, typename T2>
2300 {
2301 };
2302
2303 template <typename T1, typename T2, typename = void>
2304 struct common_type_2_impl
2305 : decay_conditional_result<const T1&, const T2&>
2306 {
2307 };
2308
2309 template <typename T1, typename T2>
2311 : decay_conditional_result<T1, T2>
2312 {
2313 };
2314 }
2315
2316 //***********************************
2317 // Two types
2318 template <typename T1, typename T2>
2319 struct common_type<T1, T2>
2320 : etl::conditional<etl::is_same<T1, typename etl::decay<T1>::type>::value&& etl::is_same<T2, typename etl::decay<T2>::type>::value,
2321 private_common_type::common_type_2_impl<T1, T2>,
2322 common_type<typename etl::decay<T2>::type,
2323 typename etl::decay<T2>::type>>::type
2324 {
2325 };
2326
2327 //***********************************
2328 // Three or more types
2329 namespace private_common_type
2330 {
2331 template <typename AlwaysVoid, typename T1, typename T2, typename... TRest>
2333 {
2334 };
2335
2336 template <typename T1, typename T2, typename... TRest>
2338 : common_type<typename common_type<T1, T2>::type, TRest...>
2339 {
2340 };
2341 }
2342
2343 template<typename T1, typename T2, typename... TRest>
2344 struct common_type<T1, T2, TRest...>
2345 : private_common_type::common_type_multi_impl<void, T1, T2, TRest...>
2346 {
2347 };
2348
2349 template <typename... T>
2350 using common_type_t = typename common_type<T...>::type;
2351#endif
2352
2353 //***************************************************************************
2355 //***************************************************************************
2356 template <typename T>
2358 {
2359 typedef typename etl::conditional<sizeof(T) == sizeof(unsigned char), unsigned char,
2360 typename etl::conditional<sizeof(T) == sizeof(unsigned short), unsigned short,
2361 typename etl::conditional<sizeof(T) == sizeof(unsigned int), unsigned int,
2362 typename etl::conditional<sizeof(T) == sizeof(unsigned long), unsigned long,
2363 unsigned long long>::type>::type>::type>::type type;
2364 };
2365
2366#if ETL_USING_CPP11
2367 template <typename T>
2368 using unsigned_type_t = typename unsigned_type<T>::type;
2369#endif
2370
2371 //***************************************************************************
2373 //***************************************************************************
2374 template <typename T>
2376 {
2377 typedef typename etl::conditional<sizeof(T) == sizeof(char), char,
2378 typename etl::conditional<sizeof(T) == sizeof(short), short,
2379 typename etl::conditional<sizeof(T) == sizeof(int), int,
2380 typename etl::conditional<sizeof(T) == sizeof(long), long,
2381 long long>::type>::type>::type>::type type;
2382 };
2383
2384#if ETL_USING_CPP11
2385 template <typename T>
2386 using signed_type_t = typename signed_type<T>::type;
2387#endif
2388
2389 //*********************************************
2390 // type_identity
2391
2392 template <typename T>
2393 struct type_identity { typedef T type; };
2394
2395#if ETL_USING_CPP11
2396 template <typename T>
2397 using type_identity_t = typename type_identity<T>::type;
2398#endif
2399
2400 //*********************************************
2401 // underlying_type
2402#if ETL_USING_BUILTIN_UNDERLYING_TYPE
2403 // Primary template for etl::underlying_type
2405 struct underlying_type;
2406
2407 // Specialization for non-enum types (invalid case)
2408 template <typename T>
2409 struct underlying_type<T, false>
2410 {
2411 // Static assertion to ensure this is only used with enums
2412 ETL_STATIC_ASSERT(etl::is_enum<T>::value, "etl::underlying_type can only be used with enumeration types.");
2413 };
2414
2415 template <typename T>
2416 struct underlying_type<T, true>
2417 {
2418 typedef __underlying_type(T) type;
2419 };
2420#else
2423 template <typename T>
2425 {
2426 typedef int type;
2427 };
2428#endif
2429
2430#if ETL_USING_CPP11
2431 template <typename T>
2432 using underlying_type_t = typename underlying_type<T>::type;
2433#endif
2434
2435#if ETL_USING_CPP11
2436 //*********************************************
2437 // has_duplicates
2438 template <typename... TTypes>
2439 struct has_duplicates;
2440
2441 template <typename TFirst, typename... TRest>
2442 struct has_duplicates<TFirst, TRest...> : etl::conditional_t<etl::is_one_of<TFirst, TRest...>::value,
2443 etl::true_type,
2444 has_duplicates<TRest...>> {};
2445
2446 template <typename T>
2447 struct has_duplicates<T> : etl::false_type {};
2448
2449 template <>
2450 struct has_duplicates<> : etl::false_type {};
2451#endif
2452
2453#if ETL_USING_CPP17
2454 template <typename... TTypes>
2455 inline constexpr bool has_duplicates_v = etl::has_duplicates<TTypes...>::value;
2456#endif
2457
2458#if ETL_USING_CPP11
2459 //*********************************************
2460 // count_of
2461 template <typename T, typename... TTypes>
2462 struct count_of;
2463
2464 template <typename T, typename U, typename... URest>
2465 struct count_of<T, U, URest...> : etl::integral_constant<size_t,
2466 etl::is_same<T, U>::value +
2467 count_of<T, URest...>::value> {};
2468
2469 template <typename T>
2470 struct count_of<T> : etl::integral_constant<size_t, 0> {};
2471#endif
2472
2473#if ETL_USING_CPP17
2474 template <typename T, typename... TTypes>
2475 inline constexpr size_t count_of_v = etl::count_of<T, TTypes...>::value;
2476#endif
2477
2478#if ETL_USING_CPP11
2479 //*********************************************
2481 template <typename T, template <typename...> class Template>
2483
2484 template <template <typename...> class Template, typename... TArgs>
2486#endif
2487
2488#if ETL_USING_CPP17
2489 template <typename T, template <typename...> class Template>
2490 inline constexpr bool is_specialization_v = etl::is_specialization<T, Template>::value;
2491#endif
2492}
2493
2494// Helper macros
2495#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)
2496#define ETL_IS_NOT_CHAR_TYPE(type) (!ETL_IS_CHAR_TYPE(type))
2497
2498#define ETL_IS_POINTER_TYPE(type) (etl::is_pointer<type>::value)
2499#define ETL_IS_NOT_POINTER_TYPE(type) (!ETL_IS_POINTER_TYPE(type))
2500
2501#define ETL_TARGET_IS_TRIVIALLY_COPYABLE(type) (etl::is_trivially_copyable<typename etl::iterator_traits<type>::value_type>::value)
2502#define ETL_TARGET_IS_NOT_TRIVIALLY_COPYABLE(type) (!ETL_TARGET_IS_TRIVIALLY_COPYABLE(type))
2503
2504#endif // ETL_TYPE_TRAITS_INCLUDED
integral_constant< bool, false > false_type
integral_constant specialisations
Definition type_traits_generator.h:875
add_const
Definition type_traits_generator.h:967
add_cv
Definition type_traits_generator.h:1017
add_pointer
Definition type_traits_generator.h:937
add_volatile
Definition type_traits_generator.h:997
add_rvalue_reference
Definition type_traits_generator.h:1366
conditional
Definition type_traits_generator.h:1199
decay
Definition type_traits_generator.h:1281
enable_if
Definition type_traits_generator.h:1230
extent
Definition type_traits_generator.h:1241
integral_constant
Definition type_traits_generator.h:871
is_arithmetic
Definition type_traits_generator.h:1100
is_array
Definition type_traits_generator.h:1130
is_base_of
Definition type_traits_generator.h:1291
is_compound
Definition type_traits_generator.h:1120
is_const
Definition type_traits_generator.h:947
is_floating_point
Definition type_traits_generator.h:1070
is_fundamental
Definition type_traits_generator.h:1110
is_integral
Definition type_traits_generator.h:1040
is_lvalue_reference
Definition type_traits_generator.h:1160
is_rvalue_reference
Definition type_traits_generator.h:1183
is_pointer
Definition type_traits_generator.h:1140
is_reference
Definition type_traits_generator.h:1150
is_same
Definition type_traits_generator.h:1080
is_signed
Definition type_traits_generator.h:1050
is_unsigned
Definition type_traits_generator.h:1060
is_void
Definition type_traits_generator.h:1090
is_volatile
Definition type_traits_generator.h:977
make_signed
Definition type_traits_generator.h:1210
make_unsigned
Definition type_traits_generator.h:1220
negation
Definition type_traits_generator.h:905
rank
Definition type_traits_generator.h:1271
remove_all_extents
Definition type_traits_generator.h:1261
remove_const
Definition type_traits_generator.h:957
remove_cv
Definition type_traits_generator.h:1007
remove_cvref
Definition type_traits_generator.h:1028
remove_extent
Definition type_traits_generator.h:1251
remove_pointer
Definition type_traits_generator.h:927
remove_reference
Definition type_traits_generator.h:917
remove_volatile
Definition type_traits_generator.h:987
bitset_ext
Definition absolute.h:38
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_even_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:314
add_lvalue_reference
Definition type_traits_generator.h:1309
Definition type_traits_generator.h:888
exclusive_disjunction
Definition type_traits_generator.h:1458
Definition type_traits_generator.h:2119
is_class
Definition type_traits_generator.h:1300
Definition type_traits_generator.h:2161
Definition type_traits_generator.h:2226
Definition type_traits_generator.h:2212
Definition type_traits_generator.h:2168
Definition type_traits_generator.h:2176
Definition type_traits_generator.h:2197
Definition type_traits_generator.h:2183
Definition type_traits_generator.h:2204
Definition type_traits_generator.h:2190
Get the Nth base of a recursively inherited type. Requires that the class has defined 'base_type'.
Definition type_traits_generator.h:1584
Defines one of five signed types that has the same size as T.
Definition type_traits_generator.h:2376
size_of
Definition type_traits_generator.h:1741
Definition type_traits_generator.h:2393
A set of templates to allow related types to be derived.
Definition type_traits_generator.h:1606
Primary template for etl::underlying_type Users must specialise this template for their enumerations.
Definition type_traits_generator.h:2425
Defines one of five unsigned types that has the same size as T.
Definition type_traits_generator.h:2358
void add_pointer(const volatile void *value, TIString &str, const etl::basic_format_spec< TIString > &format, const bool append)
Helper function for pointers.
Definition to_string_helper.h:443