mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Add more features to etl::type_list (#1307)
* Remove AppVeyor build status badge Removed AppVeyor build status badge from README. * Update README.md * Update CONTRIBUTING.md Updated the instructions for contributing. * Added etl::type_list to etl::observer * Added etl::type_list to etl::nth_type * Added missing 'typename' to type_list nth_type * Fix for issue 1276 "Data corruption in the etl::bip_buffer_spsc_atomic" (#1277) * Reproduce data corruption bug in the `etl::bip_buffer_spsc_atomic`. * Fix data corruption bug in the `etl::bip_buffer_spsc_atomic`. * Added type_list definitions for nth_type and observer * Added etl::type_list to etl::variant * Updated comments * Addedetl::type~_list to message_router, observer, visitor # Conflicts: # include/etl/observer.h # test/vs2022/etl.vcxproj.filters * Added member type_list type to tuple * Work in progress * Copy changes from other source * Removed unused tests * Fix iter_swap namespace * Add type_list functionality to etl::variant using etl::variant_from_type_list * Add type_list functionality to etl::message_packet using etl::message_packet_from_type_list * Add type_list functionality to etl::message_router using etl::message_router_from_type_list * Add type_list functionality to etl::observer using etl::observer_from_type_list * Add type_list functionality to etl::tuple using etl::tuple_from_type_list * Allow etl::make_index_sequence to be created from an etl::type_list * Add type_list functionality to etl::visitor using etl::visitor_from_type_list * Fix iter_swap namespace * Allow creation of a message_packet with no message types * Allow creation of a message_router with no message types * Updated VS2022 project files * Added missing test files CMakeLists.txt * Fix C++03 compatibility Fixed unused aregument warnings * Synced message_packet generator to updated code * Synced message_router generator to updated code * Synced message_router generator to updated code # Conflicts: # include/etl/generators/message_router_generator.h # include/etl/message_router.h * Fixed missing zero message specialisation for <= C++14 * Fixed missing zero message specialisation for <= C++14 * Fix year_month arithmetic and correct chrono API behavior (#1257) * Fix & add more tests for year_month arithmetic * Minor addtions to previous commit * More missing values to be uninitialized * Update the default constructors to = default and correct default constructor tests accordingly * Fix & add more tests for year_month arithmetic * Minor addtions to previous commit * More missing values to be uninitialized * Update the default constructors to = default and correct default constructor tests accordingly * Restore default constructor behavior for chrono calender * Suppress warnings from std in optimized builds (#1259) When testing with ./run-tests.sh 23 3 10, some warnings from std surfaced which resulted in build errors. * Add template deduction guide for span from vector (#1264) * Create span from vector deduction * Use ivector for deduction. Add vector_ext to test * Add vector pointer to test * Finish tests * Initialize pdata_ext and others * Document how to implement platform specifics (#1262) Some interfaces need to be implemented in every project or platform using the ETL: * etl_get_high_resolution_clock * etl_get_system_clock * etl_get_steady_clock * etl_putchar Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com> * Fix etl::as_bytes for etl::span<const T> (#1266) A missing 'const' in the etl::as_bytes implementation was causing a compile-time error when etl::as_bytes was called on a span of const values. Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com> * Remove some UB in test_vector_non_trivial.cpp (#1268) Some of the tests' UB are detectable by Gcc15 and thus give a compile error due to warnings-as-error flag. Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com> * Update C++26 deprecated constructs to ensure future standard compliance (#1267) * Update C++26 deprecated constructs to ensure future standard compliance I replaced std::is_trivial with a combination of std::is_trivially_default_constructible and std::is_trivially_copyable. Additionally, I added the required comma before the ellipsis in variadic functions to match updated language specifications. * Some additional is_trivial related changes not found directly when compiling tests in C++26 --------- Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com> * Fix return value of get_token_list (#1271) Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com> * Fix etl::tuple template signature error in pair assignment operator (#1265) * Fix etl::tuple template signature error in pair assignment operator * Remove AppVeyor build status badge Removed AppVeyor build status badge from README. * Update README.md * Update etl::tuple to explicitly use etl::pair or std::pair in assignment operator * Added tests for etl::tuple assignment from pair --------- Co-authored-by: Bryton Flecker <bflecker@swe.com> Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com> * Remove advance() on static spans (#1281) * Remove AppVeyor build status badge Removed AppVeyor build status badge from README. * Update README.md * Update CONTRIBUTING.md Updated the instructions for contributing. * Fix for issue 1276 "Data corruption in the etl::bip_buffer_spsc_atomic" (#1277) * Reproduce data corruption bug in the `etl::bip_buffer_spsc_atomic`. * Fix data corruption bug in the `etl::bip_buffer_spsc_atomic`. * Remove advance() on static spans Since the size of a static span is constant, we can't reasonably advance() on it. --------- Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com> Co-authored-by: Sergei <sergej.shirokov@gmail.com> * Add missing includes (#1286) * Remove AppVeyor build status badge Removed AppVeyor build status badge from README. * Update README.md * Update CONTRIBUTING.md Updated the instructions for contributing. * Fix for issue 1276 "Data corruption in the etl::bip_buffer_spsc_atomic" (#1277) * Reproduce data corruption bug in the `etl::bip_buffer_spsc_atomic`. * Fix data corruption bug in the `etl::bip_buffer_spsc_atomic`. * Add missing includes Before this change, the includes needed to be done explicitly by files using basic_string_stream.h, and be included first. This was error prone, especially if includes are reordered (e.g. via the currently defined clang-format rules). --------- Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com> Co-authored-by: Sergei <sergej.shirokov@gmail.com> * Move comparison operators of etl::expected to namespace etl (#1287) * Remove AppVeyor build status badge Removed AppVeyor build status badge from README. * Update README.md * Update CONTRIBUTING.md Updated the instructions for contributing. * Fix for issue 1276 "Data corruption in the etl::bip_buffer_spsc_atomic" (#1277) * Reproduce data corruption bug in the `etl::bip_buffer_spsc_atomic`. * Fix data corruption bug in the `etl::bip_buffer_spsc_atomic`. * Move comparison operators of etl::expected to namespace etl --------- Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com> Co-authored-by: Sergei <sergej.shirokov@gmail.com> * Make typed_storage constructor constexpr (#1291) * Remove AppVeyor build status badge Removed AppVeyor build status badge from README. * Update README.md * Update CONTRIBUTING.md Updated the instructions for contributing. * Fix for issue 1276 "Data corruption in the etl::bip_buffer_spsc_atomic" (#1277) * Reproduce data corruption bug in the `etl::bip_buffer_spsc_atomic`. * Fix data corruption bug in the `etl::bip_buffer_spsc_atomic`. * Make typed_storage constructor constexpr --------- Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com> Co-authored-by: Sergei <sergej.shirokov@gmail.com> * Add basic_format_arg constructor for ibasic_string (#1288) * Allow string as format arg * Remove AppVeyor build status badge Removed AppVeyor build status badge from README. * Update README.md * Update CONTRIBUTING.md Updated the instructions for contributing. * Fix for issue 1276 "Data corruption in the etl::bip_buffer_spsc_atomic" (#1277) * Reproduce data corruption bug in the `etl::bip_buffer_spsc_atomic`. * Fix data corruption bug in the `etl::bip_buffer_spsc_atomic`. * Added test string escaped * Add temporary string test --------- Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com> Co-authored-by: Sergei <sergej.shirokov@gmail.com> * QR Code for Github * Added etl::visitor_from_type_list * accepts(id) for empty router passes on to a sucessor * Fixed incorrect comment from 'tuple' to 'message_router' * PR review changes * PR review changes * Fixed internal constexptr flag in message_packet * Fixed unused variable in unti test * Added new type_list features Added make_index_sequence_with_offset * Renamed type_list_select_from_sequence to type_list_select_from_index_sequence * Replaced type_list_size<TTypeList>::value with TTypeList::size internally for better clarity. * Added etl::type_list_remove, etl::type_list_remove_if, etl::type_list_unique, etl::type_list_pop_front, etl::type_list_pop_back * Add ref-qualifiers to basic_format_spec (#1292) * Remove AppVeyor build status badge Removed AppVeyor build status badge from README. * Update README.md * Update CONTRIBUTING.md Updated the instructions for contributing. * Fix for issue 1276 "Data corruption in the etl::bip_buffer_spsc_atomic" (#1277) * Reproduce data corruption bug in the `etl::bip_buffer_spsc_atomic`. * Fix data corruption bug in the `etl::bip_buffer_spsc_atomic`. * feat: use ref-qualifiers for basic_format_spec Converted the l-value methods to ref-qualified and also added r-value ref-qualified methods. --------- Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com> Co-authored-by: Sergei <sergej.shirokov@gmail.com> * Add support for size_t and unsigned long to etl::format (#1290) * Remove AppVeyor build status badge Removed AppVeyor build status badge from README. * Update README.md * Update CONTRIBUTING.md Updated the instructions for contributing. * Fix for issue 1276 "Data corruption in the etl::bip_buffer_spsc_atomic" (#1277) * Reproduce data corruption bug in the `etl::bip_buffer_spsc_atomic`. * Fix data corruption bug in the `etl::bip_buffer_spsc_atomic`. * Add support for size_t and unsigned long to etl::format * Document list of supported types in etl::supported_format_types * Add further types and tests for etl::format --------- Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com> Co-authored-by: Sergei <sergej.shirokov@gmail.com> * Deduce underlying storage size when constructing string_ext from char[]. (#1269) * Deduce underlying storage size when constructing string_ext from char[]. This removes the need for passing sizeof(storage) to the constructor. * Add array constructors for the other string types. - u16string_ext - u32string_ext - u8string_ext - wstring_ext * Add additional constructors to match existing API. * Fix inconsistent test argument order. --------- Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com> * Added etl::type_list_all_of, etl::type_list_any_of, and etl::type_list_none_of * Added etl::type_list_is_unique * Added type_list_is_empty * indentation fix * Fix merge error * Renamed type_list_prepend & type_list_append to type_list_push_front & type_list_push_back respectively * Added tests for make_index_sequence & make_index_sequence_with_offset * Resolve coderabbit review issues * Resolve coderabbit review issues * Resolve coderabbit review issues * Resolve coderabbit review issues * Added etl::type_list_indices_of_type which create an etl::index_sequence of all of the indexes of a specified type in an etl::type_list * Updated comments * Resolve coderabbit review issues Added index_sequence utility to support type_list utilities. Added additional index_sequence utilities for completeness * Added etl::index_sequence_cat, etl::index_sequence_pop_front, etl::index_sequence_pop_back, etl::index_sequence_at * Fix 'unused variable' error in index_sequence tests --------- Co-authored-by: John Wellbelove <john.wellbelove@etlcpp.co.uk> Co-authored-by: Sergei <sergej.shirokov@gmail.com> Co-authored-by: John Wellbelove <john.wellbelove@etlcpp.com> Co-authored-by: Bo Rydberg <2945606+bolry@users.noreply.github.com> Co-authored-by: Roland Reichwein <Roland.Reichwein@bmw.de> Co-authored-by: Mike Bloom <91038685+mike919192@users.noreply.github.com> Co-authored-by: taltenbach <92919739+taltenbach@users.noreply.github.com> Co-authored-by: Bryton Flecker <fleckerbr@gmail.com> Co-authored-by: Bryton Flecker <bflecker@swe.com> Co-authored-by: Drew Rife <drew.rife95@gmail.com> Co-authored-by: Marco Nilsson <marco@zyax.se>
This commit is contained in:
parent
58b5bf5190
commit
7a8944224b
@ -177,8 +177,10 @@ namespace etl
|
||||
using type_list_type_at_index_t = typename type_list_type_at_index<TTypeList, Index>::type;
|
||||
|
||||
//***************************************************************************
|
||||
/// Defines an integral constant that is the index of the specified type in the type_list.
|
||||
/// Defines an integral constant that is the index of the <i>first</i> instance of specified type 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.
|
||||
//***************************************************************************
|
||||
template <typename TTypeList, typename T>
|
||||
struct type_list_index_of_type
|
||||
@ -200,6 +202,56 @@ namespace etl
|
||||
inline constexpr size_t type_list_index_of_v = etl::type_list_index_of_type<TTypeList, T>::value;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// 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.
|
||||
//***************************************************************************
|
||||
namespace private_type_list
|
||||
{
|
||||
template <typename TTypeList, typename T, size_t Index, typename TResult>
|
||||
struct type_list_indices_of_type_impl;
|
||||
|
||||
// The general case, check the head type, then recurse with the rest of the types.
|
||||
template <typename Head, typename... Tail, typename T, size_t Index, typename TResult>
|
||||
struct type_list_indices_of_type_impl<etl::type_list<Head, Tail...>, T, Index, TResult>
|
||||
{
|
||||
private:
|
||||
|
||||
// If Head is the same as T then append a new index to the result, otherwise no change.
|
||||
using next_result = etl::conditional_t<etl::is_same<Head, T>::value,
|
||||
etl::index_sequence_push_back_t<TResult, Index>,
|
||||
TResult>;
|
||||
|
||||
public:
|
||||
|
||||
// Recurse with the rest of the type_list, passing on the current result.
|
||||
using type = typename type_list_indices_of_type_impl<etl::type_list<Tail...>, T, Index + 1U, next_result>::type;
|
||||
};
|
||||
|
||||
// Specialisation for an empty type_list.
|
||||
// This is the terminating specialisation for the general case.
|
||||
template <typename T, size_t Index, typename TResult>
|
||||
struct type_list_indices_of_type_impl<etl::type_list<>, T, Index, TResult>
|
||||
{
|
||||
using type = TResult;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename TTypeList, typename T>
|
||||
struct type_list_indices_of_type
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_type_list<TTypeList>::value), "TTypeList must be an etl::type_list");
|
||||
|
||||
using type = typename private_type_list::type_list_indices_of_type_impl<TTypeList, T, 0U, etl::index_sequence<>>::type;
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
template <typename TTypeList, typename T>
|
||||
using type_list_indices_of_type_t = typename type_list_indices_of_type<TTypeList, T>::type;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// Defines a bool constant that is true if the type_list contains the specified type, otherwise false.
|
||||
//***************************************************************************
|
||||
@ -318,7 +370,7 @@ namespace etl
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// Declares a new type_list by selecting types from a given type_list, according to an index sequence.
|
||||
/// Declares a new type_list by selecting types from a given type_list, according to a list if indices.
|
||||
//***************************************************************************
|
||||
template <typename TTypeList, size_t... Indices>
|
||||
struct type_list_select
|
||||
@ -379,14 +431,8 @@ namespace etl
|
||||
using type = type_list<T, TTypes...>;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct type_list_push_front<T>
|
||||
{
|
||||
using type = etl::type_list<T>;
|
||||
};
|
||||
|
||||
template <typename TypeList, typename T>
|
||||
using type_list_prepend_t = typename type_list_push_front<TypeList, T>::type;
|
||||
using type_list_push_front_t = typename type_list_push_front<TypeList, T>::type;
|
||||
|
||||
//***************************************************************************
|
||||
/// Add a type to the end of a type_list.
|
||||
@ -400,14 +446,8 @@ namespace etl
|
||||
using type = type_list<TTypes..., T>;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct type_list_push_back<T>
|
||||
{
|
||||
using type = etl::type_list<T>;
|
||||
};
|
||||
|
||||
template <typename TypeList, typename T>
|
||||
using type_list_append_t = typename type_list_push_back<TypeList, T>::type;
|
||||
using type_list_push_back_t = typename type_list_push_back<TypeList, T>::type;
|
||||
|
||||
//***************************************************************************
|
||||
/// Insert a type at an index in a type_list.
|
||||
@ -420,7 +460,7 @@ namespace etl
|
||||
private:
|
||||
|
||||
ETL_STATIC_ASSERT((etl::is_type_list<TTypeList>::value), "TTypeList must be an etl::type_list");
|
||||
ETL_STATIC_ASSERT(Index <= TTypeList::size, "Index out of range");
|
||||
ETL_STATIC_ASSERT(Index <= TTypeList::size, "Index out of range");
|
||||
|
||||
using index_sequence_for_prefix = etl::make_index_sequence<Index>;
|
||||
using index_sequence_for_suffix = etl::make_index_sequence_with_offset<Index, TTypeList::size - Index>;
|
||||
@ -492,7 +532,7 @@ namespace etl
|
||||
|
||||
using type = typename etl::conditional<TPredicate<Head>::value,
|
||||
rest,
|
||||
etl::type_list_prepend_t<rest, Head>>::type;
|
||||
etl::type_list_push_front_t<rest, Head>>::type;
|
||||
};
|
||||
}
|
||||
|
||||
@ -582,7 +622,7 @@ namespace etl
|
||||
|
||||
using next_result = etl::conditional_t<etl::type_list_contains<TResult, Head>::value,
|
||||
TResult,
|
||||
etl::type_list_append_t<TResult, Head>>;
|
||||
etl::type_list_push_back_t<TResult, Head>>;
|
||||
|
||||
public:
|
||||
|
||||
@ -661,7 +701,7 @@ namespace etl
|
||||
|
||||
template <template <typename> class TPredicate>
|
||||
struct type_list_all_of<etl::type_list<>, TPredicate>
|
||||
: etl::bool_constant<false>
|
||||
: etl::bool_constant<true>
|
||||
{
|
||||
};
|
||||
|
||||
@ -771,7 +811,7 @@ namespace etl
|
||||
|
||||
//*********************************
|
||||
// Ensure that the list is sorted.
|
||||
// Recursively the head to the next to ensure that the list is sorted.
|
||||
// Recursively compare the head to the next element to ensure that the list is sorted.
|
||||
template <typename Head, typename Next, typename... Tail, template <typename, typename> class TCompare>
|
||||
struct type_list_is_sorted_impl<etl::type_list<Head, Next, Tail...>, TCompare>
|
||||
: etl::bool_constant<!TCompare<Next, Head>::value &&
|
||||
@ -841,7 +881,7 @@ namespace etl
|
||||
template <typename Head, typename T, template <typename, typename> class TCompare, typename... Tail>
|
||||
struct insert_sorted_impl<false, Head, T, TCompare, Tail...>
|
||||
{
|
||||
using type = etl::type_list_prepend_t<typename type_list_insert_sorted_impl<etl::type_list<Tail...>, T, TCompare>::type, Head>;
|
||||
using type = etl::type_list_push_front_t<typename type_list_insert_sorted_impl<etl::type_list<Tail...>, T, TCompare>::type, Head>;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -532,13 +532,13 @@ namespace etl
|
||||
class integer_sequence
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Integral types only");
|
||||
|
||||
typedef T value_type;
|
||||
|
||||
static ETL_CONSTEXPR size_t size() ETL_NOEXCEPT
|
||||
{
|
||||
|
||||
static ETL_CONSTEXPR size_t size() ETL_NOEXCEPT
|
||||
{
|
||||
return sizeof...(Integers);
|
||||
}
|
||||
};
|
||||
@ -577,7 +577,7 @@ namespace etl
|
||||
using make_index_sequence = typename private_integer_sequence::make_index_sequence<Count, etl::integer_sequence<size_t>>::type;
|
||||
|
||||
//***********************************
|
||||
/// Make an integer sequence with an offset.
|
||||
/// Make an integer sequence with an offset.
|
||||
//***********************************
|
||||
template <size_t Offset, size_t Count>
|
||||
using make_index_sequence_with_offset = typename private_integer_sequence::offset_index_sequence<Offset, etl::make_index_sequence<Count>>::type;
|
||||
@ -604,16 +604,164 @@ namespace etl
|
||||
};
|
||||
}
|
||||
|
||||
// Accepts either a parameter pack of types or a single etl::type_list<T...>
|
||||
//***********************************
|
||||
/// Make an index sequence for a parameter pack of types or an etl::type_list<T...>.
|
||||
/// Accepts either a parameter pack of types or a single etl::type_list<T...>
|
||||
//***********************************
|
||||
template <typename... TTypes>
|
||||
using make_index_sequence_for = typename private_make_index_sequence_for::impl<TTypes...>::type;
|
||||
|
||||
//***********************************
|
||||
/// An index sequence.
|
||||
//***********************************
|
||||
template <size_t... Indices>
|
||||
using index_sequence = etl::integer_sequence<size_t, Indices...>;
|
||||
|
||||
//************************************
|
||||
/// Alias for make_index_sequence_for.
|
||||
//************************************
|
||||
template <typename... TTypes>
|
||||
using index_sequence_for = typename etl::make_index_sequence_for<TTypes...>;
|
||||
|
||||
//************************************
|
||||
/// Concatenates two index_sequences.
|
||||
//************************************
|
||||
template <typename TIndexSequence1, typename TIndexSequence2>
|
||||
struct index_sequence_cat;
|
||||
|
||||
template <size_t... Indices1, size_t... Indices2>
|
||||
struct index_sequence_cat<etl::index_sequence<Indices1...>, etl::index_sequence<Indices2...>>
|
||||
{
|
||||
using type = etl::index_sequence<Indices1..., Indices2...>;
|
||||
};
|
||||
|
||||
template <typename TIndexSequence1, typename TIndexSequence2>
|
||||
using index_sequence_cat_t = typename index_sequence_cat<TIndexSequence1, TIndexSequence2>::type;
|
||||
|
||||
//************************************
|
||||
/// Pushes an index to the front of an index_sequence.
|
||||
//************************************
|
||||
template <typename TIndexSequence, size_t Index>
|
||||
struct index_sequence_push_front;
|
||||
|
||||
template <size_t... Indices, size_t Index>
|
||||
struct index_sequence_push_front<etl::index_sequence<Indices...>, Index>
|
||||
{
|
||||
// Adds the new index to the front of the sequence.
|
||||
using type = etl::index_sequence<Index, Indices...>;
|
||||
};
|
||||
|
||||
template <typename TIndexSequence, size_t Index>
|
||||
using index_sequence_push_front_t = typename index_sequence_push_front<TIndexSequence, Index>::type;
|
||||
|
||||
//************************************
|
||||
/// Pop an index from the front of an index_sequence.
|
||||
//************************************
|
||||
template <typename TIndexSequence>
|
||||
struct index_sequence_pop_front;
|
||||
|
||||
template <>
|
||||
struct index_sequence_pop_front<etl::index_sequence<>>
|
||||
{
|
||||
using type = etl::index_sequence<>;
|
||||
};
|
||||
|
||||
template <size_t Index, size_t... Indices>
|
||||
struct index_sequence_pop_front<etl::index_sequence<Index, Indices...>>
|
||||
{
|
||||
// Removes the front index by declaring the type to be the tail of the sequence.
|
||||
using type = etl::index_sequence<Indices...>;
|
||||
};
|
||||
|
||||
template <typename TIndexSequence>
|
||||
using index_sequence_pop_front_t = typename index_sequence_pop_front<TIndexSequence>::type;
|
||||
|
||||
//************************************
|
||||
/// Pushes an index to the back of an index_sequence.
|
||||
//************************************
|
||||
template <typename TIndexSequence, size_t Index>
|
||||
struct index_sequence_push_back;
|
||||
|
||||
template <size_t... Indices, size_t Index>
|
||||
struct index_sequence_push_back<etl::index_sequence<Indices...>, Index>
|
||||
{
|
||||
// Adds the new index to the back of the sequence by concatenating the new index with the sequence.
|
||||
using type = etl::index_sequence<Indices..., Index>;
|
||||
};
|
||||
|
||||
template <typename TIndexSequence, size_t Index>
|
||||
using index_sequence_push_back_t = typename index_sequence_push_back<TIndexSequence, Index>::type;
|
||||
|
||||
//************************************
|
||||
/// Pop an index from the back of an index_sequence.
|
||||
//************************************
|
||||
template <typename TIndexSequence>
|
||||
struct index_sequence_pop_back;
|
||||
|
||||
// Pop back of and empty sequence is an empty sequence.
|
||||
template <>
|
||||
struct index_sequence_pop_back<etl::index_sequence<>>
|
||||
{
|
||||
using type = etl::index_sequence<>;
|
||||
};
|
||||
|
||||
// Pop back of a single element sequence is an empty sequence.
|
||||
// The single element is never added to the result, so is effectively removed.
|
||||
// This is the terminating specialisation for the general case.
|
||||
template <size_t Index>
|
||||
struct index_sequence_pop_back<etl::index_sequence<Index>>
|
||||
{
|
||||
using type = etl::index_sequence<>;
|
||||
};
|
||||
|
||||
// Multi element sequence. Pop back is the front element concatenated with the pop back of the tail.
|
||||
template <size_t Index, size_t... Indices>
|
||||
struct index_sequence_pop_back<etl::index_sequence<Index, Indices...>>
|
||||
{
|
||||
// Removes the last index by concatenating the front index with the pop back of the tail.
|
||||
// The last index is never added to the result, so is effectively removed.
|
||||
using type = etl::index_sequence_cat_t<etl::index_sequence<Index>,
|
||||
typename index_sequence_pop_back<etl::index_sequence<Indices...>>::type>;
|
||||
};
|
||||
|
||||
template <typename TIndexSequence>
|
||||
using index_sequence_pop_back_t = typename index_sequence_pop_back<TIndexSequence>::type;
|
||||
|
||||
//************************************
|
||||
/// Gets the index at the Nth position in an index_sequence.
|
||||
//************************************
|
||||
template <typename TIndexSequence, size_t Nth>
|
||||
struct index_sequence_at;
|
||||
|
||||
template <size_t Nth>
|
||||
struct index_sequence_at<etl::index_sequence<>, Nth>
|
||||
{
|
||||
template <size_t>
|
||||
struct dependent_false : etl::false_type {};
|
||||
|
||||
static_assert(dependent_false<Nth>::value, "Nth out of range for index_sequence_at");
|
||||
};
|
||||
|
||||
// When Nth is 0, the index at the Nth position is the front index of the sequence.
|
||||
template <size_t Index, size_t... Indices>
|
||||
struct index_sequence_at<etl::index_sequence<Index, Indices...>, 0>
|
||||
{
|
||||
static constexpr size_t value = Index;
|
||||
};
|
||||
|
||||
// When Nth is greater than 0, recurse with the tail of the sequence and Nth - 1.
|
||||
template <size_t Index, size_t... Indices, size_t Nth>
|
||||
struct index_sequence_at<etl::index_sequence<Index, Indices...>, Nth>
|
||||
{
|
||||
static_assert(Nth < sizeof...(Indices) + 1U, "Nth out of range for index_sequence_at");
|
||||
|
||||
static constexpr size_t value = index_sequence_at<etl::index_sequence<Indices...>, Nth - 1U>::value;
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename TIndexSequence, size_t Nth>
|
||||
inline constexpr size_t index_sequence_at_v = index_sequence_at<TIndexSequence, Nth>::value;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
@ -651,9 +799,9 @@ namespace etl
|
||||
//***************************************************************************
|
||||
/// in_place disambiguation tags.
|
||||
//***************************************************************************
|
||||
|
||||
|
||||
//*************************
|
||||
struct in_place_t
|
||||
struct in_place_t
|
||||
{
|
||||
explicit ETL_CONSTEXPR in_place_t() {}
|
||||
};
|
||||
@ -661,9 +809,9 @@ namespace etl
|
||||
#if ETL_USING_CPP17
|
||||
inline constexpr in_place_t in_place{};
|
||||
#endif
|
||||
|
||||
|
||||
//*************************
|
||||
template <typename T> struct in_place_type_t
|
||||
template <typename T> struct in_place_type_t
|
||||
{
|
||||
explicit ETL_CONSTEXPR in_place_type_t() {}
|
||||
};
|
||||
@ -674,7 +822,7 @@ namespace etl
|
||||
#endif
|
||||
|
||||
//*************************
|
||||
template <size_t Index> struct in_place_index_t
|
||||
template <size_t Index> struct in_place_index_t
|
||||
{
|
||||
explicit ETL_CONSTEXPR in_place_index_t() {}
|
||||
};
|
||||
@ -767,7 +915,7 @@ namespace etl
|
||||
// Creates a static member 'call' that calls the specified functor.
|
||||
//*****************************************************************************
|
||||
template <auto& Instance>
|
||||
struct functor_as_static
|
||||
struct functor_as_static
|
||||
{
|
||||
template <typename... TArgs>
|
||||
static constexpr auto call(TArgs&&... args)
|
||||
@ -781,7 +929,7 @@ namespace etl
|
||||
// Creates a static member 'call' that calls the specified member function.
|
||||
//*****************************************************************************
|
||||
template <auto Method, auto& Instance>
|
||||
struct member_function_as_static
|
||||
struct member_function_as_static
|
||||
{
|
||||
template <typename... TArgs>
|
||||
static constexpr auto call(TArgs&&... args)
|
||||
|
||||
@ -58,7 +58,7 @@ namespace
|
||||
|
||||
// Convenience comparator for types that expose a constexpr integral ID (ascending)
|
||||
template <typename T1, typename T2>
|
||||
struct by_ascencding_id : etl::bool_constant<(T1::id < T2::id)>
|
||||
struct by_ascending_id : etl::bool_constant<(T1::id < T2::id)>
|
||||
{
|
||||
};
|
||||
|
||||
@ -223,6 +223,22 @@ namespace
|
||||
#endif
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_indices_of_type)
|
||||
{
|
||||
using t1 = etl::type_list<char, int, char, uint32_t, char, char>;
|
||||
using t2 = etl::type_list<>;
|
||||
|
||||
using indices1 = etl::type_list_indices_of_type_t<t1, char>;
|
||||
using expected1 = etl::index_sequence<0U, 2U, 4U, 5U>;
|
||||
|
||||
using indices2 = etl::type_list_indices_of_type_t<t2, char>;
|
||||
using expected2 = etl::index_sequence<>;
|
||||
|
||||
CHECK_TRUE((etl::is_same<indices1, expected1>::value));
|
||||
CHECK_TRUE((etl::is_same<indices2, expected2>::value));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_type_at_index)
|
||||
{
|
||||
@ -311,7 +327,7 @@ namespace
|
||||
TEST(test_type_list_sort_empty_list)
|
||||
{
|
||||
using list = etl::type_list<>;
|
||||
using result = etl::type_list_sort_t<list, by_ascencding_id>;
|
||||
using result = etl::type_list_sort_t<list, by_ascending_id>;
|
||||
using expected = etl::type_list<>;
|
||||
|
||||
CHECK((etl::is_same<result, expected>::value));
|
||||
@ -322,7 +338,7 @@ namespace
|
||||
TEST(test_type_list_sort_single_list)
|
||||
{
|
||||
using list = etl::type_list<A>;
|
||||
using result = etl::type_list_sort_t<list, by_ascencding_id>;
|
||||
using result = etl::type_list_sort_t<list, by_ascending_id>;
|
||||
using expected = etl::type_list<A>;
|
||||
|
||||
CHECK((etl::is_same<result, expected>::value));
|
||||
@ -333,7 +349,7 @@ namespace
|
||||
TEST(test_type_list_sort_multiple_list)
|
||||
{
|
||||
using list = etl::type_list<B, C, A>;
|
||||
using result = etl::type_list_sort_t<list, by_ascencding_id>;
|
||||
using result = etl::type_list_sort_t<list, by_ascending_id>;
|
||||
using expected = etl::type_list<A, B, C>;
|
||||
|
||||
CHECK((etl::is_same<result, expected>::value));
|
||||
@ -341,32 +357,86 @@ namespace
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_prepend_to_empty_list)
|
||||
{
|
||||
using list = etl::type_list<>;
|
||||
using result = etl::type_list_prepend_t<list, A>;
|
||||
using expected = etl::type_list<A>;
|
||||
|
||||
CHECK((etl::is_same<result, expected>::value));
|
||||
CHECK_EQUAL(1U, etl::type_list_size<result>::value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_prepend_to_non_empty_list)
|
||||
{
|
||||
using list = etl::type_list<B, C>;
|
||||
using result = etl::type_list_prepend_t<list, A>;
|
||||
using expected = etl::type_list<A, B, C>;
|
||||
|
||||
CHECK((etl::is_same<result, expected>::value));
|
||||
CHECK_EQUAL(3U, etl::type_list_size<result>::value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_append_to_empty_list)
|
||||
TEST(test_type_list_is_sorted_for_empty_list)
|
||||
{
|
||||
using list = etl::type_list<>;
|
||||
using result = etl::type_list_append_t<list, A>;
|
||||
|
||||
CHECK((etl::type_list_is_sorted<list, by_ascending_id>::value));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_is_sorted_for_single_list)
|
||||
{
|
||||
using list = etl::type_list<A>;
|
||||
|
||||
CHECK((etl::type_list_is_sorted<list, by_ascending_id>::value));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_is_sorted_for_sorted_list)
|
||||
{
|
||||
using list = etl::type_list<A, B, C>;
|
||||
|
||||
CHECK((etl::type_list_is_sorted<list, by_ascending_id>::value));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_is_sorted_for_unsorted_list)
|
||||
{
|
||||
using list = etl::type_list<B, C, A>;
|
||||
|
||||
CHECK((!etl::type_list_is_sorted<list, by_ascending_id>::value));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_insert_sorted_into_empty_list)
|
||||
{
|
||||
using list = etl::type_list<>;
|
||||
using result = etl::type_list_insert_sorted_t<list, B, by_ascending_id>;
|
||||
using expected = etl::type_list<B>;
|
||||
|
||||
CHECK((etl::is_same<result, expected>::value));
|
||||
CHECK_EQUAL(1U, etl::type_list_size<result>::value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_insert_sorted_before_head)
|
||||
{
|
||||
using list = etl::type_list<B, C>;
|
||||
using result = etl::type_list_insert_sorted_t<list, A, by_ascending_id>;
|
||||
using expected = etl::type_list<A, B, C>;
|
||||
|
||||
CHECK((etl::is_same<result, expected>::value));
|
||||
CHECK_EQUAL(3U, etl::type_list_size<result>::value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_insert_sorted_in_middle)
|
||||
{
|
||||
using list = etl::type_list<A, C>;
|
||||
using result = etl::type_list_insert_sorted_t<list, B, by_ascending_id>;
|
||||
using expected = etl::type_list<A, B, C>;
|
||||
|
||||
CHECK((etl::is_same<result, expected>::value));
|
||||
CHECK_EQUAL(3U, etl::type_list_size<result>::value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_insert_sorted_at_end)
|
||||
{
|
||||
using list = etl::type_list<A, B>;
|
||||
using result = etl::type_list_insert_sorted_t<list, C, by_ascending_id>;
|
||||
using expected = etl::type_list<A, B, C>;
|
||||
|
||||
CHECK((etl::is_same<result, expected>::value));
|
||||
CHECK_EQUAL(3U, etl::type_list_size<result>::value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_push_front_to_empty_list)
|
||||
{
|
||||
using list = etl::type_list<>;
|
||||
using result = etl::type_list_push_front_t<list, A>;
|
||||
using expected = etl::type_list<A>;
|
||||
|
||||
CHECK((etl::is_same<result, expected>::value));
|
||||
@ -374,10 +444,32 @@ namespace
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_append_to_non_empty_list)
|
||||
TEST(test_type_list_push_front_to_non_empty_list)
|
||||
{
|
||||
using list = etl::type_list<B, C>;
|
||||
using result = etl::type_list_push_front_t<list, A>;
|
||||
using expected = etl::type_list<A, B, C>;
|
||||
|
||||
CHECK((etl::is_same<result, expected>::value));
|
||||
CHECK_EQUAL(3U, etl::type_list_size<result>::value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_push_back_to_empty_list)
|
||||
{
|
||||
using list = etl::type_list<>;
|
||||
using result = etl::type_list_push_back_t<list, A>;
|
||||
using expected = etl::type_list<A>;
|
||||
|
||||
CHECK((etl::is_same<result, expected>::value));
|
||||
CHECK_EQUAL(1U, etl::type_list_size<result>::value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_push_back_to_non_empty_list)
|
||||
{
|
||||
using list = etl::type_list<A, B>;
|
||||
using result = etl::type_list_append_t<list, C>;
|
||||
using result = etl::type_list_push_back_t<list, C>;
|
||||
using expected = etl::type_list<A, B, C>;
|
||||
|
||||
CHECK((etl::is_same<result, expected>::value));
|
||||
@ -532,7 +624,7 @@ namespace
|
||||
// Uncomment to generate static_assert error.
|
||||
|
||||
//using list = etl::type_list<>;
|
||||
//using result1 = etl::type_list_pop_front_t<list>;
|
||||
//using result1 = etl::type_list_pop_back_t<list>;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -583,14 +675,14 @@ namespace
|
||||
{
|
||||
using list1 = etl::type_list<>;
|
||||
|
||||
CHECK_FALSE((etl::type_list_all_of<list1, is_type_a>::value));
|
||||
CHECK_FALSE((etl::type_list_all_of<list1, is_type_b>::value));
|
||||
CHECK_FALSE((etl::type_list_all_of<list1, is_type_c>::value));
|
||||
CHECK_TRUE((etl::type_list_all_of<list1, is_type_a>::value));
|
||||
CHECK_TRUE((etl::type_list_all_of<list1, is_type_b>::value));
|
||||
CHECK_TRUE((etl::type_list_all_of<list1, is_type_c>::value));
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
CHECK_FALSE((etl::type_list_all_of_v<list1, is_type_a>));
|
||||
CHECK_FALSE((etl::type_list_all_of_v<list1, is_type_b>));
|
||||
CHECK_FALSE((etl::type_list_all_of_v<list1, is_type_c>));
|
||||
CHECK_TRUE((etl::type_list_all_of_v<list1, is_type_a>));
|
||||
CHECK_TRUE((etl::type_list_all_of_v<list1, is_type_b>));
|
||||
CHECK_TRUE((etl::type_list_all_of_v<list1, is_type_c>));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -713,6 +805,21 @@ namespace
|
||||
#endif
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_is_unique_for_non_empty_list)
|
||||
{
|
||||
using list1 = etl::type_list<A, B, C>;
|
||||
using list2 = etl::type_list<A, B, A>;
|
||||
|
||||
CHECK_TRUE((etl::type_list_is_unique<list1>::value));
|
||||
CHECK_FALSE((etl::type_list_is_unique<list2>::value));
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
CHECK_TRUE((etl::type_list_is_unique_v<list1>));
|
||||
CHECK_FALSE((etl::type_list_is_unique_v<list2>));
|
||||
#endif
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_is_empty)
|
||||
{
|
||||
|
||||
@ -927,5 +927,107 @@ namespace
|
||||
CHECK_TRUE((std::is_same<seq2, expect2>::value));
|
||||
CHECK_TRUE((std::is_same<seq4, expect4>::value));
|
||||
}
|
||||
|
||||
//*********************************
|
||||
TEST(test_index_sequence_push_front_matches_expected)
|
||||
{
|
||||
using seq0 = etl::index_sequence<>;
|
||||
using seq1 = etl::index_sequence<1U, 2U>;
|
||||
using result0 = etl::index_sequence_push_front_t<seq0, 5U>;
|
||||
using result1 = etl::index_sequence_push_front_t<seq1, 0U>;
|
||||
using expect0 = etl::index_sequence<5U>;
|
||||
using expect1 = etl::index_sequence<0U, 1U, 2U>;
|
||||
|
||||
CHECK_TRUE((std::is_same<result0, expect0>::value));
|
||||
CHECK_TRUE((std::is_same<result1, expect1>::value));
|
||||
}
|
||||
|
||||
//*********************************
|
||||
TEST(test_index_sequence_pop_front_matches_expected)
|
||||
{
|
||||
using seq0 = etl::index_sequence<>;
|
||||
using seq1 = etl::index_sequence<1U, 2U>;
|
||||
using result0 = etl::index_sequence_pop_front_t<seq0>;
|
||||
using result1 = etl::index_sequence_pop_front_t<seq1>;
|
||||
using expect0 = etl::index_sequence<>;
|
||||
using expect1 = etl::index_sequence<2U>;
|
||||
|
||||
CHECK_TRUE((std::is_same<result0, expect0>::value));
|
||||
CHECK_TRUE((std::is_same<result1, expect1>::value));
|
||||
}
|
||||
|
||||
//*********************************
|
||||
TEST(test_index_sequence_push_back_matches_expected)
|
||||
{
|
||||
using seq0 = etl::index_sequence<>;
|
||||
using seq1 = etl::index_sequence<1U, 2U>;
|
||||
using result0 = etl::index_sequence_push_back_t<seq0, 5U>;
|
||||
using result1 = etl::index_sequence_push_back_t<seq1, 3U>;
|
||||
using expect0 = etl::index_sequence<5U>;
|
||||
using expect1 = etl::index_sequence<1U, 2U, 3U>;
|
||||
|
||||
CHECK_TRUE((std::is_same<result0, expect0>::value));
|
||||
CHECK_TRUE((std::is_same<result1, expect1>::value));
|
||||
}
|
||||
|
||||
//*********************************
|
||||
TEST(test_index_sequence_pop_back_matches_expected)
|
||||
{
|
||||
using seq0 = etl::index_sequence<>;
|
||||
using seq1 = etl::index_sequence<1U, 2U>;
|
||||
using result0 = etl::index_sequence_pop_back_t<seq0>;
|
||||
using result1 = etl::index_sequence_pop_back_t<seq1>;
|
||||
using expect0 = etl::index_sequence<>;
|
||||
using expect1 = etl::index_sequence<1U>;
|
||||
|
||||
CHECK_TRUE((std::is_same<result0, expect0>::value));
|
||||
CHECK_TRUE((std::is_same<result1, expect1>::value));
|
||||
}
|
||||
|
||||
//*********************************
|
||||
TEST(test_index_sequence_cat_matches_expected)
|
||||
{
|
||||
using seq0 = etl::index_sequence<>;
|
||||
using seq1 = etl::index_sequence<0U, 1U>;
|
||||
using seq2 = etl::index_sequence<2U, 3U>;
|
||||
using result0 = etl::index_sequence_cat_t<seq0, seq1>;
|
||||
using result1 = etl::index_sequence_cat_t<seq1, seq2>;
|
||||
using expect0 = etl::index_sequence<0U, 1U>;
|
||||
using expect1 = etl::index_sequence<0U, 1U, 2U, 3U>;
|
||||
|
||||
CHECK_TRUE((std::is_same<result0, expect0>::value));
|
||||
CHECK_TRUE((std::is_same<result1, expect1>::value));
|
||||
}
|
||||
|
||||
//*********************************
|
||||
TEST(test_index_sequence_at_matches_expected)
|
||||
{
|
||||
// using seq0 = etl::index_sequence<>; // This should fail to compile as seq0 is empty
|
||||
using seq1 = etl::index_sequence<1U, 2U, 3U>;
|
||||
//using result0 = etl::index_sequence_at<seq0, 0>; // This should fail to compile as seq0 is empty
|
||||
//auto ignore0 = result0; // Uses result0
|
||||
size_t result1a = etl::index_sequence_at<seq1, 0>::value;
|
||||
size_t result1b = etl::index_sequence_at<seq1, 1>::value;
|
||||
size_t result1c = etl::index_sequence_at<seq1, 2>::value;
|
||||
//size_t result1d = etl::index_sequence_at<seq1, 3>::value; // This should fail to compile as seq1 only has 3 elements
|
||||
//auto ignore1d = result1d; // Uses result1d
|
||||
size_t expect1a = 1U;
|
||||
size_t expect1b = 2U;
|
||||
size_t expect1c = 3U;
|
||||
|
||||
CHECK_EQUAL(expect1a, result1a);
|
||||
CHECK_EQUAL(expect1b, result1b);
|
||||
CHECK_EQUAL(expect1c, result1c);
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
size_t result1e = etl::index_sequence_at_v<seq1, 0>;
|
||||
size_t result1f = etl::index_sequence_at_v<seq1, 1>;
|
||||
size_t result1g = etl::index_sequence_at_v<seq1, 2>;
|
||||
|
||||
CHECK_EQUAL(expect1a, result1e);
|
||||
CHECK_EQUAL(expect1b, result1f);
|
||||
CHECK_EQUAL(expect1c, result1g);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user