From 5bfb9530acbc15f87e621fad24a257784dea40ca Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 13 Jun 2026 11:33:51 +0100 Subject: [PATCH 1/3] New metafunctions for type_list --- docs/types/type-list.md | 785 ++++++++++++++++++++++++++++++++++++---- include/etl/type_list.h | 292 ++++++++++++++- test/test_type_list.cpp | 352 +++++++++++++++++- 3 files changed, 1338 insertions(+), 91 deletions(-) diff --git a/docs/types/type-list.md b/docs/types/type-list.md index ad3fdd75..1a15db2c 100644 --- a/docs/types/type-list.md +++ b/docs/types/type-list.md @@ -4,114 +4,773 @@ title: "type_list" {{< callout type="info">}} Header: `type_list.h` - From: `20.39.5` + Since: `20.39.5` + From: `C++11` {{< /callout >}} -Defines a tuple of types, but unlike a tuple, does not contain any values. -This is an empty class. -Valid for C++11 and above. - ## type_list +```cpp +template > +struct type_list +``` +**Description** +Defines a tuple of types, but unlike a tuple, does not contain any values. +Also defines a range of compile time algorithms for use with `etl::type_list` template meta-programming. +Valid for C++11 and above, except where specifically noted. + +## is_type_list +```cpp +template +struct is_type_list +``` +**Description** +Check if a type is an `etl::type_list`. + +**Return** +`etl::true_type` if `T` is an `etl::type_list`, otherwise `etl::false_type`. + +--- ```cpp -etl::type_select +template +constexpr bool is_type_list_v ``` -Creates a tuple of types from a set of template type parameters. +**Return** +`true` if `T` is an `etl::type_list`, otherwise `false`. +From: `C++17` -### Member types -index_sequence_type -The index_sequence type for this type_list. +## type_list_size +```cpp +template +struct type_list_size +``` +**Description** +'value' is defined as the number of types in the `type_list`. -### Type list creation -**Using global types** +--- + +```cpp +template +constexpr size_t type_list_size_v +``` +Defined as the number of types in the `type_list`. +From: C++17 + +## type_list_type_at_index +```cpp +template +struct type_list_type_at_index +``` +**Description** +Defines `type` as the type found at `Index` in the `type_list`. +Static asserts if `Index` is out of range. + +--- + +```cpp +template +type_list_type_at_index_t +``` +**Description** +Defined as the type found at `Index` in the `type_list`. +Static asserts if `Index` is out of range. + +## type_list_index_of_type +```cpp +template +struct type_list_index_of_type +``` +**Description** +Defines an integral constant `value` that is the index of the *first* instance of `T` in the `type_list`. +If the type is not in the `type_list`, then defined as `etl::type_list_npos`. +Useful for type lists that do not contain duplicates, otherwise use `type_list_indices_of_type`. +Static asserts if `TTypeList` is not an `etl::type_list`. + +--- + +```cpp +template +constexpr size_t type_list_index_of_type_v +``` +**Description** +`value` is defined as the index of the type. +From: `C++17` + +## type_list_indices_of_type +```cpp +template +struct type_list_indices_of_type +``` +**Description** +Defines an `index_sequence` of indices where `T` appears in the `type_list`. +If the type is not in the `type_list`, then defined as an empty `index_sequence`. +Useful for type lists that contain duplicates, otherwise use `type_list_index_of_type`. +Static asserts if `TTypeList` is not an `etl::type_list`. + +--- + +```cpp +template +type_list_indices_of_type_t +``` +**Description** +Defined as `index_sequence` of indices where `T` appears in the `type_list`. +If the type is not in the `type_list`, then defined as an empty `index_sequence`. +Useful for type lists that contain duplicates, otherwise use `type_list_index_of_type`. +Static asserts if `TTypeList` is not an `etl::type_list`. + +## type_list_contains +```cpp +template +struct type_list_contains +``` +**Description** +Defines `value` as `true` if the `type_list` contains the specified type, otherwise `false`. +From: `C++17` + +--- + +```cpp +template +constexpr bool type_list_contains_v +``` +**Description** +Defined as `true` if the `type_list` contains the specified type, otherwise `false`. + +## type_list_has_duplicates_of +```cpp +template +struct type_list_has_duplicates_of +``` +**Description** +Defines `value` as `true` if the `type_list` has duplicates of the specified type, otherwise `false`. + +--- + +```cpp +template +constexpr bool type_list_has_duplicates_of_v +``` +Defined as `true` if the `type_list` has duplicates of the specified type, otherwise `false`. +From: `C++17` + +## type_list_count_of +```cpp +template +struct type_list_count_of +``` +**Description** +Defines `value` that is the count of the number of times a type is in the `type_list`. + +--- + +```cpp +template +constexpr size_t type_list_count_of_v +``` +**Description** +Defined as the count of the number of times a type is in the `type_list`. +From: `C++17` + +## type_list_max_size +```cpp +template +struct type_list_max_size; +``` +**Description** +Defines `value` that is the maximum `sizeof` all types in the `type_list`. +If the `type_list` is empty, then defined as `0`. + +--- + +```cpp +template +constexpr size_t type_list_max_size_v +``` +**Description** +Defined as the maximum `sizeof` all types in the `type_list`. +If the `type_list` is empty, then defined as `0`. +From: `C++17` + +## type_list_max_alignment +```cpp +template +struct type_list_max_alignment +``` +**Description** +Defines `value` as the maximum alignment all types in the `type_list`. +If the `type_list` is empty, then defined as `1`. + +--- + +```cpp +template +constexpr size_t type_list_max_alignment_v +``` +Defined as the maximum alignment all types in the `type_list`. +If the `type_list` is empty, then defined as `1`. +From: `C++17` + +## type_list_select +```cpp +template +struct type_list_select +``` +**Description** +Selects types from a given `type_list`, according to a list if indices. +Defines `type` as the modified `type_list`. + +--- ```cpp template -type_list_select +type_list_select_t ``` -Defines a new type_list by selecting types from a given type_list, according to an index sequence. +**Description** +Selects types from a given `type_list`, according to a list if indices. +Defined as the modified `type_list`. + +## type_list_select_from_indexes +```cpp +template +struct type_list_select_from_index_sequence +``` +**Description** +Defines a modified `type_list` by selecting types from a given `type_list`, according to an index sequence. +Defines `type` as the modified `type_list`. --- ```cpp -template -type_list_cat +template +type_list_select_from_index_sequence_t ``` -Defines a new type list by concatenating a list of `etl::type_list` objects. -`std::tuple` style access. - -## Type list properties - -### Using member types +## type_list_select_common_types ```cpp -static constexpr size_t size(); +template +struct type_list_select_common_types ``` -Returns the number of types in the type list. - -### Using global types - -```cpp -template -type_list_size -``` -Defines value as the size of the type list. -tuple style access. - -```cpp -template -type_list_size_v -``` -C++17 and above. +**Description** +Defines `type` as a modified `type_list` of all of the types that are common to all of the `type_lists`. +A type is included in the result if it is present in every `type_list`. +*The result contains no duplicates*. --- ```cpp -etl::nth_type +template +type_list_select_common_types_t ``` -Defines the nth type in the type list. +**Description** +Defined as a modified `type_list` of all of the types that are common to all of the `type_lists`. +A type is included in the result if it is present in every `type_list`. +*The result contains no duplicates*. + +## type_list_select_not_common_types + +```cpp + template + struct type_list_select_not_common_types +``` +**Description** +Defines `type` as a modified `type_list` of all of the types that are not common to all of the `type_lists`. +A type is included in the result if it is not present in every `type_list`. +*The result contains no duplicates*. + +--- + +```cpp +template +type_list_select_not_common_types_t +``` +**Description** +Defined as modified `type_list` of all of the types that are not common to all of the `type_lists`. +A type is included in the result if it is not present in every `type_list`. +*The result contains no duplicates*. + +## type_list_cat +```cpp +template +struct type_list_cat +``` +**Description** +Defines `type` as the concatenation of two or more `type_lists`. +*Does not remove duplicates.* + +--- + +```cpp +template +type_list_cat_t +``` +**Description** +Defined as the concatenation of two or more `type_lists`. +*Does not remove duplicates.* + +## type_list_cat_unique +```cpp +template +struct type_list_cat_unique +``` +**Description** +Defines `type` as the concatenation of two or more `type_lists`. +*Removes duplicates*. + +```cpp +template +type_list_cat_unique_t +``` +**Description** +Defined as the concatenation of two or more `type_lists`. +*Removes duplicates*. + +## type_list_push_front +```cpp +template +struct type_list_push_front +``` +**Description** +Add a type to the beginning of a `type_list`. +Defines `type` as the modified `type_list`. + +--- + +```cpp +template +type_list_push_front_t +``` +**Description** +Add a type to the beginning of a `type_list`. +Defined as the modified `type_list`. + +## type_list_pop_front +```cpp +template +struct type_list_pop_front +``` +**Description** +Removes the first type from a `type_list`. +Defines `type` as the modified `type_list`. + +--- + +```cpp +template +type_list_pop_front_t +``` +**Description** +Removes the first type from a `type_list`. +Defined as the modified `type_list`. + +## type_list_push_back +```cpp +template +struct type_list_push_back +``` +**Description** +Add a type to the end of a `type_list`. +Defines `type` as the modified `type_list`. + +--- + +```cpp +template +type_list_push_back_t +``` +**Description** +Add a type to the end of a `type_list`. +Defined as the modified `type_list`. + +## type_list_pop_back +```cpp +template +struct type_list_pop_back +``` +**Description** +Removes the last type from a `type_list`. +Defines `type` as the modified `type_list`. + +--- + +```cpp +template +type_list_pop_back_t +``` +**Description** +Removes the last type from a `type_list`. +Defined as the modified `type_list`. + +## type_list_insert +```cpp +template +struct type_list_insert +``` +**Description** +Insert a type at an index in a `type_list`. +Inserts before the type currently at Index. +If `Index` == size of the `type_list`, the type is appended. +Defines `type` as the modified `type_list`. + +--- + +```cpp +template +type_list_insert_t +``` +**Description** +Insert a type at an index in a `type_list`. +Inserts before the type currently at Index. +If `Index` == size of the `type_list`, the type is appended. +Defined as the modified `type_list` + +## type_list_remove +```cpp +template +struct type_list_remove +``` +**Description** +Remove a type at an index in a `type_list`. +Defines `type` as the modified `type_list`. + +--- + +```cpp +template +type_list_remove_t +``` +**Description** +Remove a type at an index in a `type_list`. +Defined as the modified `type_list` + +## type_list_remove_if +```cpp +template class TPredicate> +struct type_list_remove_if +``` +**Description** +Remove types that satisfy a predicate from a `type_list`. +Predicate must be: `template struct Pred : etl::bool_constant<...> {};` +Defines `type` as the modified `type_list`. + +--- + +```cpp +template class TPredicate> +type_list_remove_if_t +``` +**Description** +Remove types that satisfy a predicate from a `type_list`. +Predicate must be: `template struct Pred : etl::bool_constant<...> {};` +Defined as the modified `type_list` + +## type_list_unique +```cpp +template +struct type_list_unique +``` +**Description** +Removes duplicate types from a given `type_list`, preserving the first occurrence. +Defines `type` as the modified `type_list`. + +--- + +```cpp +template +type_list_unique_t +``` +**Description** +Removes duplicate types from a given `type_list`, preserving the first occurrence. +Defined as the modified `type_list` + +## type_list_is_unique +```cpp +template +struct type_list_is_unique +``` +**Description** +Checks that all of the types in a `type_list` are unique. +Inherits from `etl::true_type` or `etl::false_type`. + +--- + +```cpp +template +constexpr bool type_list_is_unique_v +``` +**Description** +Checks that all of the types in a `type_list` are unique. +Defined as `true` or `false`. +From: `C++17` + +## type_list_is_empty +```cpp +template +struct type_list_is_empty +``` +**Description** +Checks if the `type_list` is empty. +Inherits from `etl::true_type` or `etl::false_type`. + +--- + +```cpp +template +constexpr bool type_list_is_empty_v +``` +**Description** +Checks if the `type_list` is empty. +Defined as `true` or `false`. +From: `C++17` + +## type_list_all_of +```cpp +template class TPredicate> +struct type_list_all_of; +``` +**Description** +Checks that all types in a `type_list` satisfy a unary predicate. +Predicate must be: `template struct Pred : etl::bool_constant<...> {};` +Inherits from `etl::true_type` or `etl::false_type`. + +--- + +```cpp +template class TPredicate> +constexpr bool type_list_all_of_v +``` +**Description** +Checks that all types in a `type_list` satisfy a unary predicate. +Predicate must be: `template struct Pred : etl::bool_constant<...> {};` +Defined `true` or `false`. +From: `C++17` + +## type_list_any_of +```cpp +template class TPredicate> +struct type_list_any_of +``` +**Description** +Checks that any type in a `type_list` satisfies a unary predicate. +Predicate must be: `template struct Pred : etl::bool_constant<...> {};` +Inherits from `etl::true_type` or `etl::false_type`. + +--- + +```cpp +template class TPredicate> +constexpr bool type_list_any_of_v +``` +**Description** +Checks that any type in a `type_list` satisfies a unary predicate. +Predicate must be: `template struct Pred : etl::bool_constant<...> {};` +Defined as `true` or `false`. +From: `C++17` + +## type_list_none_of +```cpp +template class TPredicate> +struct type_list_none_of +``` +**Description** +Checks that no types in a `type_list` satisfy a unary predicate. +Predicate must be: `template struct Pred : etl::bool_constant<...> {};` +Inherits from `etl::true_type` or `etl::false_type`. + +--- + +```cpp +template class TPredicate> +constexpr bool type_list_none_of_v +``` +**Description** +Checks that no types in a `type_list` satisfy a unary predicate. +Predicate must be: `template struct Pred : etl::bool_constant<...> {};` +Defined` as `true` or `false`. +From: `C++17` + +## type_lists_are_convertible +```cpp +template +struct type_lists_are_convertible +``` +**Description** +Checks that two type lists are convertible. +Static asserts if the type lists are not the same length. +Inherits from `etl::true_type` or `etl::false_type`. --- ```cpp template -type_lists_are_convertible +constexpr bool type_lists_are_convertible_v ``` -Checks that types in a type_list are convertible to the type in another. -Defines value as `true` or `false`. -From: `20.43.0` +**Description** +Checks that two type lists are convertible. +Static asserts if the type lists are not the same length. +Defined as `true` or `false`. +From: `C++17` + +## type_list_is_sorted +```cpp + template class TCompare> + struct type_list_is_sorted +``` +**Description** +Checks if a `type_list` is sorted according to `TCompare`. +Static asserts if `TTypeList` is not an `etl::type_list`. +Comparator must be: template struct Compare : etl::bool_constant<...> {}; +Inherits from `etl::true_type` or `etl::false_type`. --- ```cpp -template -type_lists_are_convertible_v +template class TCompare> +constexpr bool type_list_is_sorted_v ``` -C++17 and above. -From: `20.43.0` +**Description** +Checks if a `type_list` is sorted according to `TCompare`. +Static asserts if `TTypeList` is not an `etl::type_list`. +Comparator must be: template struct Compare : etl::bool_constant<...> {}; +Defined as `true` or `false`. +From: `C++17` -## Examples +## type_list_insert_sorted +```cpp +template class TCompare> +struct type_list_insert_sorted +``` +**Description** +Insert `T` into the correct position in the sorted list, as determined by `TCompare`. +Static asserts if `TTypeList` is not sorted according to `TCompare`. +Comparator must be: `template struct Compare : etl::bool_constant<...> {};` +Defines `type` as the modified `type_list`. + +--- ```cpp -using TypeList1 = etl::type_list -using TypeList2 = etl::type_list -using TypeList3 = etl::type_list +template class TCompare> +type_list_insert_sorted_t ``` +**Description** +Insert `T` into the correct position in the sorted list, as determined by `TCompare`. +Static asserts if `TTypeList` is not sorted according to `TCompare`. +Comparator must be: `template struct Compare : etl::bool_constant<...> {};` +Defined as the modified `type_list`. -### Using member types +## type_list_sort +```cpp +template class TCompare> +struct type_list_sort +``` +**Description** +`etl::type_list` sorting by a user supplied type comparator. +Comparator must be: `template struct Compare : etl::bool_constant<...> {};` +Defines `type` as the modified `type_list`. + +--- ```cpp -// Get the size of TypeList1 -constexpr size_t typeList1Size = TypeList1::size(); +template class TCompare> +type_list_sort_t ``` +**Description** +`etl::type_list` sorting by a user supplied type comparator. +Comparator must be: `template struct Compare : etl::bool_constant<...> {};` +Defined as the modified `type_list`. -### Using tuple style global types +## type_list_in_all_lists +```cpp +template +struct type_list_in_all_lists +``` +**Description** +Checks if a type `T` is present in all provided `type_lists`. +Inherits from `etl::true_type` if `T` is in every list, otherwise `etl::false_type`. +Since: `20.48.0` ```cpp -// Get the size of TypeList1 -constexpr size_t typeList1Size = etl::type_list_size_v; - -// Define the type list -// etl::type_list -using Concatenated = etl::type_list_cat +template +constexpr bool type_list_in_all_lists_v ``` +**Description** +Checks if a type `T` is present in all provided `type_lists`. +Defined as `true` if `T` is in every list, otherwise `false`. +Since: `20.48.0` +From: `C++17` + +## type_list_in_any_list +```cpp +template +struct type_list_in_any_list +``` +**Description** +Checks if a type `T` is present in at least one of the provided `type_lists`. +Inherits from `etl::true_type` if `T` is in any list, otherwise `etl::false_type`. +Since: `20.48.0` + +--- + +```cpp +template +constexpr bool type_list_in_any_list_v +``` +**Description** +Checks if a type `T` is present in at least one of the provided `type_lists`. +Defined as `true` if `T` is in any list, otherwise `false`. +Since: `20.48.0` +From: `C++17` + +## type_list_in_no_lists + +```cpp +template +struct type_list_in_no_lists +``` +**Description** +Checks if a type `T` is present in at least one of the provided `type_lists`. +Inherits from `etl::true_type` if `T` is in any list, otherwise `etl::false_type`. +Since: `20.48.0` + +--- + +```cpp +template +constexpr bool type_list_in_no_list_v +``` +**Description** +Checks if a type `T` is present in at least one of the provided `type_lists`. +Defined as `true` if `T` is in any list, otherwise `false`. +Since: `20.48.0` +From: `C++17` + +## type_list_remove_from +```cpp +template +struct type_list_remove_from +``` +**Description** +Defines a modified `type_list` that contains the types in the first list that are not in any of the following lists. +*Does not remove duplicates*. +`type` is defined as the modified `type_list`. + +--- + +```cpp +template +type_list_remove_from_t +``` +**Description** +Defines a modified `type_list` that contains the types in the first list that are not in any of the following lists. +*Does not remove duplicates*. +Defined as the modified `type_list`. \ No newline at end of file diff --git a/include/etl/type_list.h b/include/etl/type_list.h index 3c860f9c..21d6b587 100644 --- a/include/etl/type_list.h +++ b/include/etl/type_list.h @@ -209,7 +209,7 @@ namespace etl #if ETL_USING_CPP17 template - inline constexpr size_t type_list_index_of_v = etl::type_list_index_of_type::value; + inline constexpr size_t type_list_index_of_type_v = etl::type_list_index_of_type::value; #endif //*************************************************************************** @@ -271,12 +271,12 @@ namespace etl struct type_list_contains; template - struct type_list_contains, T> : public etl::integral_constant::value> + struct type_list_contains, T> : public etl::is_one_of { }; template - struct type_list_contains, T> : public etl::integral_constant + struct type_list_contains, T> : public etl::bool_constant { }; @@ -388,6 +388,12 @@ namespace etl template using type_list_select_t = typename type_list_select::type; + template + using type_list_select_from_indexes = type_list_select; + + template + using type_list_select_from_indexes_t = typename type_list_select::type; + //*************************************************************************** /// Declares a new type_list by selecting types from a given type_list, /// according to an index sequence. @@ -410,6 +416,8 @@ namespace etl template struct type_list_cat; + // The general case, concatenate the first two type_lists, then recurse with + // the result and the rest of the type_lists. template struct type_list_cat, etl::type_list, TTail...> { @@ -422,6 +430,12 @@ namespace etl using type = T; }; + template <> + struct type_list_cat<> + { + using type = etl::type_list<>; + }; + template using type_list_cat_t = typename type_list_cat::type; @@ -705,11 +719,6 @@ namespace etl { }; - template