From fe1f19ce4dc6b763b4190049043c204e46e15030 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 8 Feb 2026 10:42:03 +0000 Subject: [PATCH] Added new type_list features Added make_index_sequence_with_offset --- include/etl/type_list.h | 273 +++++++++++++++++++++++++++++++++++++++- include/etl/utility.h | 17 +++ test/test_type_list.cpp | 119 ++++++++++++++++++ 3 files changed, 404 insertions(+), 5 deletions(-) diff --git a/include/etl/type_list.h b/include/etl/type_list.h index 19eddc15..667e2a06 100644 --- a/include/etl/type_list.h +++ b/include/etl/type_list.h @@ -48,11 +48,14 @@ namespace etl static ETL_CONSTANT size_t type_list_npos = etl::integral_limits::max; //*************************************************************************** - /// Type list forward declaration. + // Type list forward declaration. //*************************************************************************** template struct type_list; + //*************************************************************************** + /// Check if a type is an etl::type_list. + //*************************************************************************** template struct is_type_list : etl::false_type {}; @@ -154,8 +157,8 @@ namespace etl template struct type_list_type_at_index { - ETL_STATIC_ASSERT(Index < type_list_size::value, "etl::type_list_type_at_index out of range"); - ETL_STATIC_ASSERT((etl::is_base_of, TTypeList>::value), "TTypeList must be an etl::type_list"); + ETL_STATIC_ASSERT(Index < type_list_size::value, "etl::type_list_type_at_index out of range"); + ETL_STATIC_ASSERT((etl::is_type_list::value), "TTypeList must be an etl::type_list"); using type = typename type_list_type_at_index::type; }; @@ -163,6 +166,8 @@ namespace etl template struct type_list_type_at_index { + ETL_STATIC_ASSERT((etl::is_type_list::value), "TTypeList must be an etl::type_list"); + using type = typename TTypeList::head; }; @@ -179,7 +184,7 @@ namespace etl (type_list_index_of_type::value == etl::type_list_npos ? etl::type_list_npos : type_list_index_of_type::value + 1)> { - ETL_STATIC_ASSERT((etl::is_base_of, TTypeList>::value), "TTypeList must be an etl::type_list"); + ETL_STATIC_ASSERT((etl::is_type_list::value), "TTypeList must be an etl::type_list"); }; template @@ -316,7 +321,7 @@ namespace etl template struct type_list_select { - ETL_STATIC_ASSERT((etl::is_base_of, TTypeList>::value), "TTypeList must be an etl::type_list"); + ETL_STATIC_ASSERT((etl::is_type_list::value), "TTypeList must be an etl::type_list"); using type = type_list...>; }; @@ -324,6 +329,23 @@ namespace etl template using type_list_select_t = typename type_list_select::type; + //*************************************************************************** + /// Declares a new type_list by selecting types from a given type_list, according to an index sequence. + //*************************************************************************** + template + struct type_list_select_from_sequence; + + template + struct type_list_select_from_sequence> + { + using type = etl::type_list_select_t; + }; + +#if ETL_USING_CPP11 + template + using type_list_select_from_sequence_t = typename type_list_select_from_sequence::type; +#endif + //*************************************************************************** /// Concatenates two or more type_lists. //*************************************************************************** @@ -345,6 +367,78 @@ namespace etl template using type_list_cat_t = typename type_list_cat::type; + //*************************************************************************** + /// Prepend a type to a type_list. + //*************************************************************************** + template + struct type_list_prepend; + + template + struct type_list_prepend, T> + { + using type = type_list; + }; + + template + struct type_list_prepend + { + using type = etl::type_list; + }; + + template + using type_list_prepend_t = typename type_list_prepend::type; + + //*************************************************************************** + /// Append a type to a type_list. + //*************************************************************************** + template + struct type_list_append; + + template + struct type_list_append, T> + { + using type = type_list; + }; + + template + struct type_list_append + { + using type = etl::type_list; + }; + + template + using type_list_append_t = typename type_list_append::type; + + //*************************************************************************** + /// 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. + //*************************************************************************** + template + struct type_list_insert + { + private: + + ETL_STATIC_ASSERT((etl::is_type_list::value), "TTypeList must be an etl::type_list"); + ETL_STATIC_ASSERT(Index <= etl::type_list_size::value, "Index out of range"); + + using index_sequence_for_prefix = etl::make_index_sequence; + using index_sequence_for_suffix = etl::make_index_sequence_with_offset::value - Index>; + + using prefix = etl::type_list_select_from_sequence_t; + using suffix = etl::type_list_select_from_sequence_t; + + public: + + // Concatenate the prefix, new type, and suffix to create the new type list with T inserted at the correct position. + using type = etl::type_list_cat_t, suffix>; + }; + +#if ETL_USING_CPP11 + template + using type_list_insert_t = typename etl::type_list_insert::type; +#endif + //*************************************************************************** /// Checks that two type lists are convertible. /// Static asserts if the type lists are not the same length. @@ -373,6 +467,175 @@ namespace etl template inline constexpr bool type_lists_are_convertible_v = etl::type_lists_are_convertible::value; #endif + + namespace private_type_list + { + //********************************* + template class TCompare> + struct type_list_is_sorted_impl; + + //********************************* + // Empty list is sorted + template