Merge e633327c093de66f125afe9ef2632bd5b7d0fbfb into 20cab3225691a9782f422ad1ad132f3f8ce5cf8a

This commit is contained in:
John Wellbelove 2026-06-14 08:33:43 +00:00 committed by GitHub
commit 36993c04ba
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 1328 additions and 93 deletions

View File

@ -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 <typename... Typelists>
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 <typename T>
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<typename... TTypes>
template <typename T>
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 <typename TTypes>
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 <typename... TTypes>
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 <typename TTypeList, size_t Index>
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 <typename TTypeList, size_t Index>
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 <typename TTypeList, typename T>
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 <typename TTypeList, typename T>
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 <typename TTypeList, typename T>
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 <typename TTypeList, typename T>
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 <typename TTypeList, typename T>
struct type_list_contains
```
**Description**
Defines `value` as `true` if the `type_list` contains the specified type, otherwise `false`.
From: `C++17`
---
```cpp
template <typename TTypeList, typename T>
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 <typename TTypeList, typename T>
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 <typename TTypeList, typename T>
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 <typename TTypeList, typename T>
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 <typename TTypeList, typename T>
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 <typename T>
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 <typename TTypeList>
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 <typename T>
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 <typename TTypeList>
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 <typename TTypeList, size_t... Indices>
struct type_list_select
```
**Description**
Selects types from a given `type_list`, according to a list of indices.
Defines `type` as the modified `type_list`.
---
```cpp
template <typename TTypeList, size_t... Indices>
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 of indices.
Defined as the modified `type_list`.
## type_list_select_from_indexes
```cpp
template <typename TTypeList, size_t... Indices>
type_list_select_from_indexes
```
**Description**
`type_list_select_from_indexes` is an alias of `type_list_select` to be more consistent with the naming of other type_list metafunctions.
Selects types from a given `type_list`, according to a list of indices.
Defines `type` as the modified `type_list`.
## type_list_select_from_index_sequence
```cpp
template <typename TTypeList, typename TIndexSequence>
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 <typename... TTypeLists>
type_list_cat
template <typename TTypeList, typename TIndexSequence>
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 <typename... TypeLists>
struct type_list_select_common_types
```
Returns the number of types in the type list.
### Using global types
```cpp
template <typename TTypelist>
type_list_size
```
Defines value as the size of the type list.
tuple style access.
```cpp
template <typename TTypelist>
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<size_t N, typename TTypeList>
template <typename... TypeLists>
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 <typename... TypeLists>
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 <typename... TypeLists>
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 <typename... TTypes>
struct type_list_cat
```
**Description**
Defines `type` as the concatenation of two or more `type_lists`.
*Does not remove duplicates.*
---
```cpp
template <typename... TypeLists>
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 <typename... TypeLists>
struct type_list_cat_unique
```
**Description**
Defines `type` as the concatenation of two or more `type_lists`.
*Removes duplicates*.
```cpp
template <typename... TypeLists>
type_list_cat_unique_t
```
**Description**
Defined as the concatenation of two or more `type_lists`.
*Removes duplicates*.
## type_list_push_front
```cpp
template <typename T, typename... TTypes>
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 <typename TypeList, typename T>
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 <typename TTypeList>
struct type_list_pop_front
```
**Description**
Removes the first type from a `type_list`.
Defines `type` as the modified `type_list`.
---
```cpp
template <typename TTypeList>
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 <typename T, typename... TTypes>
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 <typename TypeList, typename T>
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 <typename TTypeList>
struct type_list_pop_back
```
**Description**
Removes the last type from a `type_list`.
Defines `type` as the modified `type_list`.
---
```cpp
template <typename TTypeList>
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 <typename TTypeList, typename T, size_t Index>
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 <typename TTypeList, typename T, size_t Index>
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 <typename TTypeList, size_t Index>
struct type_list_remove
```
**Description**
Remove a type at an index in a `type_list`.
Defines `type` as the modified `type_list`.
---
```cpp
template <typename TTypeList, size_t Index>
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 <typename TTypeList, template <typename> class TPredicate>
struct type_list_remove_if
```
**Description**
Remove types that satisfy a predicate from a `type_list`.
Predicate must be: `template <typename T> struct Pred : etl::bool_constant<...> {};`
Defines `type` as the modified `type_list`.
---
```cpp
template <typename TTypeList, template <typename> class TPredicate>
type_list_remove_if_t
```
**Description**
Remove types that satisfy a predicate from a `type_list`.
Predicate must be: `template <typename T> struct Pred : etl::bool_constant<...> {};`
Defined as the modified `type_list`
## type_list_unique
```cpp
template <typename TTypeList>
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 <typename TTypeList>
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 <typename TTypeList>
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 <typename TTypeList>
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 <typename T>
struct type_list_is_empty
```
**Description**
Checks if the `type_list` is empty.
Inherits from `etl::true_type` or `etl::false_type`.
---
```cpp
template <typename... TTypes>
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 <typename TTypeList, template <typename> class TPredicate>
struct type_list_all_of;
```
**Description**
Checks that all types in a `type_list` satisfy a unary predicate.
Predicate must be: `template <typename T> struct Pred : etl::bool_constant<...> {};`
Inherits from `etl::true_type` or `etl::false_type`.
---
```cpp
template <typename TTypeList, template <typename> 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 <typename T> struct Pred : etl::bool_constant<...> {};`
Defined `true` or `false`.
From: `C++17`
## type_list_any_of
```cpp
template <typename TTypeList, template <typename> class TPredicate>
struct type_list_any_of
```
**Description**
Checks that any type in a `type_list` satisfies a unary predicate.
Predicate must be: `template <typename T> struct Pred : etl::bool_constant<...> {};`
Inherits from `etl::true_type` or `etl::false_type`.
---
```cpp
template <typename TTypeList, template <typename> 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 <typename T> struct Pred : etl::bool_constant<...> {};`
Defined as `true` or `false`.
From: `C++17`
## type_list_none_of
```cpp
template <typename TTypeList, template <typename> class TPredicate>
struct type_list_none_of
```
**Description**
Checks that no types in a `type_list` satisfy a unary predicate.
Predicate must be: `template <typename T> struct Pred : etl::bool_constant<...> {};`
Inherits from `etl::true_type` or `etl::false_type`.
---
```cpp
template <typename TTypeList, template <typename> 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 <typename T> struct Pred : etl::bool_constant<...> {};`
Defined as `true` or `false`.
From: `C++17`
## type_lists_are_convertible
```cpp
template <typename TFromList, typename TToList>
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 <typename TFromList, typename TToList>
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 <typename TTypeList, template <typename, typename> 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 <typename A, typename B> struct Compare : etl::bool_constant<...> {};
Inherits from `etl::true_type` or `etl::false_type`.
---
```cpp
template <typename TFromList, typename TToList>
type_lists_are_convertible_v
template <typename TTypeList, template <typename, typename> 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 <typename A, typename B> struct Compare : etl::bool_constant<...> {};
Defined as `true` or `false`.
From: `C++17`
## Examples
## type_list_insert_sorted
```cpp
template <typename TTypeList, typename T, template <typename, typename> 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 <typename A, typename B> struct Compare : etl::bool_constant<...> {};`
Defines `type` as the modified `type_list`.
---
```cpp
using TypeList1 = etl::type_list<char, short, int, long>
using TypeList2 = etl::type_list<float, double>
using TypeList3 = etl::type_list<unsigned char, unsigned short>
template <typename TTypeList, typename T, template <typename, typename> 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 <typename A, typename B> struct Compare : etl::bool_constant<...> {};`
Defined as the modified `type_list`.
### Using member types
## type_list_sort
```cpp
template <typename TTypeList, template <typename, typename> class TCompare>
struct type_list_sort
```
**Description**
`etl::type_list` sorting by a user supplied type comparator.
Comparator must be: `template <typename A, typename B> 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 <typename TTypeList, template <typename, typename> class TCompare>
type_list_sort_t
```
**Description**
`etl::type_list` sorting by a user supplied type comparator.
Comparator must be: `template <typename A, typename B> struct Compare : etl::bool_constant<...> {};`
Defined as the modified `type_list`.
### Using tuple style global types
## type_list_in_all_lists
```cpp
template <typename T, typename... TypeLists>
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<TypeList1>;
// Define the type list
// etl::type_list<char, short, int, long, float, double, unsigned char, unsigned short>
using Concatenated = etl::type_list_cat<TypeList1, TypeList2, TypeList3>
template <typename T, typename... TypeLists>
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 <typename T, typename... TypeLists>
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 <typename T, typename... TypeLists>
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 <typename T, typename... TypeLists>
struct type_list_in_no_lists
```
**Description**
Checks if a type `T` is present none of the provided `type_lists`.
Inherits from `etl::true_type` if `T` is in no list, otherwise `etl::false_type`.
Since: `20.48.0`
---
```cpp
template <typename T, typename... TypeLists>
constexpr bool type_list_in_no_lists_v
```
**Description**
Checks if a type `T` is present in none of the provided `type_lists`.
Defined as `true` if `T` is in no list, otherwise `false`.
Since: `20.48.0`
From: `C++17`
## type_list_remove_from
```cpp
template <typename... TypeLists>
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 <typename... TypeLists>
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`.

View File

@ -209,7 +209,7 @@ namespace etl
#if ETL_USING_CPP17
template <typename TTypeList, typename T>
inline constexpr size_t type_list_index_of_v = etl::type_list_index_of_type<TTypeList, T>::value;
inline constexpr size_t type_list_index_of_type_v = etl::type_list_index_of_type<TTypeList, T>::value;
#endif
//***************************************************************************
@ -271,12 +271,12 @@ namespace etl
struct type_list_contains;
template <typename T, typename... TTypes>
struct type_list_contains<etl::type_list<TTypes...>, T> : public etl::integral_constant<bool, etl::is_one_of<T, TTypes...>::value>
struct type_list_contains<etl::type_list<TTypes...>, T> : public etl::is_one_of<T, TTypes...>
{
};
template <typename T>
struct type_list_contains<type_list<>, T> : public etl::integral_constant<bool, false>
struct type_list_contains<type_list<>, T> : public etl::bool_constant<false>
{
};
@ -388,6 +388,12 @@ namespace etl
template <typename TTypeList, size_t... Indices>
using type_list_select_t = typename type_list_select<TTypeList, Indices...>::type;
template <typename TTypeList, size_t... Indices>
using type_list_select_from_indexes = type_list_select<TTypeList, Indices...>;
template <typename TTypeList, size_t... Indices>
using type_list_select_from_indexes_t = typename type_list_select<TTypeList, Indices...>::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 <typename... TTypes>
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 <typename... TTypes1, typename... TTypes2, typename... TTail>
struct type_list_cat<etl::type_list<TTypes1...>, etl::type_list<TTypes2...>, TTail...>
{
@ -422,6 +430,12 @@ namespace etl
using type = T;
};
template <>
struct type_list_cat<>
{
using type = etl::type_list<>;
};
template <typename... TypeLists>
using type_list_cat_t = typename type_list_cat<TypeLists...>::type;
@ -705,11 +719,6 @@ namespace etl
{
};
template <template <typename> class TPredicate>
struct type_list_all_of<etl::type_list<>, TPredicate> : etl::bool_constant<true>
{
};
#if ETL_USING_CPP17
template <typename TTypeList, template <typename> class TPredicate>
inline constexpr bool type_list_all_of_v = type_list_all_of<TTypeList, TPredicate>::value;
@ -728,11 +737,6 @@ namespace etl
{
};
template <template <typename> class TPredicate>
struct type_list_any_of<etl::type_list<>, TPredicate> : etl::bool_constant<false>
{
};
#if ETL_USING_CPP17
template <typename TTypeList, template <typename> class TPredicate>
inline constexpr bool type_list_any_of_v = type_list_any_of<TTypeList, TPredicate>::value;
@ -751,11 +755,6 @@ namespace etl
{
};
template <template <typename> class TPredicate>
struct type_list_none_of<etl::type_list<>, TPredicate> : etl::bool_constant<true>
{
};
#if ETL_USING_CPP17
template <typename TTypeList, template <typename> class TPredicate>
inline constexpr bool type_list_none_of_v = type_list_none_of<TTypeList, TPredicate>::value;
@ -956,6 +955,251 @@ namespace etl
template <typename TTypeList, template <typename, typename> class TCompare>
using type_list_sort_t = typename etl::type_list_sort<TTypeList, TCompare>::type;
#endif
//*****************************************************************************
/// Checks if a type T is present in all provided type_lists.
/// Returns etl::true_type if T is in every list, otherwise etl::false_type.
//*****************************************************************************
template <typename T, typename... TypeLists>
struct type_list_in_all_lists : etl::conjunction<etl::type_list_contains<TypeLists, T>...>
{
};
// Specialisation if no lists provided.
template <typename T>
struct type_list_in_all_lists<T> : etl::false_type
{
};
#if ETL_USING_CPP17
template <typename T, typename... TypeLists>
inline constexpr bool type_list_in_all_lists_v = type_list_in_all_lists<T, TypeLists...>::value;
#endif
//*****************************************************************************
/// Checks if a type T is present in at least one of the provided type_lists.
/// Returns etl::true_type if T is in any list, otherwise etl::false_type.
//*****************************************************************************
template <typename T, typename... TypeLists>
struct type_list_in_any_list : etl::false_type
{
};
// Recursive case: Check the first list using your helper.
template <typename T, typename FirstList, typename... RestLists>
struct type_list_in_any_list<T, FirstList, RestLists...>
: etl::conditional<type_list_contains<FirstList, T>::value, etl::true_type, type_list_in_any_list<T, RestLists...>>::type
{
};
#if ETL_USING_CPP17
template <typename T, typename... TypeLists>
inline constexpr bool type_list_in_any_list_v = type_list_in_any_list<T, TypeLists...>::value;
#endif
//*****************************************************************************
/// Checks if a type T is present in none provided type_lists.
/// Returns etl::true_type if T is in no list, otherwise etl::false_type.
//*****************************************************************************
template <typename T, typename... Lists>
using type_list_in_no_lists = etl::bool_constant<!type_list_in_any_list<T, Lists...>::value>;
#if ETL_USING_CPP17
template <typename T, typename... Lists>
inline constexpr bool type_list_in_no_lists_v = type_list_in_no_lists<T, Lists...>::value;
#endif
//*****************************************************************************
namespace private_type_list
{
template <typename TInputList, typename TAccumulatedResult, typename... TOtherLists>
struct type_list_remove_from_accumulator;
// Base case: No more types to process, return the accumulated result.
template <typename TAccumulatedResult, typename... TOtherLists>
struct type_list_remove_from_accumulator<etl::type_list<>, TAccumulatedResult, TOtherLists...>
{
using type = TAccumulatedResult;
};
// Recursive case: Process Head, accumulate result forward.
template <typename Head, typename... Tail, typename TAccumulatedResult, typename... TOtherLists>
struct type_list_remove_from_accumulator<etl::type_list<Head, Tail...>, TAccumulatedResult, TOtherLists...>
{
private:
// Check if Head does not exist in any of the other lists.
static constexpr bool head_is_not_in_other_lists = etl::type_list_in_no_lists<Head, TOtherLists...>::value;
// Append Head to the result if it's NOT in any of the other lists.
using accumulated = etl::conditional_t<head_is_not_in_other_lists, etl::type_list_push_back_t<TAccumulatedResult, Head>, TAccumulatedResult>;
public:
// Recurse with the updated accumulator and remaining types.
using type = typename type_list_remove_from_accumulator<etl::type_list<Tail...>, accumulated, TOtherLists...>::type;
};
//*****************************************************************************
// Extract the first list and call the main implementation.
//*****************************************************************************
template <typename... TypeLists>
struct type_list_remove_from_helper;
// An difference of no type_lists is an empty type_list.
template <>
struct type_list_remove_from_helper<>
{
using type = etl::type_list<>;
};
// One list, so just return it.
template <typename TypeList>
struct type_list_remove_from_helper<TypeList>
{
using type = TypeList;
};
// Two or more lists.
template <typename TFirstList, typename... TRestLists>
struct type_list_remove_from_helper<TFirstList, TRestLists...>
{
using type = typename type_list_remove_from_accumulator<TFirstList, etl::type_list<>, TRestLists...>::type;
};
} // namespace private_type_list
//***************************************************************************
/// Defines a new type_list that contains the types in the first list that are
/// not in any of the following lists.
/// Does not remove duplicates.
//***************************************************************************
template <typename... TypeLists>
struct type_list_remove_from
{
// Ensure all parameters are actually type_lists.
static_assert(etl::conjunction<etl::is_type_list<TypeLists>...>::value, "All parameters must be etl::type_list types");
using type = typename private_type_list::type_list_remove_from_helper<TypeLists...>::type;
};
template <typename... TypeLists>
using type_list_remove_from_t = typename type_list_remove_from<TypeLists...>::type;
//***************************************************************************
/// Concatenates two or more type_lists and removes duplicates.
//***************************************************************************
template <typename... TypeLists>
struct type_list_cat_unique
{
// Ensure all parameters are actually type_lists (optional, but helpful).
static_assert(etl::conjunction<etl::is_type_list<TypeLists>...>::value, "All parameters must be etl::type_list types");
using type = etl::type_list_unique_t<type_list_cat_t<TypeLists...>>;
};
template <typename... TypeLists>
using type_list_cat_unique_t = typename type_list_cat_unique<TypeLists...>::type;
//****************************************************************************
namespace private_type_list
{
template <typename TInputList, typename TAccumulatedResult, typename... TOtherLists>
struct type_list_select_common_types_accumulator;
// Base case: No more types to process, return the accumulated result.
template <typename TAccumulatedResult, typename... TOtherLists>
struct type_list_select_common_types_accumulator<etl::type_list<>, TAccumulatedResult, TOtherLists...>
{
using type = TAccumulatedResult;
};
// Recursive case: Process Head, accumulate result forward.
template <typename Head, typename... Tail, typename TAccumulatedResult, typename... TOtherLists>
struct type_list_select_common_types_accumulator<etl::type_list<Head, Tail...>, TAccumulatedResult, TOtherLists...>
{
private:
// Check if Head exists in all other lists.
static constexpr bool head_is_in_all_lists = etl::type_list_in_all_lists<Head, TOtherLists...>::value;
// Append Head to the result if it's in all lists AND not already added.
using accumulated = etl::conditional_t<head_is_in_all_lists, etl::type_list_push_back_t<TAccumulatedResult, Head>, TAccumulatedResult>;
public:
// Recurse with the updated accumulator and remaining types.
using type = typename type_list_select_common_types_accumulator<etl::type_list<Tail...>, accumulated, TOtherLists...>::type;
};
//*****************************************************************************
// Extract the first list and call the main implementation.
//*****************************************************************************
template <typename... TypeLists>
struct type_list_select_common_types_helper;
// An intersection of no type lists is an empty type_list.
template <>
struct type_list_select_common_types_helper<>
{
using type = etl::type_list<>;
};
// One list, so just return it.
template <typename TypeList>
struct type_list_select_common_types_helper<TypeList>
{
using type = etl::type_list_unique_t<TypeList>;
};
// Two or more lists, use the intersection algorithm.
template <typename TFirstList, typename... TRestLists>
struct type_list_select_common_types_helper<TFirstList, TRestLists...>
{
private:
// Remove duplicates from the first list.
using first_unique = etl::type_list_unique_t<TFirstList>;
public:
using type = typename type_list_select_common_types_accumulator<first_unique, etl::type_list<>, TRestLists...>::type;
};
} // namespace private_type_list
//*****************************************************************************
/// Defines a new 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.
//*****************************************************************************
template <typename... TypeLists>
struct type_list_select_common_types
{
// Ensure all parameters are actually type_lists (optional, but helpful).
static_assert(etl::conjunction<etl::is_type_list<TypeLists>...>::value, "All parameters must be etl::type_list types");
using type = typename private_type_list::type_list_select_common_types_helper<TypeLists...>::type;
};
template <typename... TypeLists>
using type_list_select_common_types_t = typename type_list_select_common_types<TypeLists...>::type;
//*****************************************************************************
/// Defines a new type_list that a selection 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 provided type_list.
/// The result contains no duplicates.
//*****************************************************************************
template <typename... TypeLists>
struct type_list_select_not_common_types
{
// Ensure all parameters are actually type_lists (optional, but helpful).
static_assert(etl::conjunction<etl::is_type_list<TypeLists>...>::value, "All parameters must be etl::type_list types");
using type = etl::type_list_remove_from_t<etl::type_list_cat_unique_t<TypeLists...>, etl::type_list_select_common_types_t<TypeLists...>>;
};
template <typename... TypeLists>
using type_list_select_not_common_types_t = typename type_list_select_not_common_types<TypeLists...>::type;
} // namespace etl
#endif

View File

@ -49,6 +49,19 @@ namespace
static constexpr int id = 2;
};
struct D
{
static constexpr int id = 3;
};
struct E
{
static constexpr int id = 4;
};
struct F
{
static constexpr int id = 5;
};
template <typename T>
struct is_type_a : etl::bool_constant<std::is_same<T, A>::value>
{
@ -64,6 +77,21 @@ namespace
{
};
template <typename T>
struct is_type_d : etl::bool_constant<std::is_same<T, D>::value>
{
};
template <typename T>
struct is_type_e : etl::bool_constant<std::is_same<T, E>::value>
{
};
template <typename T>
struct is_type_f : etl::bool_constant<std::is_same<T, F>::value>
{
};
// Convenience comparator for types that expose a constexpr integral ID
// (ascending)
template <typename T1, typename T2>
@ -101,6 +129,28 @@ namespace
CHECK_TRUE((std::is_same<etl::type_list_select_t<t1, 0, 2>, t2>::value));
}
//*************************************************************************
TEST(test_type_list_select_from_indexes)
{
typedef etl::type_list<char, int, uint32_t> t1;
typedef etl::type_list<char, uint32_t> t2;
CHECK_TRUE((std::is_same<etl::type_list_select_from_indexes<t1, 0, 2>::type, t2>::value));
CHECK_TRUE((std::is_same<etl::type_list_select_from_indexes_t<t1, 0, 2>, t2>::value));
}
//*************************************************************************
TEST(test_type_list_select_from_index_sequence)
{
typedef etl::type_list<char, int, uint32_t> t1;
typedef etl::type_list<char, uint32_t> t2;
using index_sequence = etl::index_sequence<0, 2>;
CHECK_TRUE((std::is_same< etl::type_list_select_from_index_sequence<t1, index_sequence>::type, t2>::value));
CHECK_TRUE((std::is_same<etl::type_list_select_from_index_sequence_t<t1, index_sequence>, t2>::value));
}
//*************************************************************************
TEST(test_type_list_size)
{
@ -116,12 +166,12 @@ namespace
//*************************************************************************
TEST(test_type_list_cat)
{
typedef etl::type_list<char, int, uint32_t> t1;
typedef etl::type_list<uint8_t, uint16_t> t2;
typedef etl::type_list<> t3;
typedef etl::type_list<char, uint16_t, int, uint32_t> t1;
typedef etl::type_list<uint8_t, uint16_t, int> t2;
typedef etl::type_list<> t3;
typedef etl::type_list<char, int, uint32_t, uint8_t, uint16_t> t_cat1;
typedef etl::type_list<char, int, uint32_t, uint8_t, bool> t_cat2;
typedef etl::type_list<char, uint16_t, int, uint32_t, uint8_t, uint16_t, int> t_cat1;
typedef etl::type_list<char, int, uint32_t, uint8_t, bool> t_cat2;
CHECK_TRUE((std::is_same<etl::type_list_cat<t1, t2>::type, t_cat1>::value));
CHECK_TRUE((std::is_same<etl::type_list_cat<t1, t2, t3>::type, t_cat1>::value));
@ -132,6 +182,25 @@ namespace
CHECK_FALSE((std::is_same<etl::type_list_cat_t<t1, t2>, t_cat2>::value));
}
//*************************************************************************
TEST(test_type_list_cat_unique)
{
using t1 = etl::type_list<char, uint16_t, int, uint32_t>;
using t2 = etl::type_list<uint8_t, uint16_t, int>;
using t3 = etl::type_list<>;
using t_cat1 = etl::type_list<char, uint16_t, int, uint32_t, uint8_t>;
using t_cat2 = etl::type_list<char, int, uint32_t, uint8_t, bool>;
CHECK_TRUE((std::is_same<etl::type_list_cat_unique<t1, t2>::type, t_cat1>::value));
CHECK_TRUE((std::is_same<etl::type_list_cat_unique<t1, t2, t3>::type, t_cat1>::value));
CHECK_FALSE((std::is_same<etl::type_list_cat_unique<t1, t2>::type, t_cat2>::value));
CHECK_TRUE((std::is_same<etl::type_list_cat_unique_t<t1, t2>, t_cat1>::value));
CHECK_TRUE((std::is_same<etl::type_list_cat_unique_t<t1, t2, t3>, t_cat1>::value));
CHECK_FALSE((std::is_same<etl::type_list_cat_unique_t<t1, t2>, t_cat2>::value));
}
//*************************************************************************
TEST(test_type_list_contains)
{
@ -225,10 +294,10 @@ namespace
CHECK_EQUAL((etl::type_list_index_of_type<t2, uint32_t>::value), etl::type_list_npos);
#if ETL_USING_CPP17
CHECK_EQUAL((etl::type_list_index_of_v<t1, char>), 0);
CHECK_EQUAL((etl::type_list_index_of_v<t1, int>), 1);
CHECK_EQUAL((etl::type_list_index_of_v<t1, uint32_t>), 2);
CHECK_EQUAL((etl::type_list_index_of_v<t2, uint32_t>), etl::type_list_npos);
CHECK_EQUAL((etl::type_list_index_of_type_v<t1, char>), 0);
CHECK_EQUAL((etl::type_list_index_of_type_v<t1, int>), 1);
CHECK_EQUAL((etl::type_list_index_of_type_v<t1, uint32_t>), 2);
CHECK_EQUAL((etl::type_list_index_of_type_v<t2, uint32_t>), etl::type_list_npos);
#endif
}
@ -357,12 +426,12 @@ namespace
//*************************************************************************
TEST(test_type_list_sort_multiple_list)
{
using list = etl::type_list<B, C, A>;
using list = etl::type_list<E, B, F, C, A, D>;
using result = etl::type_list_sort_t<list, by_ascending_id>;
using expected = etl::type_list<A, B, C>;
using expected = etl::type_list<A, B, C, D, E, F>;
CHECK((etl::is_same<result, expected>::value));
CHECK_EQUAL(3U, etl::type_list_size<result>::value);
CHECK_EQUAL(6U, etl::type_list_size<result>::value);
}
//*************************************************************************
@ -843,6 +912,269 @@ namespace
CHECK_FALSE((etl::type_list_is_empty_v<list2>));
#endif
}
//*************************************************************************
TEST(test_type_list_in_all_lists)
{
using list1 = etl::type_list<A, B, F, C>;
using list2 = etl::type_list<B, E, D>;
using list3 = etl::type_list<A, B, E, D, E, F>;
using list4 = etl::type_list<>;
#if ETL_USING_CPP17
constexpr bool type_list_in_all_lists0 = etl::type_list_in_all_lists_v<A>;
constexpr bool type_list_in_all_lists1 = etl::type_list_in_all_lists_v<A, list1>;
constexpr bool type_list_in_all_lists2 = etl::type_list_in_all_lists_v<A, list2>;
constexpr bool type_list_in_all_lists3 = etl::type_list_in_all_lists_v<A, list1, list3>;
constexpr bool type_list_in_all_lists4 = etl::type_list_in_all_lists_v<A, list4>;
constexpr bool type_list_in_all_lists5 = etl::type_list_in_all_lists_v<A, list1, list2, list3>;
constexpr bool type_list_in_all_lists6 = etl::type_list_in_all_lists_v<A, list1, list2, list3, list4>;
#else
constexpr bool type_list_in_all_lists0 = etl::type_list_in_all_lists<A>::value;
constexpr bool type_list_in_all_lists1 = etl::type_list_in_all_lists<A, list1>::value;
constexpr bool type_list_in_all_lists2 = etl::type_list_in_all_lists<A, list2>::value;
constexpr bool type_list_in_all_lists3 = etl::type_list_in_all_lists<A, list1, list3>::value;
constexpr bool type_list_in_all_lists4 = etl::type_list_in_all_lists<A, list4>::value;
constexpr bool type_list_in_all_lists5 = etl::type_list_in_all_lists<A, list1, list2, list3>::value;
constexpr bool type_list_in_all_lists6 = etl::type_list_in_all_lists<A, list1, list2, list3, list4>::value;
#endif
CHECK_FALSE(type_list_in_all_lists0);
CHECK_TRUE(type_list_in_all_lists1);
CHECK_FALSE(type_list_in_all_lists2);
CHECK_TRUE(type_list_in_all_lists3);
CHECK_FALSE(type_list_in_all_lists4);
CHECK_FALSE(type_list_in_all_lists5);
CHECK_FALSE(type_list_in_all_lists6);
}
//*************************************************************************
TEST(test_type_list_in_any_list)
{
using list1 = etl::type_list<A, B, F, C>;
using list2 = etl::type_list<B, E, D>;
using list3 = etl::type_list<A, B, E, D, E, F>;
using list4 = etl::type_list<>;
#if ETL_USING_CPP17
constexpr bool type_list_in_any_list0 = etl::type_list_in_any_list_v<A>;
constexpr bool type_list_in_any_list1 = etl::type_list_in_any_list_v<A, list1>;
constexpr bool type_list_in_any_list2 = etl::type_list_in_any_list_v<A, list2>;
constexpr bool type_list_in_any_list3 = etl::type_list_in_any_list_v<A, list1, list3>;
constexpr bool type_list_in_any_list4 = etl::type_list_in_any_list_v<A, list4>;
constexpr bool type_list_in_any_list5 = etl::type_list_in_any_list_v<A, list1, list2, list3>;
constexpr bool type_list_in_any_list6 = etl::type_list_in_any_list_v<A, list1, list2, list3, list4>;
#else
constexpr bool type_list_in_any_list0 = etl::type_list_in_any_list<A>::value;
constexpr bool type_list_in_any_list1 = etl::type_list_in_any_list<A, list1>::value;
constexpr bool type_list_in_any_list2 = etl::type_list_in_any_list<A, list2>::value;
constexpr bool type_list_in_any_list3 = etl::type_list_in_any_list<A, list1, list3>::value;
constexpr bool type_list_in_any_list4 = etl::type_list_in_any_list<A, list4>::value;
constexpr bool type_list_in_any_list5 = etl::type_list_in_any_list<A, list1, list2, list3>::value;
constexpr bool type_list_in_any_list6 = etl::type_list_in_any_list<A, list1, list2, list3, list4>::value;
#endif
CHECK_FALSE(type_list_in_any_list0);
CHECK_TRUE(type_list_in_any_list1);
CHECK_FALSE(type_list_in_any_list2);
CHECK_TRUE(type_list_in_any_list3);
CHECK_FALSE(type_list_in_any_list4);
CHECK_TRUE(type_list_in_any_list5);
CHECK_TRUE(type_list_in_any_list6);
}
//*************************************************************************
TEST(test_type_list_in_no_lists)
{
using list1 = etl::type_list<A, B, F, C>;
using list2 = etl::type_list<B, E, D>;
using list3 = etl::type_list<A, B, E, D, E, F>;
using list4 = etl::type_list<>;
#if ETL_USING_CPP17
constexpr bool type_list_in_no_lists0 = etl::type_list_in_no_lists_v<A>;
constexpr bool type_list_in_no_lists1 = etl::type_list_in_no_lists_v<A, list1>;
constexpr bool type_list_in_no_lists2 = etl::type_list_in_no_lists_v<A, list2>;
constexpr bool type_list_in_no_lists3 = etl::type_list_in_no_lists_v<A, list1, list3>;
constexpr bool type_list_in_no_lists4 = etl::type_list_in_no_lists_v<A, list4>;
constexpr bool type_list_in_no_lists5 = etl::type_list_in_no_lists_v<A, list1, list2, list3>;
constexpr bool type_list_in_no_lists6 = etl::type_list_in_no_lists_v<A, list1, list2, list3, list4>;
#else
constexpr bool type_list_in_no_lists0 = etl::type_list_in_no_lists<A>::value;
constexpr bool type_list_in_no_lists1 = etl::type_list_in_no_lists<A, list1>::value;
constexpr bool type_list_in_no_lists2 = etl::type_list_in_no_lists<A, list2>::value;
constexpr bool type_list_in_no_lists3 = etl::type_list_in_no_lists<A, list1, list3>::value;
constexpr bool type_list_in_no_lists4 = etl::type_list_in_no_lists<A, list4>::value;
constexpr bool type_list_in_no_lists5 = etl::type_list_in_no_lists<A, list1, list2, list3>::value;
constexpr bool type_list_in_no_lists6 = etl::type_list_in_no_lists<A, list1, list2, list3, list4>::value;
#endif
CHECK_TRUE(type_list_in_no_lists0);
CHECK_FALSE(type_list_in_no_lists1);
CHECK_TRUE(type_list_in_no_lists2);
CHECK_FALSE(type_list_in_no_lists3);
CHECK_TRUE(type_list_in_no_lists4);
CHECK_FALSE(type_list_in_no_lists5);
CHECK_FALSE(type_list_in_no_lists6);
}
//*************************************************************************
TEST(test_type_list_cat_unique_of_no_list)
{
using type_list_cat_unique = etl::type_list_cat_unique_t<>;
CHECK_TRUE((etl::is_same<type_list_cat_unique, etl::type_list<>>::value));
}
//*************************************************************************
TEST(test_type_list_cat_unique_of_empty_list)
{
using list1 = etl::type_list<>;
using type_list_cat_unique = etl::type_list_cat_unique_t<list1>;
CHECK_TRUE((etl::is_same<type_list_cat_unique, etl::type_list<>>::value));
}
//*************************************************************************
TEST(test_type_list_cat_unique_of_1_list)
{
using list1 = etl::type_list<A, D, A, B, F, C>;
using type_list_cat_unique = etl::type_list_cat_unique_t<list1>;
CHECK_TRUE(etl::type_list_is_unique<type_list_cat_unique>::value);
CHECK_TRUE((etl::is_same<type_list_cat_unique, etl::type_list<A, D, B, F, C>>::value));
}
//*************************************************************************
TEST(test_type_list_cat_unique_of_3_lists)
{
using list1 = etl::type_list<A, D, A, B, F, C>;
using list2 = etl::type_list<>;
using list3 = etl::type_list<A, B, E, D, E, F>;
using type_list_cat_unique = etl::type_list_cat_unique_t<list1, list2, list3>;
CHECK_TRUE(etl::type_list_is_unique<type_list_cat_unique>::value);
CHECK_TRUE((etl::is_same<type_list_cat_unique, etl::type_list<A, D, B, F, C, E>>::value));
}
//*************************************************************************
TEST(test_type_list_select_common_types_of_no_list)
{
using type_list_select_common_types = etl::type_list_select_common_types_t<>;
CHECK_TRUE((etl::is_same<type_list_select_common_types, etl::type_list<>>::value));
}
//*************************************************************************
TEST(test_type_list_select_common_types_of_empty_list)
{
using list1 = etl::type_list<>;
using type_list_select_common_types = etl::type_list_select_common_types_t<list1>;
CHECK_TRUE((etl::is_same<type_list_select_common_types, etl::type_list<>>::value));
}
//*************************************************************************
TEST(test_type_list_select_common_types_of_1_list)
{
using list1 = etl::type_list<A, D, A, B, F, C>;
using type_list_select_common_types = etl::type_list_select_common_types_t<list1>;
CHECK_TRUE(etl::type_list_is_unique<type_list_select_common_types>::value);
CHECK_TRUE((etl::is_same<type_list_select_common_types, etl::type_list<A, D, B, F, C>>::value));
}
//*************************************************************************
TEST(test_type_list_select_common_types_of_3_lists)
{
using list1 = etl::type_list<A, D, A, B, F, C>;
using list2 = etl::type_list<A, D, B, F, B>;
using list3 = etl::type_list<A, B, E, D, E, F>;
using type_list_select_common_types = etl::type_list_select_common_types_t<list1, list2, list3>;
CHECK_TRUE(etl::type_list_is_unique<type_list_select_common_types>::value);
CHECK_TRUE((etl::is_same<type_list_select_common_types, etl::type_list<A, D, B, F>>::value));
}
//*************************************************************************
TEST(test_type_list_select_not_common_types_1)
{
using list1 = etl::type_list<A, B, C, D, E, F>;
using type_list_select_not_common_types = etl::type_list_select_not_common_types_t<list1>;
CHECK_TRUE(etl::type_list_is_unique<type_list_select_not_common_types>::value);
CHECK_TRUE((etl::is_same<type_list_select_not_common_types, etl::type_list<>>::value));
}
//*************************************************************************
TEST(test_type_list_select_not_common_types_2)
{
using list1 = etl::type_list<A, B, C, D, E, F>;
using list2 = etl::type_list<A, B, C, D, E, F>;
using type_list_select_not_common_types = etl::type_list_select_not_common_types_t<list1, list2>;
CHECK_TRUE(etl::type_list_is_unique<type_list_select_not_common_types>::value);
CHECK_TRUE((etl::is_same<type_list_select_not_common_types, etl::type_list<>>::value));
CHECK_TRUE((std::is_same<etl::type_list_select_not_common_types_t<list1, list2>, etl::type_list<>>::value));
}
//*************************************************************************
TEST(test_type_list_select_not_common_types_3)
{
using list1 = etl::type_list<A, B, C, D, E, F>;
using list2 = etl::type_list<A, B, D, F>;
using list3 = etl::type_list<B, C, D, E, F>;
using type_list_select_not_common_types = etl::type_list_select_not_common_types_t<list1, list2, list3>;
CHECK_TRUE(etl::type_list_is_unique<type_list_select_not_common_types>::value);
CHECK_TRUE((etl::is_same<type_list_select_not_common_types, etl::type_list<A, C, E>>::value));
}
//*************************************************************************
TEST(test_type_list_remove_from_1_list)
{
using list1 = etl::type_list<A, D, A, B, F, C>;
using type_list_remove_from = etl::type_list_remove_from_t<list1>;
CHECK_FALSE(etl::type_list_is_unique<type_list_remove_from>::value);
CHECK_TRUE((etl::is_same<type_list_remove_from, etl::type_list<A, D, A, B, F, C>>::value));
}
//*************************************************************************
TEST(test_type_list_remove_from_2_list)
{
using list1 = etl::type_list<A, D, A, B, F, C>;
using list2 = etl::type_list<D, B>;
using type_list_remove_from = etl::type_list_remove_from_t<list1, list2>;
CHECK_FALSE(etl::type_list_is_unique<type_list_remove_from>::value);
CHECK_TRUE((etl::is_same<type_list_remove_from, etl::type_list<A, A, F, C>>::value));
}
//*************************************************************************
TEST(test_type_list_remove_from_3_lists)
{
using list1 = etl::type_list<A, D, A, B, F, C>;
using list2 = etl::type_list<A, D, B, F, B>;
using list3 = etl::type_list<A, E, D, E, F>;
using type_list_remove_from = etl::type_list_remove_from_t<list1, list2, list3>;
CHECK_TRUE(etl::type_list_is_unique<type_list_remove_from>::value);
CHECK_TRUE((etl::is_same<type_list_remove_from, etl::type_list<C>>::value));
}
}
#endif
} // namespace