diff --git a/include/etl/index_of_type.h b/include/etl/index_of_type.h new file mode 100644 index 00000000..5546ad53 --- /dev/null +++ b/include/etl/index_of_type.h @@ -0,0 +1,80 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2025 John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef ETL_INDEX_OF_TYPE_INCLUDED +#define ETL_INDEX_OF_TYPE_INCLUDED + +#include "platform.h" +#include "static_assert.h" +#include "integral_limits.h" + +namespace etl +{ +#if ETL_USING_CPP11 + + //*************************************************************************** + /// Defines a no-position constant. + //*************************************************************************** + static ETL_CONSTANT size_t index_of_type_npos = etl::integral_limits::max; + + //*************************************************************************** + /// Finds the index of a type in a variadic type parameter. + //*************************************************************************** + template + struct index_of_type; + + //*************************************************************************** + /// Finds the index of a type in a variadic type parameter. + //*************************************************************************** + template + struct index_of_type : public etl::integral_constant::value ? 0 : + (etl::index_of_type::value == etl::index_of_type_npos ? etl::index_of_type_npos : + etl::index_of_type::value + 1)> + { + }; + + //*************************************************************************** + /// Finds the index of a type in a variadic type parameter. + /// No types left. + //*************************************************************************** + template + struct index_of_type : public etl::integral_constant + { + }; + +#if ETL_USING_CPP17 + //*************************************************************************** + /// Finds the index of a type in a variadic type parameter. + //*************************************************************************** + template + inline constexpr size_t index_of_type_v = etl::index_of_type::value; +#endif +#endif +} + +#endif diff --git a/include/etl/intrusive_forward_list.h b/include/etl/intrusive_forward_list.h index 6cb44280..7e6d4dba 100644 --- a/include/etl/intrusive_forward_list.h +++ b/include/etl/intrusive_forward_list.h @@ -322,7 +322,10 @@ namespace etl if (p_next != &this->terminator) { link_type* p_unlinked = etl::unlink_after(link); - p_unlinked->clear(); + if (p_unlinked != ETL_NULLPTR) + { + p_unlinked->clear(); + } --current_size; } } diff --git a/include/etl/private/variant_variadic.h b/include/etl/private/variant_variadic.h index 44334669..6874f7f9 100644 --- a/include/etl/private/variant_variadic.h +++ b/include/etl/private/variant_variadic.h @@ -31,13 +31,14 @@ SOFTWARE. #include "../platform.h" #include "../utility.h" #include "../largest.h" +#include "../nth_type.h" #include "../exception.h" #include "../type_traits.h" #include "../integral_limits.h" #include "../static_assert.h" #include "../alignment.h" #include "../error_handler.h" -#include "../parameter_pack.h" +#include "../type_list.h" #include "../placement_new.h" #include "../visitor.h" #include "../memory.h" @@ -66,82 +67,6 @@ namespace etl { namespace private_variant { - //*************************************************************************** - // This is a copy of the normal etl::parameter_pack, but without the static_assert - // so that the C++11 versions of do_visitor() & do_operator() do not throw a compile time error. - //*************************************************************************** - template - class parameter_pack - { - public: - - static constexpr size_t size = sizeof...(TTypes); - - //*************************************************************************** - /// index_of_type - //*************************************************************************** - template - class index_of_type - { - private: - - using type = etl::remove_cvref_t; - - //*********************************** - template - struct index_of_type_helper - { - static constexpr size_t value = etl::is_same::value ? 1 : 1 + index_of_type_helper::value; - }; - - //*********************************** - template - struct index_of_type_helper - { - static constexpr size_t value = 1UL; - }; - - public: - - static_assert(etl::is_one_of::value, "T is not in parameter pack"); - - /// The index value. - static constexpr size_t value = index_of_type_helper::value - 1; - }; - - //*************************************************************************** - /// type_from_index - //*************************************************************************** - template - class type_from_index - { - private: - - //*********************************** - template - struct type_from_index_helper - { - using type = typename etl::conditional::type>::type; - }; - - //*********************************** - template - struct type_from_index_helper - { - using type = T1; - }; - - public: - - /// Template alias - using type = typename type_from_index_helper::type; - }; - - //*********************************** - template - using type_from_index_t = typename type_from_index::type; - }; - //******************************************* // The traits an object may have. //******************************************* @@ -327,7 +252,7 @@ namespace etl template struct variant_alternative> { - using type = typename etl::private_variant::parameter_pack::template type_from_index::type; + using type = nth_type_t; }; template @@ -529,13 +454,13 @@ namespace etl // Get the index of a type. //******************************************* template - using index_of_type = typename etl::private_variant::parameter_pack::template index_of_type>; + using index_of_type = etl::type_list_index_of_type, etl::remove_cvref_t>; //******************************************* // Get the type from the index. //******************************************* template - using type_from_index = typename etl::private_variant::parameter_pack::template type_from_index::type; + using type_from_index = typename etl::type_list_type_at_index, Index>::type; public: @@ -546,7 +471,7 @@ namespace etl #include "diagnostic_uninitialized_push.h" ETL_CONSTEXPR14 variant() { - using type = typename etl::private_variant::parameter_pack::template type_from_index<0U>::type; + using type = type_from_index<0U>; default_construct_in_place(data); operation = operation_type::value, etl::is_move_constructible::value>::do_operation; @@ -592,7 +517,7 @@ namespace etl ETL_CONSTEXPR14 explicit variant(etl::in_place_index_t, TArgs&&... args) : type_id(Index) { - using type = typename private_variant::parameter_pack:: template type_from_index_t; + using type = type_from_index; static_assert(etl::is_one_of ::value, "Unsupported type"); construct_in_place_args(data, etl::forward(args)...); @@ -625,7 +550,7 @@ namespace etl ETL_CONSTEXPR14 explicit variant(etl::in_place_index_t, std::initializer_list init, TArgs&&... args) : type_id(Index) { - using type = typename private_variant::parameter_pack:: template type_from_index_t; + using type = type_from_index; static_assert(etl::is_one_of ::value, "Unsupported type"); construct_in_place_args(data, init, etl::forward(args)...); @@ -715,7 +640,7 @@ namespace etl operation = operation_type::value, etl::is_move_constructible::value>::do_operation; - type_id = etl::private_variant::parameter_pack::template index_of_type::value; + type_id = index_of_type::value; return *static_cast(data); } @@ -737,7 +662,7 @@ namespace etl operation = operation_type::value, etl::is_move_constructible::value>::do_operation; - type_id = etl::private_variant::parameter_pack::template index_of_type::value; + type_id = index_of_type::value; return *static_cast(data); } @@ -747,9 +672,9 @@ namespace etl /// Emplace by index with variadic constructor parameters. //*************************************************************************** template - typename etl::variant_alternative>::type& emplace(TArgs&&... args) + typename etl::variant_alternative>::type& emplace(TArgs&&... args) { - static_assert(Index < etl::private_variant::parameter_pack::size, "Index out of range"); + static_assert(Index < sizeof...(TTypes), "Index out of range"); using type = type_from_index; @@ -769,9 +694,9 @@ namespace etl /// Emplace by index with variadic constructor parameters. //*************************************************************************** template - typename etl::variant_alternative>::type& emplace(std::initializer_list il, TArgs&&... args) + typename etl::variant_alternative>::type& emplace(std::initializer_list il, TArgs&&... args) { - static_assert(Index < etl::private_variant::parameter_pack::size, "Index out of range"); + static_assert(Index < sizeof...(TTypes), "Index out of range"); using type = type_from_index; @@ -803,7 +728,7 @@ namespace etl construct_in_place(data, etl::forward(value)); operation = operation_type::value, etl::is_move_constructible::value>::do_operation; - type_id = etl::private_variant::parameter_pack::template index_of_type::value; + type_id = index_of_type::value; return *this; } @@ -896,7 +821,7 @@ namespace etl template (), int> = 0> constexpr bool is_type() const noexcept { - return (type_id == etl::private_variant::parameter_pack::template index_of_type::value); + return (type_id == index_of_type::value); } //*************************************************************************** @@ -1469,7 +1394,7 @@ namespace etl template ETL_CONSTEXPR14 bool holds_alternative(const etl::variant& v) noexcept { - constexpr size_t Index = etl::private_variant::parameter_pack::template index_of_type::value; + constexpr size_t Index = etl::type_list_index_of_type, T>::value; return (Index == variant_npos) ? false : (v.index() == Index); } @@ -1560,7 +1485,7 @@ namespace etl template ETL_CONSTEXPR14 T& get(etl::variant& v) { - constexpr size_t Index = etl::private_variant::parameter_pack::template index_of_type::value; + constexpr size_t Index = etl::type_list_index_of_type, T>::value; return get(v); } @@ -1569,7 +1494,7 @@ namespace etl template ETL_CONSTEXPR14 T&& get(etl::variant&& v) { - constexpr size_t Index = etl::private_variant::parameter_pack::template index_of_type::value; + constexpr size_t Index = etl::type_list_index_of_type, T>::value; return get(etl::move(v)); } @@ -1578,7 +1503,7 @@ namespace etl template ETL_CONSTEXPR14 const T& get(const etl::variant& v) { - constexpr size_t Index = etl::private_variant::parameter_pack::template index_of_type::value; + constexpr size_t Index = etl::type_list_index_of_type, T>::value; return get(v); } @@ -1587,7 +1512,7 @@ namespace etl template ETL_CONSTEXPR14 const T&& get(const etl::variant&& v) { - constexpr size_t Index = etl::private_variant::parameter_pack::template index_of_type::value; + constexpr size_t Index = etl::type_list_index_of_type, T>::value; return get(etl::move(v)); } @@ -1628,7 +1553,7 @@ namespace etl template< class T, typename... TTypes > ETL_CONSTEXPR14 etl::add_pointer_t get_if(etl::variant* pv) noexcept { - constexpr size_t Index = etl::private_variant::parameter_pack::template index_of_type::value; + constexpr size_t Index = etl::type_list_index_of_type, T>::value; if ((pv != nullptr) && (pv->index() == Index)) { @@ -1644,7 +1569,7 @@ namespace etl template< typename T, typename... TTypes > ETL_CONSTEXPR14 etl::add_pointer_t get_if(const etl::variant* pv) noexcept { - constexpr size_t Index = etl::private_variant::parameter_pack::template index_of_type::value; + constexpr size_t Index = etl::type_list_index_of_type, T>::value; if ((pv != nullptr) && (pv->index() == Index)) { diff --git a/include/etl/type_list.h b/include/etl/type_list.h index 533ae761..4dbc66ec 100644 --- a/include/etl/type_list.h +++ b/include/etl/type_list.h @@ -30,14 +30,23 @@ SOFTWARE. #define ETL_TYPE_LIST_INCLUDED #include "platform.h" -#include "nth_type.h" + +#include "algorithm.h" +#include "index_of_type.h" +#include "integral_limits.h" #include "static_assert.h" #include "type_traits.h" #include "utility.h" +#include "largest.h" #if ETL_USING_CPP11 namespace etl { + //*************************************************************************** + /// Defines a no-position constant. + //*************************************************************************** + static ETL_CONSTANT size_t type_list_npos = etl::integral_limits::max; + //*************************************************************************** /// Type list forward declaration. //*************************************************************************** @@ -61,13 +70,24 @@ namespace etl type_list& operator =(const type_list&) ETL_DELETE; }; + namespace private_type_list + { + // helper to solve the issue that recursed-rest can't be put directly in type_list::tail definition + template + struct recursion_helper + { + using type = type_list; + }; + } + //*************************************************************************** /// Recursive type list implementation for multiple types. //*************************************************************************** template struct type_list : type_list { - using type = THead; + using head = THead; + using tail = typename private_type_list::recursion_helper::type; static constexpr size_t size = sizeof...(TTail) + 1U; @@ -86,7 +106,8 @@ namespace etl template struct type_list : type_list<> { - using type = THead; + using head = THead; + using tail = typename private_type_list::recursion_helper<>::type; static constexpr size_t size = 1U; @@ -99,50 +120,10 @@ namespace etl type_list& operator =(const type_list&) ETL_DELETE; }; - //*************************************************************************** - /// Specialisation of etl::nth_type for etl::type_list - //*************************************************************************** - template - struct nth_type> - { - ETL_STATIC_ASSERT(N <= sizeof...(TTail), "etl::nth_type out of range for etl::type_list"); - - using type = typename nth_type>::type; - }; - - //*************************************************************************** - /// Specialisation of etl::nth_type for etl::type_list with index of 0 - //*************************************************************************** - template - struct nth_type<0, type_list> - { - using type = THead; - }; - - //*************************************************************************** - /// Specialisation of etl::nth_type for empty etl::type_list - //*************************************************************************** - template - struct nth_type> - { - }; - - //*************************************************************************** - /// Declares a new type_list by selecting types from a given type_list, according to an index sequence. - //*************************************************************************** - template - struct type_list_select - { - using type = type_list...>; - }; - - template - using type_list_select_t = typename type_list_select::type; - //*************************************************************************** /// Type list size. //*************************************************************************** - template + template struct type_list_size; template @@ -156,30 +137,156 @@ namespace etl #endif //*************************************************************************** - /// Concatenates two or more type_lists. + /// Defines type as the type found at Index in the type_list. + /// Static asserts if Index is out of range. //*************************************************************************** - template - struct type_list_cat; - - //*************************************************************************** - /// Concatenates two or more type_lists. - /// Specialisation for a single type_list (base case) - //*************************************************************************** - template - struct type_list_cat + template + struct type_list_type_at_index { - using type = TypeList; + 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"); + + using type = typename type_list_type_at_index::type; }; + template + struct type_list_type_at_index + { + using type = typename TTypeList::head; + }; + + template + using type_list_type_at_index_t = typename type_list_type_at_index::type; + + //*************************************************************************** + /// Defines an integral constant that is the index of the specified type in the type_list. + /// If the type is not in the type_list, then defined as etl::type_list_npos. + //*************************************************************************** + template + struct type_list_index_of_type + : public etl::integral_constant::value ? 0 : + (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"); + }; + + template + struct type_list_index_of_type, T> + : public etl::integral_constant + { + }; + +#if ETL_USING_CPP17 + template + inline constexpr size_t type_list_index_of_v = etl::type_list_index_of_type::value; +#endif + + //*************************************************************************** + /// Defines a bool constant that is true if the type_list contains the specified type, otherwise false. + //*************************************************************************** + template + struct type_list_contains; + + template + struct type_list_contains, T> + : public etl::integral_constant::value> + { + }; + + template + struct type_list_contains, T> + : public etl::integral_constant + { + }; + +#if ETL_USING_CPP17 + template + inline constexpr bool type_list_contains_v = etl::type_list_contains::value; +#endif + + //*************************************************************************** + /// Defines an integral constant that is maximum sizeof all types in the type_list. + /// If the type_list is empty, then defined as 0. + //*************************************************************************** + template + struct type_list_max_size; + + template + struct type_list_max_size> + : public etl::integral_constant::size> + { + }; + + template <> + struct type_list_max_size> + : public etl::integral_constant + { + }; + +#if ETL_USING_CPP17 + template + inline constexpr size_t type_list_max_size_v = etl::type_list_max_size::value; +#endif + + //*************************************************************************** + /// Defines an integral constant that is maximum alignment all types in the type_list. + /// If the type_list is empty, then defined as 1. + //*************************************************************************** + template + struct type_list_max_alignment; + + template + struct type_list_max_alignment> + : public etl::integral_constant::alignment> + { + }; + + template <> + struct type_list_max_alignment> + : public etl::integral_constant + { + }; + +#if ETL_USING_CPP17 + template + inline constexpr size_t type_list_max_alignment_v = etl::type_list_max_alignment::value; +#endif + + //*************************************************************************** + /// Declares a new type_list by selecting types from a given type_list, according to an index sequence. + //*************************************************************************** + template + struct type_list_select + { + ETL_STATIC_ASSERT((etl::is_base_of, TTypeList>::value), "TTypeList must be an etl::type_list"); + + using type = type_list...>; + }; + + template + using type_list_select_t = typename type_list_select::type; + //*************************************************************************** /// Concatenates two or more type_lists. - /// Specialisation for two or more type_lists //*************************************************************************** + template + struct type_list_cat; + template struct type_list_cat, etl::type_list, TTail...> { using type = typename type_list_cat, TTail...>::type; }; + + template + struct type_list_cat + { + using type = T; + }; + + template + using type_list_cat_t = typename type_list_cat::type; } #endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bcc8a0da..498fa7db 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -149,6 +149,7 @@ add_executable(etl_tests test_hfsm.cpp test_hfsm_recurse_to_inner_state_on_start.cpp test_histogram.cpp + test_index_of_type.cpp test_indirect_vector.cpp test_indirect_vector_external_buffer.cpp test_instance_count.cpp @@ -286,6 +287,7 @@ add_executable(etl_tests test_to_u8string.cpp test_to_wstring.cpp test_type_def.cpp + test_type_list.cpp test_type_lookup.cpp test_type_select.cpp test_type_traits.cpp diff --git a/test/test_index_of_type.cpp b/test/test_index_of_type.cpp new file mode 100644 index 00000000..60d211e8 --- /dev/null +++ b/test/test_index_of_type.cpp @@ -0,0 +1,58 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2025 John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include "unit_test_framework.h" + +#include "etl/index_of_type.h" +#include + +namespace +{ + SUITE(test_index_of_type) + { + //************************************************************************* + TEST(test_index_of_type) + { + CHECK_EQUAL(0, (etl::index_of_type::value)); + CHECK_EQUAL(1, (etl::index_of_type::value)); + CHECK_EQUAL(2, (etl::index_of_type::value)); + CHECK_EQUAL(etl::index_of_type_npos, (etl::index_of_type::value)); + } + + //************************************************************************* +#if ETL_USING_CPP17 + TEST(test_index_of_type_v) + { + CHECK_EQUAL(0, (etl::index_of_type_v)); + CHECK_EQUAL(1, (etl::index_of_type_v)); + CHECK_EQUAL(2, (etl::index_of_type_v)); + CHECK_EQUAL(etl::index_of_type_npos, (etl::index_of_type_v)); + } +#endif + } +} diff --git a/test/test_map.cpp b/test/test_map.cpp index bd8817ce..2c19e4e4 100644 --- a/test/test_map.cpp +++ b/test/test_map.cpp @@ -37,6 +37,7 @@ SOFTWARE. #include #include "etl/map.h" +#include "etl/string.h" #include "data.h" @@ -1575,7 +1576,7 @@ namespace #if ETL_USING_CPP17 && ETL_HAS_INITIALIZER_LIST && !defined(ETL_TEMPLATE_DEDUCTION_GUIDE_TESTS_DISABLED) TEST_FIXTURE(SetupFixture, test_map_template_deduction) { - using Pair = std::pair; + using Pair = std::pair, int>; etl::map data { Pair{"0", 0}, Pair{"1", 1}, Pair{"2", 2}, Pair{"3", 3}, Pair{"4", 4}, Pair{"5", 5} }; @@ -1596,9 +1597,9 @@ namespace #if ETL_HAS_INITIALIZER_LIST TEST_FIXTURE(SetupFixture, test_make_map) { - using Pair = ETL_OR_STD::pair; + using Pair = ETL_OR_STD::pair, int>; - auto data = etl::make_map>(Pair{ "0", 0 }, Pair{ "1", 1 }, Pair{ "2", 2 }, Pair{ "3", 3 }, Pair{ "4", 4 }, Pair{ "5", 5 }); + auto data = etl::make_map, int, std::less>>(Pair{ "0", 0 }, Pair{ "1", 1 }, Pair{ "2", 2 }, Pair{ "3", 3 }, Pair{ "4", 4 }, Pair{ "5", 5 }); auto v = *data.begin(); using Type = decltype(v); diff --git a/test/test_multi_span.cpp b/test/test_multi_span.cpp index 11c77196..c3e20a6e 100644 --- a/test/test_multi_span.cpp +++ b/test/test_multi_span.cpp @@ -341,14 +341,7 @@ namespace etl::multi_span::iterator ms_itr = ms_int.begin(); etl::multi_span::iterator ms_end_itr = ms_int.end(); - while (ms_itr != ms_end_itr) - { - // Fill the multi span - *ms_itr++ = *exp_itr++; - } - - ms_itr = ms_int.begin(); - exp_itr = expected.begin(); + std::copy(ms_itr, ms_end_itr, exp_itr); while (ms_itr != ms_end_itr) { @@ -554,10 +547,7 @@ namespace multi_span_type::reverse_iterator ms_itr = ms_int.rbegin(); multi_span_type::reverse_iterator ms_end_itr = ms_int.rend(); - while (ms_itr != ms_end_itr) - { - *ms_itr++ = *exp_itr++; - } + std::copy(ms_itr, ms_end_itr, exp_itr); while (ms_itr != ms_end_itr) { diff --git a/test/test_type_list.cpp b/test/test_type_list.cpp new file mode 100644 index 00000000..de9be9fc --- /dev/null +++ b/test/test_type_list.cpp @@ -0,0 +1,185 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2025 BMW AG + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include "unit_test_framework.h" + +#include "etl/type_list.h" + +#include + +namespace +{ +#if ETL_USING_CPP11 + SUITE(test_type_list) + { + //************************************************************************* + TEST(test_type_list_select) + { + typedef etl::type_list t1; + typedef etl::type_list t2; + + CHECK_TRUE((std::is_same::type, t2>::value)); + CHECK_TRUE((std::is_same, t2>::value)); + } + + //************************************************************************* + TEST(test_type_list_size) + { + typedef etl::type_list t1; + typedef etl::type_list t2; + typedef etl::type_list<> t3; + + CHECK_EQUAL(etl::type_list_size::value, 3); + CHECK_EQUAL(etl::type_list_size::value, 2); + CHECK_EQUAL(etl::type_list_size::value, 0); + } + + //************************************************************************* + TEST(test_type_list_cat) + { + typedef etl::type_list t1; + typedef etl::type_list t2; + typedef etl::type_list<> t3; + + typedef etl::type_list t_cat1; + typedef etl::type_list t_cat2; + + CHECK_TRUE((std::is_same::type, t_cat1>::value)); + CHECK_TRUE((std::is_same::type, t_cat1>::value)); + CHECK_FALSE((std::is_same::type, t_cat2>::value)); + + CHECK_TRUE((std::is_same, t_cat1>::value)); + CHECK_TRUE((std::is_same, t_cat1>::value)); + CHECK_FALSE((std::is_same, t_cat2>::value)); + } + + //************************************************************************* + TEST(test_type_list_contains) + { + typedef etl::type_list t1; + typedef etl::type_list t2; + typedef etl::type_list t3; + typedef etl::type_list<> t4; + + CHECK_TRUE((etl::type_list_contains::value)); + CHECK_FALSE((etl::type_list_contains::value)); + CHECK_FALSE((etl::type_list_contains::value)); + CHECK_TRUE((etl::type_list_contains::value)); + CHECK_TRUE((etl::type_list_contains::value)); + CHECK_FALSE((etl::type_list_contains::value)); + CHECK_FALSE((etl::type_list_contains::value)); + +#if ETL_USING_CPP17 + CHECK_TRUE((etl::type_list_contains_v)); + CHECK_FALSE((etl::type_list_contains_v)); + CHECK_FALSE((etl::type_list_contains_v)); + CHECK_TRUE((etl::type_list_contains_v)); + CHECK_TRUE((etl::type_list_contains_v)); + CHECK_FALSE((etl::type_list_contains_v)); + CHECK_FALSE((etl::type_list_contains_v)); +#endif + } + + //************************************************************************* + TEST(test_type_list_index_of_type) + { + typedef etl::type_list t1; + typedef etl::type_list<> t2; + + CHECK_EQUAL((etl::type_list_index_of_type::value), 0); + CHECK_EQUAL((etl::type_list_index_of_type::value), 1); + CHECK_EQUAL((etl::type_list_index_of_type::value), 2); + CHECK_EQUAL((etl::type_list_index_of_type::value), etl::type_list_npos); + +#if ETL_USING_CPP17 + CHECK_EQUAL((etl::type_list_index_of_v), 0); + CHECK_EQUAL((etl::type_list_index_of_v), 1); + CHECK_EQUAL((etl::type_list_index_of_v), 2); + CHECK_EQUAL((etl::type_list_index_of_v), etl::type_list_npos); +#endif + } + + //************************************************************************* + TEST(test_type_list_type_at_index) + { + typedef etl::type_list t1; + + CHECK_TRUE((std::is_same::type>::value)); + CHECK_TRUE((std::is_same::type>::value)); + CHECK_TRUE((std::is_same::type>::value)); + + CHECK_TRUE((std::is_same>::value)); + CHECK_TRUE((std::is_same>::value)); + CHECK_TRUE((std::is_same>::value)); + } + + //************************************************************************* + TEST(test_type_list_max_sizeof_type) + { + typedef etl::type_list t1; + typedef etl::type_list t2; + typedef etl::type_list t3; + typedef etl::type_list<> t4; + + CHECK_EQUAL(etl::type_list_max_size::value, 4); + CHECK_EQUAL(etl::type_list_max_size::value, 2); + CHECK_EQUAL(etl::type_list_max_size::value, 4); + CHECK_EQUAL(etl::type_list_max_size::value, 0); + +#if ETL_USING_CPP17 + CHECK_EQUAL((etl::type_list_max_size_v), 4); + CHECK_EQUAL((etl::type_list_max_size_v), 2); + CHECK_EQUAL((etl::type_list_max_size_v), 4); + CHECK_EQUAL((etl::type_list_max_size_v), 0); +#endif + } + + //************************************************************************* + TEST(test_type_list_max_alignment) + { + typedef etl::type_list t1; + typedef etl::type_list t2; + typedef etl::type_list t3; + typedef etl::type_list<> t4; + + CHECK_EQUAL(etl::type_list_max_alignment::value, std::alignment_of::value); + CHECK_EQUAL(etl::type_list_max_alignment::value, std::alignment_of::value); + CHECK_EQUAL(etl::type_list_max_alignment::value, std::alignment_of::value); + CHECK_EQUAL(etl::type_list_max_alignment::value, 1); + +#if ETL_USING_CPP17 + CHECK_EQUAL((etl::type_list_max_alignment_v), std::alignment_of::value); + CHECK_EQUAL((etl::type_list_max_alignment_v), std::alignment_of::value); + CHECK_EQUAL((etl::type_list_max_alignment_v), std::alignment_of::value); + CHECK_EQUAL((etl::type_list_max_alignment_v), 1); +#endif + } + + }; +#endif +} diff --git a/test/vs2022/etl.vcxproj b/test/vs2022/etl.vcxproj index dfa03400..808b085a 100644 --- a/test/vs2022/etl.vcxproj +++ b/test/vs2022/etl.vcxproj @@ -3169,6 +3169,7 @@ + @@ -8477,6 +8478,7 @@ + @@ -9453,6 +9455,7 @@ + diff --git a/test/vs2022/etl.vcxproj.filters b/test/vs2022/etl.vcxproj.filters index 5251ef8b..f778794a 100644 --- a/test/vs2022/etl.vcxproj.filters +++ b/test/vs2022/etl.vcxproj.filters @@ -1429,7 +1429,10 @@ UnitTest++\Header Files - UnitTest++\Header Files + ETL\Utilities + + + ETL\Utilities @@ -3431,6 +3434,12 @@ Tests\Syntax Checks\Source + + Tests\Types + + + Tests\Types +