RESTinio
metaprogramming.hpp
Go to the documentation of this file.
1/*
2 * RESTinio
3 */
4
13#pragma once
14
15#include <type_traits>
16
17namespace restinio
18{
19
20namespace utils
21{
22
23namespace metaprogramming
24{
25
26// See https://en.cppreference.com/w/cpp/types/void_t for details.
27template<typename... Ts> struct make_void { using type = void; };
28template<typename... Ts> using void_t = typename make_void<Ts...>::type;
29
30namespace impl
31{
32
33//
34// debug_print
35//
36/*
37 * NOTE: this type is intended to be used just for debugging
38 * metaprogramming stuff. That is why it hasn't the definition.
39 */
40template<typename T>
42
43} /* namespace impl */
44
45//
46// type_list
47//
53template<typename... Types>
54struct type_list {};
55
56namespace impl
57{
58
59//
60// head_of
61//
62template<typename T, typename... Rest>
63struct head_of
64{
65 using type = T;
66};
67
68template<typename T>
69struct head_of<T>
70{
71 using type = T;
72};
73
74} /* namespace impl */
75
76//
77// head_of_t
78//
90template<typename... L>
91using head_of_t = typename impl::head_of<L...>::type;
92
93namespace impl
94{
95
96//
97// tail_of
98//
99template<typename T, typename... Rest>
101{
102 using type = type_list<Rest...>;
103};
104
105template<typename L>
106struct tail_of<L>
107{
109};
110
111} /* namespace impl */
112
128template<typename... L>
129using tail_of_t = typename impl::tail_of<L...>::type;
130
131namespace impl
132{
133
134//
135// put_front
136//
137template<typename T, typename Rest>
139
140template<typename T, template<class...> class L, typename... Rest>
141struct put_front< T, L<Rest...> >
142{
143 using type = L<T, Rest...>;
144};
145
146} /* namespace impl */
147
148//
149// put_front_t
150//
164template<typename T, typename Rest>
166
167namespace impl
168{
169
170//
171// rename
172//
173template<typename From, template<class...> class To>
174struct rename;
175
176template<
177 template<class...> class From,
178 typename... Types,
179 template<class...> class To>
180struct rename<From<Types...>, To>
181{
182 using type = To<Types...>;
183};
184
185} /* namespace impl */
186
187//
188// rename_t
189//
202template<typename From, template<class...> class To>
204
205namespace impl
206{
207
208//
209// transform
210//
211
212template<
213 template<class...> class Transform_F,
214 typename To,
215 typename From >
217
218template<
219 template<class...> class Transform_F,
220 template<class...> class From,
221 typename... Sources,
222 template<class...> class To,
223 typename... Results >
224struct transform< Transform_F, From<Sources...>, To<Results...> >
225{
226 using type = typename transform<
227 Transform_F,
228 tail_of_t<Sources...>,
229 To<Results..., typename Transform_F< head_of_t<Sources...> >::type>
230 >::type;
231};
232
233template<
234 template<class...> class Transform_F,
235 template<class...> class From,
236 template<class...> class To,
237 typename... Results >
238struct transform< Transform_F, From<>, To<Results...> >
239{
240 using type = To<Results...>;
241};
242
243} /* namespace impl */
244
258template< template<class...> class Transform_F, typename From >
260 Transform_F,
261 From,
263 >::type;
264
265namespace impl
266{
267
268//
269// all_of
270//
271template<
272 template<class...> class Predicate,
273 typename H,
274 typename... Tail >
275struct all_of
276{
277 static constexpr bool value = Predicate<H>::value &&
278 all_of<Predicate, Tail...>::value;
279};
280
281template<
282 template<class...> class Predicate,
283 typename H >
284struct all_of< Predicate, H >
285{
286 static constexpr bool value = Predicate<H>::value;
287};
288
289// Specialization for the case when types are represented as type_list.
290//
291// Since v.0.6.6.
292template<
293 template<class...> class Predicate,
294 typename... Types >
295struct all_of< Predicate, type_list<Types...> >
296{
297 static constexpr bool value = all_of<Predicate, Types...>::value;
298};
299
300} /* namespace impl */
301
302//
303// all_of
304//
324template< template<class...> class Predicate, typename... List >
325constexpr bool all_of_v = impl::all_of<Predicate, List...>::value;
326
327} /* namespace metaprogramming */
328
329} /* namespace utils */
330
331} /* namespace restinio */
332
typename impl::tail_of< L... >::type tail_of_t
Metafunction to get the tail of a list of types in a form of type_list.
typename impl::put_front< T, Rest >::type put_front_t
Metafunction to insert a type to the front of a type_list.
constexpr bool all_of_v
Applies the predicate to all types from the list and return true only if all types satisty that predi...
typename impl::rename< From, To >::type rename_t
Allows to pass all template arguments from one type to another.
typename impl::head_of< L... >::type head_of_t
Metafunction to get the first item from a list of types.
typename make_void< Ts... >::type void_t
typename impl::transform< Transform_F, From, type_list<> >::type transform_t
Applies a specified meta-function to every item from a specified type-list and return a new type-list...
typename transform< Transform_F, tail_of_t< Sources... >, To< Results..., typename Transform_F< head_of_t< Sources... > >::type > >::type type
The basic building block: a type for representation of a type list.