Embedded Template Library 1.0
Loading...
Searching...
No Matches
type_list.h
1/******************************************************************************
2The MIT License(MIT)
3
4Embedded Template Library.
5https://github.com/ETLCPP/etl
6https://www.etlcpp.com
7
8Copyright(c) 2025 John Wellbelove
9
10Permission is hereby granted, free of charge, to any person obtaining a copy
11of this software and associated documentation files(the "Software"), to deal
12in the Software without restriction, including without limitation the rights
13to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
14copies of the Software, and to permit persons to whom the Software is
15furnished to do so, subject to the following conditions :
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26SOFTWARE.
27******************************************************************************/
28
29#ifndef ETL_TYPE_LIST_INCLUDED
30#define ETL_TYPE_LIST_INCLUDED
31
32#include "platform.h"
33
34#include "algorithm.h"
35#include "index_of_type.h"
36#include "integral_limits.h"
37#include "static_assert.h"
38#include "type_traits.h"
39#include "utility.h"
40#include "largest.h"
41
42#if ETL_USING_CPP11
43namespace etl
44{
45 //***************************************************************************
47 //***************************************************************************
48 static ETL_CONSTANT size_t type_list_npos = etl::integral_limits<size_t>::max;
49
50 //***************************************************************************
52 //***************************************************************************
53 template <typename... TTypes>
54 struct type_list;
55
56 //***************************************************************************
58 //***************************************************************************
59 template <>
60 struct type_list<>
61 {
62 static constexpr size_t size = 0U;
63
65
66 private:
67
68 type_list() ETL_DELETE;
69 type_list(const type_list&) ETL_DELETE;
70 type_list& operator =(const type_list&) ETL_DELETE;
71 };
72
74 {
75 // helper to solve the issue that recursed-rest can't be put directly in type_list::tail definition
76 template <typename... TTypes>
77 struct recursion_helper
78 {
79 using type = type_list<TTypes...>;
80 };
81 }
82
83 //***************************************************************************
85 //***************************************************************************
86 template <typename THead, typename... TTail>
87 struct type_list<THead, TTail...> : type_list<TTail...>
88 {
89 using head = THead;
90 using tail = typename private_type_list::recursion_helper<TTail...>::type;
91
92 static constexpr size_t size = sizeof...(TTail) + 1U;
93
94 using index_sequence_type = etl::make_index_sequence<sizeof...(TTail) + 1U>;
95
96 private:
97
98 type_list() ETL_DELETE;
99 type_list(const type_list&) ETL_DELETE;
100 type_list& operator =(const type_list&) ETL_DELETE;
101 };
102
103 //***************************************************************************
105 //***************************************************************************
106 template <typename THead>
107 struct type_list<THead> : type_list<>
108 {
109 using head = THead;
110 using tail = typename private_type_list::recursion_helper<>::type;
111
112 static constexpr size_t size = 1U;
113
114 using index_sequence_type = etl::make_index_sequence<1>;
115
116 private:
117
118 type_list() ETL_DELETE;
119 type_list(const type_list&) ETL_DELETE;
120 type_list& operator =(const type_list&) ETL_DELETE;
121 };
122
123 //***************************************************************************
125 //***************************************************************************
126 template <typename TTypes>
127 struct type_list_size;
128
129 template <typename... TTypes>
130 struct type_list_size<etl::type_list<TTypes...>> : public etl::integral_constant<size_t, sizeof...(TTypes)>
131 {
132 };
133
134#if ETL_USING_CPP17
135 template <typename... TTypes>
136 inline constexpr size_t type_list_size_v = type_list_size<etl::type_list<TTypes...>>::value;
137#endif
138
139 //***************************************************************************
142 //***************************************************************************
143 template <typename TTypeList, size_t Index>
144 struct type_list_type_at_index
145 {
146 ETL_STATIC_ASSERT(Index < type_list_size<TTypeList>::value, "etl::type_list_type_at_index out of range");
147 ETL_STATIC_ASSERT((etl::is_base_of<etl::type_list<>, TTypeList>::value), "TTypeList must be an etl::type_list");
148
149 using type = typename type_list_type_at_index<typename TTypeList::tail, Index - 1>::type;
150 };
151
152 template <typename TTypeList>
153 struct type_list_type_at_index<TTypeList, 0>
154 {
155 using type = typename TTypeList::head;
156 };
157
158 template <typename TTypeList, size_t Index>
159 using type_list_type_at_index_t = typename type_list_type_at_index<TTypeList, Index>::type;
160
161 //***************************************************************************
164 //***************************************************************************
165 template <typename TTypeList, typename T>
166 struct type_list_index_of_type
167 : public etl::integral_constant<size_t, etl::is_same<typename TTypeList::head, T>::value ? 0 :
168 (type_list_index_of_type<typename TTypeList::tail, T>::value == etl::type_list_npos ? etl::type_list_npos :
169 type_list_index_of_type<typename TTypeList::tail, T>::value + 1)>
170 {
171 ETL_STATIC_ASSERT((etl::is_base_of<etl::type_list<>, TTypeList>::value), "TTypeList must be an etl::type_list");
172 };
173
174 template <typename T>
175 struct type_list_index_of_type<type_list<>, T>
176 : public etl::integral_constant<size_t, etl::type_list_npos>
177 {
178 };
179
180#if ETL_USING_CPP17
181 template <typename TTypeList, typename T>
182 inline constexpr size_t type_list_index_of_v = etl::type_list_index_of_type<TTypeList, T>::value;
183#endif
184
185 //***************************************************************************
187 //***************************************************************************
188 template <typename T, typename TTypes>
189 struct type_list_contains;
190
191 template <typename T, typename... TTypes>
192 struct type_list_contains<etl::type_list<TTypes...>, T>
193 : public etl::integral_constant<bool, etl::is_one_of<T, TTypes...>::value>
194 {
195 };
196
197 template <typename T>
198 struct type_list_contains<type_list<>, T>
199 : public etl::integral_constant<bool, false>
200 {
201 };
202
203#if ETL_USING_CPP17
204 template <typename TTypeList, typename T>
205 inline constexpr bool type_list_contains_v = etl::type_list_contains<TTypeList, T>::value;
206#endif
207
208 //***************************************************************************
211 //***************************************************************************
212 template <typename T>
213 struct type_list_max_size;
214
215 template <typename... TTypes>
216 struct type_list_max_size<etl::type_list<TTypes...>>
217 : public etl::integral_constant<size_t, etl::largest<TTypes...>::size>
218 {
219 };
220
221 template <>
222 struct type_list_max_size<type_list<>>
223 : public etl::integral_constant<size_t, 0>
224 {
225 };
226
227#if ETL_USING_CPP17
228 template <typename TTypeList>
229 inline constexpr size_t type_list_max_size_v = etl::type_list_max_size<TTypeList>::value;
230#endif
231
232 //***************************************************************************
235 //***************************************************************************
236 template <typename T>
237 struct type_list_max_alignment;
238
239 template <typename... TTypes>
240 struct type_list_max_alignment<etl::type_list<TTypes...>>
241 : public etl::integral_constant<size_t, etl::largest<TTypes...>::alignment>
242 {
243 };
244
245 template <>
246 struct type_list_max_alignment<type_list<>>
247 : public etl::integral_constant<size_t, 1>
248 {
249 };
250
251#if ETL_USING_CPP17
252 template <typename TTypeList>
253 inline constexpr size_t type_list_max_alignment_v = etl::type_list_max_alignment<TTypeList>::value;
254#endif
255
256 //***************************************************************************
258 //***************************************************************************
259 template <typename TTypeList, size_t... Indices>
260 struct type_list_select
261 {
262 ETL_STATIC_ASSERT((etl::is_base_of<etl::type_list<>, TTypeList>::value), "TTypeList must be an etl::type_list");
263
264 using type = type_list<type_list_type_at_index_t<TTypeList, Indices>...>;
265 };
266
267 template <typename TTypeList, size_t... Indices>
268 using type_list_select_t = typename type_list_select<TTypeList, Indices...>::type;
269
270 //***************************************************************************
272 //***************************************************************************
273 template <typename... TTypes>
274 struct type_list_cat;
275
276 template <typename... TTypes1, typename... TTypes2, typename... TTail>
277 struct type_list_cat<etl::type_list<TTypes1...>, etl::type_list<TTypes2...>, TTail...>
278 {
279 using type = typename type_list_cat<etl::type_list<TTypes1..., TTypes2...>, TTail...>::type;
280 };
281
282 template <typename T>
283 struct type_list_cat<T>
284 {
285 using type = T;
286 };
287
288 template <typename... TypeLists>
289 using type_list_cat_t = typename type_list_cat<TypeLists...>::type;
290
291 //***************************************************************************
294 //***************************************************************************
295 // Primary template
296 template <typename TFromList, typename TToList>
297 struct type_lists_are_convertible;
298
299 // Specialization: both lists empty, convertible
300 template <>
301 struct type_lists_are_convertible<etl::type_list<>, etl::type_list<>>
302 : public etl::true_type
303 {
304 };
305
306 // Recursive case: check head types, then recurse
307 template <typename TFromHead, typename... TFromTail, typename TToHead, typename... TToTail>
308 struct type_lists_are_convertible<etl::type_list<TFromHead, TFromTail...>, etl::type_list<TToHead, TToTail...>>
309 : public etl::bool_constant<etl::is_convertible<TFromHead, TToHead>::value &&
310 etl::type_lists_are_convertible<etl::type_list<TFromTail...>, etl::type_list<TToTail...>>::value>
311 {
312 static_assert(sizeof...(TFromTail) == sizeof...(TToTail), "Type lists are not the same length");
313 };
314
315#if ETL_USING_CPP17
316 template <typename TFromList, typename TToList>
317 inline constexpr bool type_lists_are_convertible_v = etl::type_lists_are_convertible<TFromList, TToList>::value;
318#endif
319}
320#endif
321
322#endif
Definition integral_limits.h:516
integral_constant
Definition type_traits_generator.h:871
is_base_of
Definition type_traits_generator.h:1291
bitset_ext
Definition absolute.h:38
ETL_CONSTEXPR TContainer::size_type size(const TContainer &container)
Definition iterator.h:1187
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_even_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:314
Definition type_traits_generator.h:888