Skip to content

Commit 17d9436

Browse files
Add traits to type_list
1 parent 37539a2 commit 17d9436

File tree

4 files changed

+264
-0
lines changed

4 files changed

+264
-0
lines changed

include/etl/integral_limits.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,8 @@ template <typename T = void>
619619
{
620620
};
621621
#endif
622+
623+
static ETL_CONSTEXPR size_t npos = etl::integral_limits<size_t>::max;
622624
}
623625

624626
#include "private/minmax_pop.h"

include/etl/type_list.h

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,18 @@ SOFTWARE.
3030
#define ETL_TYPE_LIST_INCLUDED
3131

3232
#include "platform.h"
33+
34+
#include "algorithm.h"
3335
#include "nth_type.h"
36+
#include "integral_limits.h"
3437
#include "static_assert.h"
3538
#include "type_traits.h"
3639
#include "utility.h"
3740

3841
#if ETL_USING_CPP11
3942
namespace etl
4043
{
44+
4145
//***************************************************************************
4246
/// Type list forward declaration.
4347
//***************************************************************************
@@ -61,13 +65,26 @@ namespace etl
6165
type_list& operator =(const type_list&) ETL_DELETE;
6266
};
6367

68+
namespace private_type_list
69+
{
70+
71+
// helper to solve the issue that recursed-rest can't be put directly in type_list::tail definition
72+
template <typename... TTypes>
73+
struct recursion_helper
74+
{
75+
using type = type_list<TTypes...>;
76+
};
77+
78+
}
79+
6480
//***************************************************************************
6581
/// Recursive type list implementation for multiple types.
6682
//***************************************************************************
6783
template <typename THead, typename... TTail>
6884
struct type_list<THead, TTail...> : type_list<TTail...>
6985
{
7086
using type = THead;
87+
using tail = typename private_type_list::recursion_helper<TTail...>::type;
7188

7289
static constexpr size_t size = sizeof...(TTail) + 1U;
7390

@@ -87,6 +104,7 @@ namespace etl
87104
struct type_list<THead> : type_list<>
88105
{
89106
using type = THead;
107+
using tail = typename private_type_list::recursion_helper<>::type;
90108

91109
static constexpr size_t size = 1U;
92110

@@ -180,6 +198,77 @@ namespace etl
180198
{
181199
using type = typename type_list_cat<etl::type_list<TTypes1..., TTypes2...>, TTail...>::type;
182200
};
201+
202+
template<typename TypeList, typename T>
203+
struct type_list_contains
204+
: public etl::integral_constant<bool, etl::is_same<typename TypeList::type, T>::value ? true : type_list_contains<typename TypeList::tail, T>::value>
205+
{
206+
};
207+
208+
template<typename T>
209+
struct type_list_contains<type_list<>, T>
210+
: public etl::integral_constant<bool, false>
211+
{
212+
};
213+
214+
#if ETL_USING_CPP17
215+
template<typename TypeList, typename T>
216+
inline constexpr bool type_list_contains_v = etl::type_list_contains<TypeList, T>::value;
217+
#endif
218+
219+
template<typename TypeList, typename T>
220+
struct type_list_index_of
221+
: public etl::integral_constant<size_t, etl::is_same<typename TypeList::type, T>::value ? 0 :
222+
(type_list_index_of<typename TypeList::tail, T>::value == npos ?
223+
npos : type_list_index_of<typename TypeList::tail, T>::value + 1)>
224+
{
225+
};
226+
227+
template<typename T>
228+
struct type_list_index_of<type_list<>, T>
229+
: public etl::integral_constant<size_t, npos>
230+
{
231+
};
232+
233+
#if ETL_USING_CPP17
234+
template<typename TypeList, typename T>
235+
inline constexpr bool type_list_index_of_v = etl::type_list_index_of<TypeList, T>::value;
236+
#endif
237+
238+
template<typename TypeList>
239+
struct type_list_max_sizeof_type
240+
: public etl::integral_constant<size_t, etl::max(sizeof(typename TypeList::type), type_list_max_sizeof_type<typename TypeList::tail>::value)>
241+
{
242+
};
243+
244+
template<>
245+
struct type_list_max_sizeof_type<type_list<>>
246+
: public etl::integral_constant<size_t, 0>
247+
{
248+
};
249+
250+
#if ETL_USING_CPP17
251+
template<typename TypeList, typename T>
252+
inline constexpr bool type_list_max_sizeof_type_v = etl::type_list_max_sizeof_type<TypeList, T>::value;
253+
#endif
254+
255+
template<typename TypeList>
256+
struct type_list_max_alignment
257+
: public etl::integral_constant<size_t, etl::max(etl::alignment_of<typename TypeList::type>::value,
258+
type_list_max_alignment<typename TypeList::tail>::value)>
259+
{
260+
};
261+
262+
template<>
263+
struct type_list_max_alignment<type_list<>>
264+
: public etl::integral_constant<size_t, 1>
265+
{
266+
};
267+
268+
#if ETL_USING_CPP17
269+
template<typename TypeList, typename T>
270+
inline constexpr bool type_list_max_alignment_v = etl::type_list_max_alignment<TypeList, T>::value;
271+
#endif
183272
}
184273
#endif
185274

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ add_executable(etl_tests
286286
test_to_u8string.cpp
287287
test_to_wstring.cpp
288288
test_type_def.cpp
289+
test_type_list.cpp
289290
test_type_lookup.cpp
290291
test_type_select.cpp
291292
test_type_traits.cpp

test/test_type_list.cpp

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
/******************************************************************************
2+
The MIT License(MIT)
3+
4+
Embedded Template Library.
5+
https://github.com/ETLCPP/etl
6+
https://www.etlcpp.com
7+
8+
Copyright(c) 2025 BMW AG
9+
10+
Permission is hereby granted, free of charge, to any person obtaining a copy
11+
of this software and associated documentation files(the "Software"), to deal
12+
in the Software without restriction, including without limitation the rights
13+
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
14+
copies of the Software, and to permit persons to whom the Software is
15+
furnished to do so, subject to the following conditions :
16+
17+
The above copyright notice and this permission notice shall be included in all
18+
copies or substantial portions of the Software.
19+
20+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
23+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26+
SOFTWARE.
27+
******************************************************************************/
28+
29+
#include "unit_test_framework.h"
30+
31+
#include "etl/type_list.h"
32+
33+
#include <type_traits>
34+
35+
namespace
36+
{
37+
#if ETL_USING_CPP11
38+
SUITE(test_type_list)
39+
{
40+
//*************************************************************************
41+
TEST(test_nth_type)
42+
{
43+
typedef etl::type_list<char, int, uint32_t> t1;
44+
45+
CHECK_TRUE((std::is_same<etl::nth_type<0, t1>::type, char>::value));
46+
CHECK_TRUE((std::is_same<etl::nth_type<1, t1>::type, int>::value));
47+
CHECK_TRUE((std::is_same<etl::nth_type<2, t1>::type, uint32_t>::value));
48+
}
49+
50+
//*************************************************************************
51+
TEST(test_type_list_select)
52+
{
53+
typedef etl::type_list<char, int, uint32_t> t1;
54+
typedef etl::type_list<char, uint32_t> t2;
55+
56+
CHECK_TRUE((std::is_same<etl::type_list_select<t1, 0, 2>::type, t2>::value));
57+
}
58+
59+
//*************************************************************************
60+
TEST(test_type_list_size)
61+
{
62+
typedef etl::type_list<char, int, uint32_t> t1;
63+
typedef etl::type_list<char, uint32_t> t2;
64+
65+
CHECK_EQUAL(etl::type_list_size<t1>::value, 3);
66+
CHECK_EQUAL(etl::type_list_size<t2>::value, 2);
67+
}
68+
69+
//*************************************************************************
70+
TEST(test_type_list_cat)
71+
{
72+
typedef etl::type_list<char, int, uint32_t> t1;
73+
typedef etl::type_list<uint8_t, uint16_t> t2;
74+
75+
typedef etl::type_list<char, int, uint32_t, uint8_t, uint16_t> t_cat1;
76+
typedef etl::type_list<char, int, uint32_t, uint8_t, bool> t_cat2;
77+
78+
CHECK_TRUE((std::is_same<etl::type_list_cat<t1, t2>::type, t_cat1>::value));
79+
CHECK_FALSE((std::is_same<etl::type_list_cat<t1, t2>::type, t_cat2>::value));
80+
}
81+
82+
//*************************************************************************
83+
TEST(test_type_list_contains)
84+
{
85+
typedef etl::type_list<char, int, uint32_t> t1;
86+
typedef etl::type_list<uint8_t, uint16_t> t2;
87+
typedef etl::type_list<uint16_t> t3;
88+
typedef etl::type_list<> t4;
89+
90+
CHECK_TRUE((etl::type_list_contains<t1, char>::value));
91+
CHECK_FALSE((etl::type_list_contains<t1, uint8_t>::value));
92+
CHECK_FALSE((etl::type_list_contains<t2, int>::value));
93+
CHECK_TRUE((etl::type_list_contains<t2, uint16_t>::value));
94+
CHECK_TRUE((etl::type_list_contains<t3, uint16_t>::value));
95+
CHECK_FALSE((etl::type_list_contains<t3, uint32_t>::value));
96+
CHECK_FALSE((etl::type_list_contains<t4, uint32_t>::value));
97+
98+
#if ETL_USING_CPP17
99+
CHECK_TRUE((etl::type_list_contains_v<t1, char>));
100+
CHECK_FALSE((etl::type_list_contains_v<t1, uint8_t>));
101+
CHECK_FALSE((etl::type_list_contains_v<t2, int>));
102+
CHECK_TRUE((etl::type_list_contains_v<t2, uint16_t>));
103+
CHECK_TRUE((etl::type_list_contains_v<t3, uint16_t>));
104+
CHECK_FALSE((etl::type_list_contains_v<t3, uint32_t>));
105+
CHECK_FALSE((etl::type_list_contains_v<t4, uint32_t>));
106+
#endif
107+
}
108+
109+
//*************************************************************************
110+
TEST(test_type_list_index_of)
111+
{
112+
typedef etl::type_list<char, int, uint32_t> t1;
113+
typedef etl::type_list<> t2;
114+
115+
CHECK_EQUAL((etl::type_list_index_of<t1, char>::value), 0);
116+
CHECK_EQUAL((etl::type_list_index_of<t1, int>::value), 1);
117+
CHECK_EQUAL((etl::type_list_index_of<t1, uint32_t>::value), 2);
118+
CHECK_EQUAL((etl::type_list_index_of<t2, uint32_t>::value), etl::npos);
119+
120+
#if ETL_USING_CPP17
121+
CHECK_EQUAL((etl::type_list_index_of_v<t1, char>), 0);
122+
CHECK_EQUAL((etl::type_list_index_of_v<t1, int>), 1);
123+
CHECK_EQUAL((etl::type_list_index_of_v<t1, uint32_t>), 2);
124+
CHECK_EQUAL((etl::type_list_index_of_v<t2, uint32_t>), etl::npos);
125+
#endif
126+
}
127+
128+
//*************************************************************************
129+
TEST(test_type_list_max_sizeof_type)
130+
{
131+
typedef etl::type_list<char, int16_t, uint32_t> t1;
132+
typedef etl::type_list<uint8_t, uint16_t> t2;
133+
typedef etl::type_list<uint32_t> t3;
134+
typedef etl::type_list<> t4;
135+
136+
CHECK_EQUAL(etl::type_list_max_sizeof_type<t1>::value, 4);
137+
CHECK_EQUAL(etl::type_list_max_sizeof_type<t2>::value, 2);
138+
CHECK_EQUAL(etl::type_list_max_sizeof_type<t3>::value, 4);
139+
CHECK_EQUAL(etl::type_list_max_sizeof_type<t4>::value, 0);
140+
141+
#if ETL_USING_CPP17
142+
CHECK_EQUAL(etl::type_list_max_sizeof_type_v<t1>, 4);
143+
CHECK_EQUAL(etl::type_list_max_sizeof_type_v<t2>, 2);
144+
CHECK_EQUAL(etl::type_list_max_sizeof_type_v<t3>, 4);
145+
CHECK_EQUAL(etl::type_list_max_sizeof_type_v<t4>, 0);
146+
#endif
147+
}
148+
149+
//*************************************************************************
150+
TEST(test_type_list_max_alignment)
151+
{
152+
typedef etl::type_list<char, int16_t, uint32_t> t1;
153+
typedef etl::type_list<uint8_t, uint16_t> t2;
154+
typedef etl::type_list<uint16_t> t3;
155+
typedef etl::type_list<> t4;
156+
157+
CHECK_EQUAL(etl::type_list_max_alignment<t1>::value, std::alignment_of<uint32_t>::value);
158+
CHECK_EQUAL(etl::type_list_max_alignment<t2>::value, std::alignment_of<uint16_t>::value);
159+
CHECK_EQUAL(etl::type_list_max_alignment<t3>::value, std::alignment_of<uint16_t>::value);
160+
CHECK_EQUAL(etl::type_list_max_alignment<t4>::value, 1);
161+
162+
#if ETL_USING_CPP17
163+
CHECK_EQUAL(etl::type_list_max_alignment_v<t1>, std::alignment_of<uint32_t>::value);
164+
CHECK_EQUAL(etl::type_list_max_alignment_v<t2>, std::alignment_of<uint16_t>::value);
165+
CHECK_EQUAL(etl::type_list_max_alignment_v<t3>, std::alignment_of<uint16_t>::value);
166+
CHECK_EQUAL(etl::type_list_max_alignment_v<t4>, 1);
167+
#endif
168+
}
169+
170+
};
171+
#endif
172+
}

0 commit comments

Comments
 (0)