29#ifndef ETL_TYPE_LIST_INCLUDED
30#define ETL_TYPE_LIST_INCLUDED
34#include "index_of_type.h"
37#include "static_assert.h"
47 static ETL_CONSTANT
size_t type_list_npos = etl::integral_limits<size_t>::max;
52 template <
typename... TTypes>
63 template <
typename... TTypes>
64 struct is_type_list<etl::type_list<TTypes...>> : etl::true_type
70 inline constexpr bool is_type_list_v = is_type_list<T>::value;
79 static constexpr size_t size = 0U;
81 using index_sequence_type = etl::make_index_sequence<0>;
88 type_list() ETL_DELETE;
89 type_list(const type_list&) ETL_DELETE;
90 type_list& operator=(const type_list&) ETL_DELETE;
93 namespace private_type_list
97 template <
typename... TTypes>
98 struct recursion_helper
100 using type = type_list<TTypes...>;
107 template <
typename THead,
typename... TTail>
108 struct type_list<THead, TTail...> : type_list<TTail...>
111 using tail =
typename private_type_list::recursion_helper<TTail...>::type;
113 static constexpr size_t size =
sizeof...(TTail) + 1U;
115 using index_sequence_type = etl::make_index_sequence<
sizeof...(TTail) + 1U>;
121 type_list() ETL_DELETE;
122 type_list(const type_list&) ETL_DELETE;
123 type_list& operator=(const type_list&) ETL_DELETE;
129 template <typename THead>
130 struct type_list<THead> : type_list<>
133 using tail =
typename private_type_list::recursion_helper<>::type;
135 static constexpr size_t size = 1U;
137 using index_sequence_type = etl::make_index_sequence<1>;
142 type_list() ETL_DELETE;
143 type_list(const type_list&) ETL_DELETE;
144 type_list& operator=(const type_list&) ETL_DELETE;
150 template <typename TTypes>
151 struct type_list_size;
153 template <typename... TTypes>
154 struct type_list_size<etl::type_list<TTypes...>> : public etl::integral_constant<
size_t, sizeof...(TTypes)>
159 template <
typename... TTypes>
160 inline constexpr size_t type_list_size_v = type_list_size<etl::type_list<TTypes...>>::value;
167 template <
typename TTypeList,
size_t Index>
168 struct type_list_type_at_index
170 ETL_STATIC_ASSERT(Index < TTypeList::size,
"etl::type_list_type_at_index out of range");
171 ETL_STATIC_ASSERT((etl::is_type_list<TTypeList>::value),
"TTypeList must be an etl::type_list");
173 using type =
typename type_list_type_at_index<
typename TTypeList::tail, Index - 1>::type;
176 template <
typename TTypeList>
177 struct type_list_type_at_index<TTypeList, 0>
179 ETL_STATIC_ASSERT((etl::is_type_list<TTypeList>::value),
"TTypeList must be an etl::type_list");
181 using type =
typename TTypeList::head;
184 template <
typename TTypeList,
size_t Index>
185 using type_list_type_at_index_t =
typename type_list_type_at_index<TTypeList, Index>::type;
194 template <
typename TTypeList,
typename T>
195 struct type_list_index_of_type
196 :
public etl::integral_constant< size_t, etl::is_same<typename TTypeList::head, T>::value
198 : (type_list_index_of_type<typename TTypeList::tail, T>::value == etl::type_list_npos
199 ? etl::type_list_npos
200 : type_list_index_of_type<typename TTypeList::tail, T>::value + 1)>
202 ETL_STATIC_ASSERT((etl::is_type_list<TTypeList>::value),
"TTypeList must be an etl::type_list");
205 template <
typename T>
206 struct type_list_index_of_type<type_list<>, T> :
public etl::integral_constant<size_t, etl::type_list_npos>
211 template <
typename TTypeList,
typename T>
212 inline constexpr size_t type_list_index_of_v = etl::type_list_index_of_type<TTypeList, T>::value;
222 namespace private_type_list
224 template <
typename TTypeList,
typename T,
size_t Index,
typename TResult>
225 struct type_list_indices_of_type_impl;
229 template <
typename Head,
typename... Tail,
typename T,
size_t Index,
typename TResult>
230 struct type_list_indices_of_type_impl<etl::type_list<Head, Tail...>, T, Index, TResult>
236 using next_result = etl::conditional_t<etl::is_same<Head, T>::value, etl::index_sequence_push_back_t<TResult, Index>, TResult>;
241 using type =
typename type_list_indices_of_type_impl<etl::type_list<Tail...>, T, Index + 1U, next_result>::type;
246 template <
typename T,
size_t Index,
typename TResult>
247 struct type_list_indices_of_type_impl<etl::type_list<>, T, Index, TResult>
249 using type = TResult;
253 template <
typename TTypeList,
typename T>
254 struct type_list_indices_of_type
256 ETL_STATIC_ASSERT((etl::is_type_list<TTypeList>::value),
"TTypeList must be an etl::type_list");
258 using type =
typename private_type_list::type_list_indices_of_type_impl< TTypeList, T, 0U, etl::index_sequence<>>::type;
262 template <
typename TTypeList,
typename T>
263 using type_list_indices_of_type_t =
typename type_list_indices_of_type<TTypeList, T>::type;
270 template <
typename TTypeList,
typename T>
271 struct type_list_contains;
273 template <
typename T,
typename... TTypes>
274 struct type_list_contains<etl::type_list<TTypes...>, T> :
public etl::integral_constant<bool, etl::is_one_of<T, TTypes...>::value>
278 template <
typename T>
279 struct type_list_contains<type_list<>, T> :
public etl::integral_constant<bool, false>
284 template <
typename TTypeList,
typename T>
285 inline constexpr bool type_list_contains_v = etl::type_list_contains<TTypeList, T>::value;
292 template <
typename TTypeList,
typename T>
293 struct type_list_has_duplicates_of;
295 template <
typename T,
typename... TTypes>
296 struct type_list_has_duplicates_of<etl::type_list<TTypes...>, T> :
public etl::has_duplicates_of<T, TTypes...>
300 template <
typename T>
301 struct type_list_has_duplicates_of<type_list<>, T> :
public etl::integral_constant<bool, false>
306 template <
typename TTypeList,
typename T>
307 inline constexpr bool type_list_has_duplicates_of_v = etl::type_list_has_duplicates_of<TTypeList, T>::value;
314 template <
typename TTypeList,
typename T>
315 struct type_list_count_of;
317 template <
typename T,
typename... TTypes>
318 struct type_list_count_of<etl::type_list<TTypes...>, T> :
public etl::count_of<T, TTypes...>
322 template <
typename T>
323 struct type_list_count_of<type_list<>, T> :
public etl::integral_constant<size_t, 0>
328 template <
typename TTypeList,
typename T>
329 inline constexpr size_t type_list_count_of_v = etl::type_list_count_of<TTypeList, T>::value;
336 template <
typename T>
337 struct type_list_max_size;
339 template <
typename... TTypes>
340 struct type_list_max_size<etl::type_list<TTypes...>> :
public etl::integral_constant<size_t, etl::largest<TTypes...>::size>
345 struct type_list_max_size<type_list<>> :
public etl::integral_constant<size_t, 0>
350 template <
typename TTypeList>
351 inline constexpr size_t type_list_max_size_v = etl::type_list_max_size<TTypeList>::value;
358 template <
typename T>
359 struct type_list_max_alignment;
361 template <
typename... TTypes>
362 struct type_list_max_alignment<etl::type_list<TTypes...>> :
public etl::integral_constant<size_t, etl::largest<TTypes...>::alignment>
367 struct type_list_max_alignment<type_list<>> :
public etl::integral_constant<size_t, 1>
372 template <
typename TTypeList>
373 inline constexpr size_t type_list_max_alignment_v = etl::type_list_max_alignment<TTypeList>::value;
380 template <
typename TTypeList,
size_t... Indices>
381 struct type_list_select
383 ETL_STATIC_ASSERT((etl::is_type_list<TTypeList>::value),
"TTypeList must be an etl::type_list");
385 using type = type_list<type_list_type_at_index_t<TTypeList, Indices>...>;
388 template <
typename TTypeList,
size_t... Indices>
389 using type_list_select_t =
typename type_list_select<TTypeList, Indices...>::type;
395 template <
typename TTypeList,
typename TIndexSequence>
396 struct type_list_select_from_index_sequence;
398 template <
typename TTypeList,
size_t... Indices>
399 struct type_list_select_from_index_sequence<TTypeList, etl::index_sequence<Indices...>>
401 using type = etl::type_list_select_t<TTypeList, Indices...>;
404 template <
typename TTypeList,
typename TIndexSequence>
405 using type_list_select_from_index_sequence_t =
typename type_list_select_from_index_sequence<TTypeList, TIndexSequence>::type;
410 template <
typename... TTypes>
411 struct type_list_cat;
413 template <
typename... TTypes1,
typename... TTypes2,
typename... TTail>
414 struct type_list_cat<etl::type_list<TTypes1...>, etl::type_list<TTypes2...>, TTail...>
416 using type =
typename type_list_cat<etl::type_list<TTypes1..., TTypes2...>, TTail...>::type;
419 template <
typename T>
420 struct type_list_cat<T>
425 template <
typename... TypeLists>
426 using type_list_cat_t =
typename type_list_cat<TypeLists...>::type;
431 template <
typename T,
typename... TTypes>
432 struct type_list_push_front;
434 template <
typename T,
typename... TTypes>
435 struct type_list_push_front<etl::type_list<TTypes...>, T>
437 using type = type_list<T, TTypes...>;
440 template <
typename TypeList,
typename T>
441 using type_list_push_front_t =
typename type_list_push_front<TypeList, T>::type;
446 template <
typename T,
typename... TTypes>
447 struct type_list_push_back;
449 template <
typename T,
typename... TTypes>
450 struct type_list_push_back<etl::type_list<TTypes...>, T>
452 using type = type_list<TTypes..., T>;
455 template <
typename TypeList,
typename T>
456 using type_list_push_back_t =
typename type_list_push_back<TypeList, T>::type;
463 template <
typename TTypeList,
typename T,
size_t Index>
464 struct type_list_insert
468 ETL_STATIC_ASSERT((etl::is_type_list<TTypeList>::value),
"TTypeList must be an etl::type_list");
469 ETL_STATIC_ASSERT(Index <= TTypeList::size,
"Index out of range");
471 using index_sequence_for_prefix = etl::make_index_sequence<Index>;
472 using index_sequence_for_suffix = etl::make_index_sequence_with_offset<Index, TTypeList::size - Index>;
474 using prefix = etl::type_list_select_from_index_sequence_t<TTypeList, index_sequence_for_prefix>;
475 using suffix = etl::type_list_select_from_index_sequence_t<TTypeList, index_sequence_for_suffix>;
481 using type = etl::type_list_cat_t<prefix, etl::type_list<T>, suffix>;
485 template <
typename TTypeList,
typename T,
size_t Index>
486 using type_list_insert_t =
typename etl::type_list_insert<TTypeList, T, Index>::type;
492 template <
typename TTypeList,
size_t Index>
493 struct type_list_remove
497 ETL_STATIC_ASSERT((etl::is_type_list<TTypeList>::value),
"TTypeList must be an etl::type_list");
498 ETL_STATIC_ASSERT(Index < TTypeList::size,
"Index out of range");
500 using index_sequence_for_prefix = etl::make_index_sequence<Index>;
501 using index_sequence_for_suffix = etl::make_index_sequence_with_offset<Index + 1, TTypeList::size - Index - 1>;
503 using prefix = etl::type_list_select_from_index_sequence_t<TTypeList, index_sequence_for_prefix>;
504 using suffix = etl::type_list_select_from_index_sequence_t<TTypeList, index_sequence_for_suffix>;
510 using type = etl::type_list_cat_t<prefix, suffix>;
514 template <
typename TTypeList,
size_t Index>
515 using type_list_remove_t =
typename etl::type_list_remove<TTypeList, Index>::type;
521 namespace private_type_list
523 template <
typename TTypeList,
template <
typename>
class TPredicate>
524 struct type_list_remove_if_impl;
526 template <
template <
typename>
class TPredicate>
527 struct type_list_remove_if_impl<etl::type_list<>, TPredicate>
529 using type = etl::type_list<>;
532 template <
typename Head,
typename... Tail,
template <
typename>
class TPredicate>
533 struct type_list_remove_if_impl<etl::type_list<Head, Tail...>, TPredicate>
537 using rest =
typename type_list_remove_if_impl<etl::type_list<Tail...>, TPredicate>::type;
541 using type =
typename etl::conditional< TPredicate<Head>::value, rest, etl::type_list_push_front_t<rest, Head>>::type;
550 template <
typename TTypeList,
template <
typename>
class TPredicate>
551 struct type_list_remove_if
555 ETL_STATIC_ASSERT((etl::is_type_list<TTypeList>::value),
"TTypeList must be an etl::type_list");
559 using type =
typename private_type_list::type_list_remove_if_impl<TTypeList, TPredicate>::type;
563 template <
typename TTypeList,
template <
typename>
class TPredicate>
564 using type_list_remove_if_t =
typename etl::type_list_remove_if<TTypeList, TPredicate>::type;
570 template <
typename TTypeList>
571 struct type_list_pop_front
575 ETL_STATIC_ASSERT((etl::is_type_list<TTypeList>::value),
"TTypeList must be an etl::type_list");
576 ETL_STATIC_ASSERT(TTypeList::size > 0U,
"Cannot pop_front from an empty type_list");
580 using type =
typename TTypeList::tail;
584 template <
typename TTypeList>
585 using type_list_pop_front_t =
typename etl::type_list_pop_front<TTypeList>::type;
591 template <
typename TTypeList>
592 struct type_list_pop_back
596 ETL_STATIC_ASSERT((etl::is_type_list<TTypeList>::value),
"TTypeList must be an etl::type_list");
597 ETL_STATIC_ASSERT(TTypeList::size > 0U,
"Cannot pop_back from an empty type_list");
601 using type =
typename etl::type_list_remove<TTypeList, TTypeList::size - 1U>::type;
605 template <
typename TTypeList>
606 using type_list_pop_back_t =
typename etl::type_list_pop_back<TTypeList>::type;
612 namespace private_type_list
614 template <
typename TTypeList,
typename TResult>
615 struct type_list_unique_impl;
618 template <
typename TResult>
619 struct type_list_unique_impl<etl::type_list<>, TResult>
621 using type = TResult;
626 template <
typename Head,
typename... Tail,
typename TResult>
627 struct type_list_unique_impl<etl::type_list<Head, Tail...>, TResult>
631 using next_result = etl::conditional_t<etl::type_list_contains<TResult, Head>::value, TResult, etl::type_list_push_back_t<TResult, Head>>;
635 using type =
typename type_list_unique_impl<etl::type_list<Tail...>, next_result>::type;
643 template <
typename TTypeList>
644 struct type_list_unique
646 ETL_STATIC_ASSERT((etl::is_type_list<TTypeList>::value),
"TTypeList must be an etl::type_list");
648 using type =
typename private_type_list::type_list_unique_impl<TTypeList, etl::type_list<>>::type;
652 template <
typename TTypeList>
653 using type_list_unique_t =
typename etl::type_list_unique<TTypeList>::type;
659 template <
typename TTypeList>
660 struct type_list_is_unique
664 : etl::bool_constant< etl::is_same< TTypeList, typename type_list_unique<TTypeList>::type>::value>
666 ETL_STATIC_ASSERT((etl::is_type_list<TTypeList>::value),
"TTypeList must be an etl::type_list");
670 template <
typename TTypeList>
671 inline constexpr bool type_list_is_unique_v = etl::type_list_is_unique<TTypeList>::value;
677 template <
typename T>
678 struct type_list_is_empty;
681 struct type_list_is_empty<etl::type_list<>> : etl::true_type
685 template <
typename... TTypes>
691 template <
typename... TTypes>
692 inline constexpr bool type_list_is_empty_v = type_list_is_empty<TTypes...>::value;
700 template <
typename TTypeList,
template <
typename>
class TPredicate>
701 struct type_list_all_of;
703 template <
template <
typename>
class TPredicate,
typename... TTypes>
704 struct type_list_all_of<etl::type_list<TTypes...>, TPredicate> : etl::conjunction<TPredicate<TTypes>...>
708 template <
template <
typename>
class TPredicate>
709 struct type_list_all_of<etl::type_list<>, TPredicate> : etl::bool_constant<true>
714 template <
typename TTypeList,
template <
typename>
class TPredicate>
715 inline constexpr bool type_list_all_of_v = type_list_all_of<TTypeList, TPredicate>::value;
723 template <
typename TTypeList,
template <
typename>
class TPredicate>
724 struct type_list_any_of;
726 template <
template <
typename>
class TPredicate,
typename... TTypes>
727 struct type_list_any_of<etl::type_list<TTypes...>, TPredicate> : etl::disjunction<TPredicate<TTypes>...>
731 template <
template <
typename>
class TPredicate>
732 struct type_list_any_of<etl::type_list<>, TPredicate> : etl::bool_constant<false>
737 template <
typename TTypeList,
template <
typename>
class TPredicate>
738 inline constexpr bool type_list_any_of_v = type_list_any_of<TTypeList, TPredicate>::value;
746 template <
typename TTypeList,
template <
typename>
class TPredicate>
747 struct type_list_none_of;
749 template <
template <
typename>
class TPredicate,
typename... TTypes>
750 struct type_list_none_of<etl::type_list<TTypes...>, TPredicate> : etl::negation<etl::disjunction<TPredicate<TTypes>...>>
754 template <
template <
typename>
class TPredicate>
755 struct type_list_none_of<etl::type_list<>, TPredicate> : etl::bool_constant<true>
760 template <
typename TTypeList,
template <
typename>
class TPredicate>
761 inline constexpr bool type_list_none_of_v = type_list_none_of<TTypeList, TPredicate>::value;
769 template <
typename TFromList,
typename TToList>
770 struct type_lists_are_convertible;
774 struct type_lists_are_convertible<etl::type_list<>, etl::type_list<>> :
public etl::true_type
779 template <
typename TFromHead,
typename... TFromTail,
typename TToHead,
typename... TToTail>
780 struct type_lists_are_convertible<etl::type_list<TFromHead, TFromTail...>, etl::type_list<TToHead, TToTail...>>
781 :
public etl::bool_constant< etl::is_convertible<TFromHead, TToHead>::value
782 && etl::type_lists_are_convertible< etl::type_list<TFromTail...>, etl::type_list<TToTail...>>::value>
784 static_assert(
sizeof...(TFromTail) ==
sizeof...(TToTail),
"Type lists are not the same length");
788 template <
typename TFromList,
typename TToList>
789 inline constexpr bool type_lists_are_convertible_v = etl::type_lists_are_convertible<TFromList, TToList>::value;
792 namespace private_type_list
795 template <
typename TTypeList,
template <
typename,
typename>
class TCompare>
796 struct type_list_is_sorted_impl;
800 template <
template <
typename,
typename>
class TCompare>
801 struct type_list_is_sorted_impl<etl::type_list<>, TCompare> : etl::true_type
807 template <
typename T0,
template <
typename,
typename>
class TCompare>
808 struct type_list_is_sorted_impl<etl::type_list<T0>, TCompare> : etl::true_type
816 template <
typename Head,
typename Next,
typename... Tail,
template <
typename,
typename>
class TCompare>
817 struct type_list_is_sorted_impl<etl::type_list<Head, Next, Tail...>, TCompare>
818 : etl::bool_constant< !TCompare<Next, Head>::value && type_list_is_sorted_impl< etl::type_list<Next, Tail...>, TCompare>::value>
829 template <
typename TTypeList,
template <
typename,
typename>
class TCompare>
830 struct type_list_is_sorted :
public private_type_list::type_list_is_sorted_impl<TTypeList, TCompare>
832 ETL_STATIC_ASSERT((etl::is_type_list<TTypeList>::value),
"TTypeList must be an etl::type_list");
836 template <
typename TTypeList,
template <
typename,
typename>
class TCompare>
837 inline constexpr bool type_list_is_sorted_v = etl::type_list_is_sorted<TTypeList, TCompare>::value;
841 namespace private_type_list
844 template <
bool InsertBefore,
typename Head,
typename T,
template <
typename,
typename>
class TCompare,
typename... Tail>
845 struct insert_sorted_impl;
848 template <
typename TSortedList,
typename T,
template <
typename,
typename>
class TCompare>
849 struct type_list_insert_sorted_impl;
854 template <
typename T,
template <
typename,
typename>
class TCompare>
855 struct type_list_insert_sorted_impl<etl::type_list<>, T, TCompare>
857 using type = etl::type_list<T>;
863 template <
typename Head,
typename... Tail,
typename T,
template <
typename,
typename>
class TCompare>
864 struct type_list_insert_sorted_impl<etl::type_list<Head, Tail...>, T, TCompare>
866 using type =
typename insert_sorted_impl<TCompare<T, Head>::value, Head, T, TCompare, Tail...>::type;
871 template <
typename Head,
typename T,
template <
typename,
typename>
class TCompare,
typename... Tail>
872 struct insert_sorted_impl<true, Head, T, TCompare, Tail...>
874 using type = etl::type_list<T, Head, Tail...>;
880 template <
typename Head,
typename T,
template <
typename,
typename>
class TCompare,
typename... Tail>
881 struct insert_sorted_impl<false, Head, T, TCompare, Tail...>
883 using type = etl::type_list_push_front_t<
typename type_list_insert_sorted_impl<etl::type_list<Tail...>, T, TCompare>::type, Head>;
893 template <
typename TTypeList,
typename T,
template <
typename,
typename>
class TCompare>
894 struct type_list_insert_sorted :
public private_type_list::type_list_insert_sorted_impl<TTypeList, T, TCompare>
896 ETL_STATIC_ASSERT((etl::is_type_list<TTypeList>::value),
"TTypeList must be an etl::type_list");
897 ETL_STATIC_ASSERT((etl::type_list_is_sorted<TTypeList, TCompare>::value),
"Cannot insert into a non-sorted type list");
901 template <
typename TTypeList,
typename T,
template <
typename,
typename>
class TCompare>
902 using type_list_insert_sorted_t =
typename etl::type_list_insert_sorted<TTypeList, T, TCompare>::type;
906 namespace private_type_list
910 template <
typename TTypeList,
template <
typename,
typename>
class TCompare>
911 struct type_list_sort_impl;
915 template <
template <
typename,
typename>
class TCompare>
916 struct type_list_sort_impl<etl::type_list<>, TCompare>
918 using type = etl::type_list<>;
923 template <
typename T0,
template <
typename,
typename>
class TCompare>
924 struct type_list_sort_impl<etl::type_list<T0>, TCompare>
926 using type = etl::type_list<T0>;
931 template <
typename Head,
typename... Tail,
template <
typename,
typename>
class TCompare>
932 struct type_list_sort_impl<etl::type_list<Head, Tail...>, TCompare>
936 using sorted_tail =
typename type_list_sort_impl<etl::type_list<Tail...>, TCompare>::type;
940 using type =
typename etl::type_list_insert_sorted<sorted_tail, Head, TCompare>::type;
949 template <
typename TTypeList,
template <
typename,
typename>
class TCompare>
950 struct type_list_sort :
public private_type_list::type_list_sort_impl<TTypeList, TCompare>
952 ETL_STATIC_ASSERT((etl::is_type_list<TTypeList>::value),
"TTypeList must be an etl::type_list");
956 template <
typename TTypeList,
template <
typename,
typename>
class TCompare>
957 using type_list_sort_t =
typename etl::type_list_sort<TTypeList, TCompare>::type;
bitset_ext
Definition absolute.h:40
integral_constant< bool, false > false_type
integral_constant specialisations
Definition type_traits.h:80
ETL_CONSTEXPR TContainer::size_type size(const TContainer &container)
Definition iterator.h:1192