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
64 using index_sequence_type = etl::make_index_sequence<0>;
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
73 namespace private_type_list
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 TTypeList, typename T>
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 //***************************************************************************
210 //***************************************************************************
211 template <typename TTypeList, typename T>
212 struct type_list_has_duplicates_of;
213
214 template <typename T, typename... TTypes>
215 struct type_list_has_duplicates_of<etl::type_list<TTypes...>, T>
216 : public etl::has_duplicates_of<T, TTypes...>
217 {
218 };
219
220 template <typename T>
221 struct type_list_has_duplicates_of<type_list<>, T>
222 : public etl::integral_constant<bool, false>
223 {
224 };
225
226#if ETL_USING_CPP17
227 template <typename TTypeList, typename T>
228 inline constexpr bool type_list_has_duplicates_of_v = etl::type_list_has_duplicates_of<TTypeList, T>::value;
229#endif
230
231 //***************************************************************************
233 //***************************************************************************
234 template <typename TTypeList, typename T>
235 struct type_list_count_of;
236
237 template <typename T, typename... TTypes>
238 struct type_list_count_of<etl::type_list<TTypes...>, T>
239 : public etl::count_of<T, TTypes...>
240 {
241 };
242
243 template <typename T>
244 struct type_list_count_of<type_list<>, T>
245 : public etl::integral_constant<size_t, 0>
246 {
247 };
248
249#if ETL_USING_CPP17
250 template <typename TTypeList, typename T>
251 inline constexpr size_t type_list_count_of_v = etl::type_list_count_of<TTypeList, T>::value;
252#endif
253
254 //***************************************************************************
257 //***************************************************************************
258 template <typename T>
259 struct type_list_max_size;
260
261 template <typename... TTypes>
262 struct type_list_max_size<etl::type_list<TTypes...>>
263 : public etl::integral_constant<size_t, etl::largest<TTypes...>::size>
264 {
265 };
266
267 template <>
268 struct type_list_max_size<type_list<>>
269 : public etl::integral_constant<size_t, 0>
270 {
271 };
272
273#if ETL_USING_CPP17
274 template <typename TTypeList>
275 inline constexpr size_t type_list_max_size_v = etl::type_list_max_size<TTypeList>::value;
276#endif
277
278 //***************************************************************************
281 //***************************************************************************
282 template <typename T>
283 struct type_list_max_alignment;
284
285 template <typename... TTypes>
286 struct type_list_max_alignment<etl::type_list<TTypes...>>
287 : public etl::integral_constant<size_t, etl::largest<TTypes...>::alignment>
288 {
289 };
290
291 template <>
292 struct type_list_max_alignment<type_list<>>
293 : public etl::integral_constant<size_t, 1>
294 {
295 };
296
297#if ETL_USING_CPP17
298 template <typename TTypeList>
299 inline constexpr size_t type_list_max_alignment_v = etl::type_list_max_alignment<TTypeList>::value;
300#endif
301
302 //***************************************************************************
304 //***************************************************************************
305 template <typename TTypeList, size_t... Indices>
306 struct type_list_select
307 {
308 ETL_STATIC_ASSERT((etl::is_base_of<etl::type_list<>, TTypeList>::value), "TTypeList must be an etl::type_list");
309
310 using type = type_list<type_list_type_at_index_t<TTypeList, Indices>...>;
311 };
312
313 template <typename TTypeList, size_t... Indices>
314 using type_list_select_t = typename type_list_select<TTypeList, Indices...>::type;
315
316 //***************************************************************************
318 //***************************************************************************
319 template <typename... TTypes>
320 struct type_list_cat;
321
322 template <typename... TTypes1, typename... TTypes2, typename... TTail>
323 struct type_list_cat<etl::type_list<TTypes1...>, etl::type_list<TTypes2...>, TTail...>
324 {
325 using type = typename type_list_cat<etl::type_list<TTypes1..., TTypes2...>, TTail...>::type;
326 };
327
328 template <typename T>
329 struct type_list_cat<T>
330 {
331 using type = T;
332 };
333
334 template <typename... TypeLists>
335 using type_list_cat_t = typename type_list_cat<TypeLists...>::type;
336
337 //***************************************************************************
340 //***************************************************************************
341 // Primary template
342 template <typename TFromList, typename TToList>
343 struct type_lists_are_convertible;
344
345 // Specialization: both lists empty, convertible
346 template <>
347 struct type_lists_are_convertible<etl::type_list<>, etl::type_list<>>
348 : public etl::true_type
349 {
350 };
351
352 // Recursive case: check head types, then recurse
353 template <typename TFromHead, typename... TFromTail, typename TToHead, typename... TToTail>
354 struct type_lists_are_convertible<etl::type_list<TFromHead, TFromTail...>, etl::type_list<TToHead, TToTail...>>
355 : public etl::bool_constant<etl::is_convertible<TFromHead, TToHead>::value &&
356 etl::type_lists_are_convertible<etl::type_list<TFromTail...>, etl::type_list<TToTail...>>::value>
357 {
358 static_assert(sizeof...(TFromTail) == sizeof...(TToTail), "Type lists are not the same length");
359 };
360
361#if ETL_USING_CPP17
362 template <typename TFromList, typename TToList>
363 inline constexpr bool type_lists_are_convertible_v = etl::type_lists_are_convertible<TFromList, TToList>::value;
364#endif
365}
366#endif
367
368#endif
bitset_ext
Definition absolute.h:39
ETL_CONSTEXPR TContainer::size_type size(const TContainer &container)
Definition iterator.h:1187