mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Add traits to type_list (#1044)
This commit is contained in:
parent
a6615a419d
commit
d9d9ae1e53
@ -30,7 +30,10 @@ SOFTWARE.
|
||||
#define ETL_TYPE_LIST_INCLUDED
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include "algorithm.h"
|
||||
#include "nth_type.h"
|
||||
#include "integral_limits.h"
|
||||
#include "static_assert.h"
|
||||
#include "type_traits.h"
|
||||
#include "utility.h"
|
||||
@ -38,6 +41,9 @@ SOFTWARE.
|
||||
#if ETL_USING_CPP11
|
||||
namespace etl
|
||||
{
|
||||
|
||||
static ETL_CONSTEXPR size_t type_list_npos = etl::integral_limits<size_t>::max;
|
||||
|
||||
//***************************************************************************
|
||||
/// Type list forward declaration.
|
||||
//***************************************************************************
|
||||
@ -61,6 +67,18 @@ 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 <typename... TTypes>
|
||||
struct recursion_helper
|
||||
{
|
||||
using type = type_list<TTypes...>;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Recursive type list implementation for multiple types.
|
||||
//***************************************************************************
|
||||
@ -68,6 +86,7 @@ namespace etl
|
||||
struct type_list<THead, TTail...> : type_list<TTail...>
|
||||
{
|
||||
using type = THead;
|
||||
using tail = typename private_type_list::recursion_helper<TTail...>::type;
|
||||
|
||||
static constexpr size_t size = sizeof...(TTail) + 1U;
|
||||
|
||||
@ -87,6 +106,7 @@ namespace etl
|
||||
struct type_list<THead> : type_list<>
|
||||
{
|
||||
using type = THead;
|
||||
using tail = typename private_type_list::recursion_helper<>::type;
|
||||
|
||||
static constexpr size_t size = 1U;
|
||||
|
||||
@ -180,6 +200,77 @@ namespace etl
|
||||
{
|
||||
using type = typename type_list_cat<etl::type_list<TTypes1..., TTypes2...>, TTail...>::type;
|
||||
};
|
||||
|
||||
template<typename TypeList, typename T>
|
||||
struct type_list_contains
|
||||
: public etl::integral_constant<bool, etl::is_same<typename TypeList::type, T>::value ? true : type_list_contains<typename TypeList::tail, T>::value>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct type_list_contains<type_list<>, T>
|
||||
: public etl::integral_constant<bool, false>
|
||||
{
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template<typename TypeList, typename T>
|
||||
inline constexpr bool type_list_contains_v = etl::type_list_contains<TypeList, T>::value;
|
||||
#endif
|
||||
|
||||
template<typename TypeList, typename T>
|
||||
struct type_list_index_of
|
||||
: public etl::integral_constant<size_t, etl::is_same<typename TypeList::type, T>::value ? 0 :
|
||||
(type_list_index_of<typename TypeList::tail, T>::value == type_list_npos ?
|
||||
type_list_npos : type_list_index_of<typename TypeList::tail, T>::value + 1)>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct type_list_index_of<type_list<>, T>
|
||||
: public etl::integral_constant<size_t, type_list_npos>
|
||||
{
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template<typename TypeList, typename T>
|
||||
inline constexpr size_t type_list_index_of_v = etl::type_list_index_of<TypeList, T>::value;
|
||||
#endif
|
||||
|
||||
template<typename TypeList>
|
||||
struct type_list_max_sizeof_type
|
||||
: public etl::integral_constant<size_t, etl::max(sizeof(typename TypeList::type), type_list_max_sizeof_type<typename TypeList::tail>::value)>
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct type_list_max_sizeof_type<type_list<>>
|
||||
: public etl::integral_constant<size_t, 0>
|
||||
{
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template<typename TypeList>
|
||||
inline constexpr size_t type_list_max_sizeof_type_v = etl::type_list_max_sizeof_type<TypeList>::value;
|
||||
#endif
|
||||
|
||||
template<typename TypeList>
|
||||
struct type_list_max_alignment
|
||||
: public etl::integral_constant<size_t, etl::max(etl::alignment_of<typename TypeList::type>::value,
|
||||
type_list_max_alignment<typename TypeList::tail>::value)>
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct type_list_max_alignment<type_list<>>
|
||||
: public etl::integral_constant<size_t, 1>
|
||||
{
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template<typename TypeList>
|
||||
inline constexpr size_t type_list_max_alignment_v = etl::type_list_max_alignment<TypeList>::value;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -286,6 +286,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
|
||||
|
||||
172
test/test_type_list.cpp
Normal file
172
test/test_type_list.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
/******************************************************************************
|
||||
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 <type_traits>
|
||||
|
||||
namespace
|
||||
{
|
||||
#if ETL_USING_CPP11
|
||||
SUITE(test_type_list)
|
||||
{
|
||||
//*************************************************************************
|
||||
TEST(test_nth_type)
|
||||
{
|
||||
typedef etl::type_list<char, int, uint32_t> t1;
|
||||
|
||||
CHECK_TRUE((std::is_same<etl::nth_type<0, t1>::type, char>::value));
|
||||
CHECK_TRUE((std::is_same<etl::nth_type<1, t1>::type, int>::value));
|
||||
CHECK_TRUE((std::is_same<etl::nth_type<2, t1>::type, uint32_t>::value));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_select)
|
||||
{
|
||||
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<t1, 0, 2>::type, t2>::value));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_size)
|
||||
{
|
||||
typedef etl::type_list<char, int, uint32_t> t1;
|
||||
typedef etl::type_list<char, uint32_t> t2;
|
||||
|
||||
CHECK_EQUAL(etl::type_list_size<t1>::value, 3);
|
||||
CHECK_EQUAL(etl::type_list_size<t2>::value, 2);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
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<char, int, uint32_t, uint8_t, uint16_t> 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_FALSE((std::is_same<etl::type_list_cat<t1, t2>::type, t_cat2>::value));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_contains)
|
||||
{
|
||||
typedef etl::type_list<char, int, uint32_t> t1;
|
||||
typedef etl::type_list<uint8_t, uint16_t> t2;
|
||||
typedef etl::type_list<uint16_t> t3;
|
||||
typedef etl::type_list<> t4;
|
||||
|
||||
CHECK_TRUE((etl::type_list_contains<t1, char>::value));
|
||||
CHECK_FALSE((etl::type_list_contains<t1, uint8_t>::value));
|
||||
CHECK_FALSE((etl::type_list_contains<t2, int>::value));
|
||||
CHECK_TRUE((etl::type_list_contains<t2, uint16_t>::value));
|
||||
CHECK_TRUE((etl::type_list_contains<t3, uint16_t>::value));
|
||||
CHECK_FALSE((etl::type_list_contains<t3, uint32_t>::value));
|
||||
CHECK_FALSE((etl::type_list_contains<t4, uint32_t>::value));
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
CHECK_TRUE((etl::type_list_contains_v<t1, char>));
|
||||
CHECK_FALSE((etl::type_list_contains_v<t1, uint8_t>));
|
||||
CHECK_FALSE((etl::type_list_contains_v<t2, int>));
|
||||
CHECK_TRUE((etl::type_list_contains_v<t2, uint16_t>));
|
||||
CHECK_TRUE((etl::type_list_contains_v<t3, uint16_t>));
|
||||
CHECK_FALSE((etl::type_list_contains_v<t3, uint32_t>));
|
||||
CHECK_FALSE((etl::type_list_contains_v<t4, uint32_t>));
|
||||
#endif
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_index_of)
|
||||
{
|
||||
typedef etl::type_list<char, int, uint32_t> t1;
|
||||
typedef etl::type_list<> t2;
|
||||
|
||||
CHECK_EQUAL((etl::type_list_index_of<t1, char>::value), 0);
|
||||
CHECK_EQUAL((etl::type_list_index_of<t1, int>::value), 1);
|
||||
CHECK_EQUAL((etl::type_list_index_of<t1, uint32_t>::value), 2);
|
||||
CHECK_EQUAL((etl::type_list_index_of<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);
|
||||
#endif
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_max_sizeof_type)
|
||||
{
|
||||
typedef etl::type_list<char, int16_t, uint32_t> t1;
|
||||
typedef etl::type_list<uint8_t, uint16_t> t2;
|
||||
typedef etl::type_list<uint32_t> t3;
|
||||
typedef etl::type_list<> t4;
|
||||
|
||||
CHECK_EQUAL(etl::type_list_max_sizeof_type<t1>::value, 4);
|
||||
CHECK_EQUAL(etl::type_list_max_sizeof_type<t2>::value, 2);
|
||||
CHECK_EQUAL(etl::type_list_max_sizeof_type<t3>::value, 4);
|
||||
CHECK_EQUAL(etl::type_list_max_sizeof_type<t4>::value, 0);
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
CHECK_EQUAL((etl::type_list_max_sizeof_type_v<t1>), 4);
|
||||
CHECK_EQUAL((etl::type_list_max_sizeof_type_v<t2>), 2);
|
||||
CHECK_EQUAL((etl::type_list_max_sizeof_type_v<t3>), 4);
|
||||
CHECK_EQUAL((etl::type_list_max_sizeof_type_v<t4>), 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_type_list_max_alignment)
|
||||
{
|
||||
typedef etl::type_list<char, int16_t, uint32_t> t1;
|
||||
typedef etl::type_list<uint8_t, uint16_t> t2;
|
||||
typedef etl::type_list<uint16_t> t3;
|
||||
typedef etl::type_list<> t4;
|
||||
|
||||
CHECK_EQUAL(etl::type_list_max_alignment<t1>::value, std::alignment_of<uint32_t>::value);
|
||||
CHECK_EQUAL(etl::type_list_max_alignment<t2>::value, std::alignment_of<uint16_t>::value);
|
||||
CHECK_EQUAL(etl::type_list_max_alignment<t3>::value, std::alignment_of<uint16_t>::value);
|
||||
CHECK_EQUAL(etl::type_list_max_alignment<t4>::value, 1);
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
CHECK_EQUAL((etl::type_list_max_alignment_v<t1>), std::alignment_of<uint32_t>::value);
|
||||
CHECK_EQUAL((etl::type_list_max_alignment_v<t2>), std::alignment_of<uint16_t>::value);
|
||||
CHECK_EQUAL((etl::type_list_max_alignment_v<t3>), std::alignment_of<uint16_t>::value);
|
||||
CHECK_EQUAL((etl::type_list_max_alignment_v<t4>), 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
};
|
||||
#endif
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user