SPARK  0.1.0
A general purpose game engine written in C++.
Loading...
Searching...
No Matches
type_seq.h
1#pragma once
2
3namespace spark::mpl::type_seq
4{
5 // size
6 template <typename... Ts>
7 struct size
8 {
9 inline static constexpr std::size_t value = sizeof...(Ts);
10 };
11
12 template <typename... Ts>
13 inline static constexpr std::size_t size_v = size<Ts...>::value;
14
15 // empty
16 template <typename... Ts>
17 struct empty
18 {
19 inline static constexpr bool value = sizeof...(Ts) == 0;
20 };
21
22 template <typename... Ts>
23 inline static constexpr bool empty_v = empty<Ts...>::value;
24
25 // contains
26 template <typename T, typename... Ts>
27 struct contains {};
28
29 template <typename T, typename Head, typename... Ts>
30 struct contains<T, Head, Ts...>
31 {
32 inline static constexpr bool value = std::is_same_v<T, Head> || contains<T, Ts...>::value;
33 };
34
35 template <typename T>
36 struct contains<T>
37 {
38 inline static constexpr bool value = false;
39 };
40
41 template <typename T, typename... Ts>
42 inline static constexpr bool contains_v = contains<T, Ts...>::value;
43
44 // index_of
45 template <typename T, typename... Ts>
46 struct index_of {};
47
48 template <typename T, typename Head, typename... Ts>
49 struct index_of<T, Head, Ts...>
50 {
51 inline static constexpr std::size_t value = std::is_same_v<T, Head> ? 0 : 1 + index_of<T, Ts...>::value;
52 };
53
54 template <typename T>
55 struct index_of<T>
56 {
57 inline static constexpr std::size_t value = 0;
58 };
59
60 template <typename T, typename... Ts>
61 inline static constexpr std::size_t index_of_v = index_of<T, Ts...>::value;
62
63 // find
64 template <typename T, typename... Ts>
65 struct find {};
66
67 template <template<typename...> typename C, typename T, typename Head, typename... Ts>
68 struct find<T, C<Head, Ts...>>
69 {
70 inline static constexpr std::size_t value = find<T, C<Ts...>>::value + 1;
71 };
72
73 template <template<typename...> typename C, typename T, typename... Ts>
74 struct find<T, C<T, Ts...>>
75 {
76 inline static constexpr std::size_t value = 0;
77 };
78
79 template <typename T, typename... Ts>
80 inline static constexpr std::size_t find_v = find<T, Ts...>::value;
81
82 // front
83 template <typename... Ts>
84 struct front {};
85
86 template <typename Head, typename... Ts>
87 struct front<Head, Ts...>
88 {
89 using type = Head;
90 };
91
92 template <typename... Ts>
93 using front_t = typename front<Ts...>::type;
94
95 // back
96 template <typename... Ts>
97 struct back {};
98
99 template <typename Head, typename... Ts>
100 struct back<Head, Ts...>
101 {
102 using type = typename back<Ts...>::type;
103 };
104
105 template <typename Head>
106 struct back<Head>
107 {
108 using type = Head;
109 };
110
111 template <typename... Ts>
112 using back_t = typename back<Ts...>::type;
113
114 // push_front
115 template <typename T, typename List>
116 struct push_front {};
117
118 template <template<typename...> typename C, typename T, typename... Ts>
119 struct push_front<T, C<Ts...>>
120 {
121 using type = C<T, Ts...>;
122 };
123
124 template <typename T, typename... Ts>
125 using push_front_t = typename push_front<T, Ts...>::type;
126
127 // push_back
128 template <typename T, typename... Ts>
129 struct push_back {};
130
131 template <template<typename...> typename C, typename T, typename... Ts>
132 struct push_back<T, C<Ts...>>
133 {
134 using type = C<Ts..., T>;
135 };
136
137 template <typename T, typename... Ts>
138 using push_back_t = typename push_back<T, Ts...>::type;
139
140 // pop_front
141 template <typename List>
142 struct pop_front {};
143
144 template <template<typename...> typename C, typename Head, typename... Ts>
145 struct pop_front<C<Head, Ts...>>
146 {
147 using type = C<Ts...>;
148 };
149
150 template <typename... Ts>
151 using pop_front_t = typename pop_front<Ts...>::type;
152
153 // pop_back
154 template <typename... Ts>
155 struct pop_back {};
156
157 template <template<typename...> typename C, typename Head, typename... Ts>
158 struct pop_back<C<Head, Ts...>>
159 {
160 using type = typename push_front<Head, typename pop_back<C<Ts...>>::type>::type;
161 };
162
163 template <template<typename...> typename C, typename Head>
164 struct pop_back<C<Head>>
165 {
166 using type = C<>;
167 };
168
169 template <typename... Ts>
170 using pop_back_t = typename pop_back<Ts...>::type;
171
172 // at
173 template <std::size_t N, typename List>
174 struct at {};
175
176 template <template<typename...> typename C, std::size_t N, typename Head, typename... Ts>
177 struct at<N, C<Head, Ts...>>
178 {
179 using type = typename at<N - 1, C<Ts...>>::type;
180 };
181
182 template <template<typename...> typename C, typename Head, typename... Ts>
183 struct at<0, C<Head, Ts...>>
184 {
185 using type = Head;
186 };
187
188 template <std::size_t N, typename... Ts>
189 using at_t = typename at<N, Ts...>::type;
190
191 // erase
192 template <typename T, typename... Ts>
193 struct erase {};
194
195 template <template<typename...> typename C, typename T, typename... Ts>
196 struct erase<T, C<T, Ts...>>
197 {
198 using type = C<Ts...>;
199 };
200
201 template <template<typename...> typename C, typename T, typename Head, typename... Ts>
202 struct erase<T, C<Head, Ts...>>
203 {
204 using type = typename push_front<Head, typename erase<T, C<Ts...>>::type>::type;
205 };
206
207 template <typename T, typename... Ts>
208 using erase_t = typename erase<T, Ts...>::type;
209
210 // erase_at
211 template <std::size_t N, typename... Ts>
212 struct erase_at {};
213
214 template <template<typename...> typename C, std::size_t N, typename Head, typename... Ts>
215 struct erase_at<N, C<Head, Ts...>>
216 {
217 using type = typename push_front<Head, typename erase_at<N - 1, C<Ts...>>::type>::type;
218 };
219
220 template <template<typename...> typename C, typename Head, typename... Ts>
221 struct erase_at<0, C<Head, Ts...>>
222 {
223 using type = C<Ts...>;
224 };
225
226 template <std::size_t N, typename... Ts>
227 using erase_at_t = typename erase_at<N, Ts...>::type;
228
229 // insert_at
230 template <std::size_t N, typename T, typename... Ts>
231 struct insert_at {};
232
233 template <template<typename...> typename C, std::size_t N, typename T, typename Head, typename... Ts>
234 struct insert_at<N, T, C<Head, Ts...>>
235 {
236 using type = typename push_front<Head, typename insert_at<N - 1, T, C<Ts...>>::type>::type;
237 };
238
239 template <template<typename...> typename C, typename T, typename Head, typename... Ts>
240 struct insert_at<0, T, C<Head, Ts...>>
241 {
242 using type = typename push_front<T, C<Head, Ts...>>::type;
243 };
244
245 template <template<typename...> typename C, std::size_t N, typename T>
246 struct insert_at<N, T, C<>>
247 {
248 using type = C<T>;
249 };
250
251 template <std::size_t N, typename T, typename... Ts>
252 using insert_at_t = typename insert_at<N, T, Ts...>::type;
253
254 // replace
255 template <typename T, typename U, typename... Ts>
256 struct replace {};
257
258 template <template<typename...> typename C, typename T, typename U, typename Head, typename... Ts>
259 struct replace<T, U, C<Head, Ts...>>
260 {
261 using type = typename push_front<Head, typename replace<T, U, C<Ts...>>::type>::type;
262 };
263
264 template <template<typename...> typename C, typename T, typename U, typename Head, typename... Ts>
265 struct replace<T, U, C<T, Head, Ts...>>
266 {
267 using type = typename push_front<U, typename replace<T, U, C<Head, Ts...>>::type>::type;
268 };
269
270 template <template<typename...> typename C, typename T, typename U, typename... Ts>
271 struct replace<T, U, C<T, Ts...>>
272 {
273 using type = typename replace<T, U, C<U, Ts...>>::type;
274 };
275
276 template <template<typename...> typename C, typename T, typename U>
277 struct replace<T, U, C<>>
278 {
279 using type = C<>;
280 };
281
282 template <typename T, typename U, typename... Ts>
283 using replace_t = typename replace<T, U, Ts...>::type;
284
285 // replace_at
286 template <std::size_t N, typename T, typename... Ts>
287 struct replace_at {};
288
289 template <template<typename...> typename C, std::size_t N, typename T, typename Head, typename... Ts>
290 struct replace_at<N, T, C<Head, Ts...>>
291 {
292 using type = typename push_front<Head, typename replace_at<N - 1, T, C<Ts...>>::type>::type;
293 };
294
295 template <template<typename...> typename C, typename T, typename Head, typename... Ts>
296 struct replace_at<0, T, C<Head, Ts...>>
297 {
298 using type = typename push_front<T, C<Ts...>>::type;
299 };
300
301 template <template<typename...> typename C, std::size_t N, typename T>
302 struct replace_at<N, T, C<>>
303 {
304 using type = C<>;
305 };
306
307 template <std::size_t N, typename T, typename... Ts>
308 using replace_at_t = typename replace_at<N, T, Ts...>::type;
309
310 // reverse
311 template <typename... Ts>
312 struct reverse {};
313
314 template <template<typename...> typename C, typename... TypesToAdd, typename Head, typename... Ts>
315 struct reverse<C<Head, Ts...>, TypesToAdd...>
316 {
317 using type = typename reverse<C<Ts...>, Head, TypesToAdd...>::type;
318 };
319
320 template <template<typename...> typename C, typename... TypesToAdd>
321 struct reverse<C<>, TypesToAdd...>
322 {
323 using type = C<TypesToAdd...>;
324 };
325
326 template <typename... Ts>
327 using reverse_t = typename reverse<Ts...>::type;
328
329 // filter
330 template <template <typename> typename Predicate, typename... Ts>
331 struct filter {};
332
333 template <template<typename...> typename C, template <typename> typename Predicate, typename Head, typename... Ts>
334 struct filter<Predicate, C<Head, Ts...>>
335 {
336 using type = std::conditional_t<Predicate<Head>::value, typename push_front<Head, typename filter<Predicate, C<Ts...>>::type>::type, typename filter<
337 Predicate, C<Ts...>>::type>;
338 };
339
340 template <template<typename...> typename C, template <typename> typename Predicate>
341 struct filter<Predicate, C<>>
342 {
343 using type = C<>;
344 };
345
346 template <template <typename> typename Predicate, typename... Ts>
347 using filter_t = typename filter<Predicate, Ts...>::type;
348
349 // convert
350 template <template <typename...> typename T, typename... Ts>
351 struct convert
352 {
353 using type = T<Ts...>;
354 };
355
356 template <template <typename...> typename T, typename... Ts>
357 using convert_t = typename convert<T, Ts...>::type;
358
359 // transform
360 template <template <typename> typename F, typename... Ts>
361 struct transform {};
362
363 template <template <typename...> typename C, template <typename> typename F, typename Head, typename... Ts>
364 struct transform<F, C<Head, Ts...>>
365 {
366 using type = typename push_front<typename F<Head>::type, typename transform<F, C<Ts...>>::type>::type;
367 };
368
369 template <template <typename...> typename C, template <typename> typename F>
370 struct transform<F, C<>>
371 {
372 using type = C<>;
373 };
374
375 template <template <typename> typename F, typename... Ts>
376 using transform_t = typename transform<F, Ts...>::type;
377
378 // concat
379 template <typename... Lists>
380 struct concat {};
381
382 template <template <typename...> class C, typename... Ts>
383 struct concat<C<Ts...>>
384 {
385 using type = C<Ts...>;
386 };
387
388 template <template <typename...> class C, typename... Ts, typename... Us>
389 struct concat<C<Ts...>, C<Us...>>
390 {
391 using type = C<Ts..., Us...>;
392 };
393
394 template <typename T, typename U, typename V, typename... O>
395 struct concat<T, U, V, O...>
396 {
397 using type = typename concat<typename concat<T, U>::type, typename concat<V, O...>::type>::type;
398 };
399
400 template <typename... Lists>
401 using concat_t = typename concat<Lists...>::type;
402
403 // flatten
404 template <typename List>
405 struct flatten {};
406
407 template <template <typename...> class C, typename... Ts>
408 struct flatten<C<Ts...>>
409 {
410 using type = typename concat<Ts...>::type;
411 };
412
413 template <template <typename...> class C>
414 struct flatten<C<>>
415 {
416 using type = C<>;
417 };
418
419 template <typename List>
420 using flatten_t = typename flatten<List>::type;
421
422 // match
423 template <template<typename, typename> typename Matcher, typename L1, typename L2>
424 struct match {};
425
426 template <template <typename, typename> typename Matcher, template <typename...> typename C, typename T, typename U, typename... Ts, typename... Us>
427 struct match<Matcher, C<T, Ts...>, C<U, Us...>>
428 {
429 static constexpr bool value = Matcher<T, U>::value && match<Matcher, C<Ts...>, C<Us...>>::value;
430 };
431
432 template <template <typename, typename> typename Matcher, template <typename...> typename C>
433 struct match<Matcher, C<>, C<>>
434 {
435 static constexpr bool value = true;
436 };
437
438 template <template<typename, typename> typename Matcher, typename L1, typename L2>
439 inline static constexpr bool match_v = match<Matcher, L1, L2>::value;
440}
Definition type_seq.h:174
Definition type_seq.h:97
Definition type_seq.h:380
Definition type_seq.h:27
Definition type_seq.h:352
Definition type_seq.h:18
Definition type_seq.h:212
Definition type_seq.h:193
Definition type_seq.h:331
Definition type_seq.h:65
Definition type_seq.h:405
Definition type_seq.h:84
Definition type_seq.h:46
Definition type_seq.h:231
Definition type_seq.h:424
Definition type_seq.h:155
Definition type_seq.h:142
Definition type_seq.h:129
Definition type_seq.h:116
Definition type_seq.h:287
Definition type_seq.h:256
Definition type_seq.h:312
Definition type_seq.h:8
Definition type_seq.h:361