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