RESTinio
metaprogramming.hpp
Go to the documentation of this file.
1 /*
2  * RESTinio
3  */
4 
13 #pragma once
14 
15 #include <type_traits>
16 
17 namespace restinio
18 {
19 
20 namespace utils
21 {
22 
23 namespace metaprogramming
24 {
25 
26 // See https://en.cppreference.com/w/cpp/types/void_t for details.
27 template<typename... Ts> struct make_void { using type = void; };
28 template<typename... Ts> using void_t = typename make_void<Ts...>::type;
29 
30 namespace 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  */
40 template<typename T>
41 struct debug_print;
42 
43 } /* namespace impl */
44 
45 //
46 // type_list
47 //
53 template<typename... Types>
54 struct type_list {};
55 
56 namespace impl
57 {
58 
59 //
60 // head_of
61 //
62 template<typename T, typename... Rest>
63 struct head_of
64 {
65  using type = T;
66 };
67 
68 template<typename T>
69 struct head_of<T>
70 {
71  using type = T;
72 };
73 
74 } /* namespace impl */
75 
76 //
77 // head_of_t
78 //
90 template<typename... L>
91 using head_of_t = typename impl::head_of<L...>::type;
92 
93 namespace impl
94 {
95 
96 //
97 // tail_of
98 //
99 template<typename T, typename... Rest>
100 struct tail_of
101 {
102  using type = type_list<Rest...>;
103 };
104 
105 template<typename L>
106 struct tail_of<L>
107 {
108  using type = type_list<>;
109 };
110 
111 } /* namespace impl */
112 
128 template<typename... L>
129 using tail_of_t = typename impl::tail_of<L...>::type;
130 
131 namespace impl
132 {
133 
134 //
135 // put_front
136 //
137 template<typename T, typename Rest>
138 struct put_front;
139 
140 template<typename T, template<class...> class L, typename... Rest>
141 struct put_front< T, L<Rest...> >
142 {
143  using type = L<T, Rest...>;
144 };
145 
146 } /* namespace impl */
147 
148 //
149 // put_front_t
150 //
164 template<typename T, typename Rest>
166 
167 namespace impl
168 {
169 
170 //
171 // rename
172 //
173 template<typename From, template<class...> class To>
174 struct rename;
175 
176 template<
177  template<class...> class From,
178  typename... Types,
179  template<class...> class To>
180 struct rename<From<Types...>, To>
181 {
182  using type = To<Types...>;
183 };
184 
185 } /* namespace impl */
186 
187 //
188 // rename_t
189 //
202 template<typename From, template<class...> class To>
204 
205 namespace impl
206 {
207 
208 //
209 // transform
210 //
211 
212 template<
213  template<class...> class Transform_F,
214  typename To,
215  typename From >
216 struct transform;
217 
218 template<
219  template<class...> class Transform_F,
220  template<class...> class From,
221  typename... Sources,
222  template<class...> class To,
223  typename... Results >
224 struct 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 
233 template<
234  template<class...> class Transform_F,
235  template<class...> class From,
236  template<class...> class To,
237  typename... Results >
238 struct transform< Transform_F, From<>, To<Results...> >
239 {
240  using type = To<Results...>;
241 };
242 
243 } /* namespace impl */
244 
258 template< template<class...> class Transform_F, typename From >
259 using transform_t = typename impl::transform<
260  Transform_F,
261  From,
263  >::type;
264 
265 namespace impl
266 {
267 
268 //
269 // all_of
270 //
271 template<
272  template<class...> class Predicate,
273  typename H,
274  typename... Tail >
275 struct all_of
276 {
277  static constexpr bool value = Predicate<H>::value &&
278  all_of<Predicate, Tail...>::value;
279 };
280 
281 template<
282  template<class...> class Predicate,
283  typename H >
284 struct 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.
292 template<
293  template<class...> class Predicate,
294  typename... Types >
295 struct 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 //
324 template< template<class...> class Predicate, typename... List >
325 constexpr bool all_of_v = impl::all_of<Predicate, List...>::value;
326 
327 } /* namespace metaprogramming */
328 
329 } /* namespace utils */
330 
331 } /* namespace restinio */
332 
restinio::utils::metaprogramming::type_list
The basic building block: a type for representation of a type list.
Definition: metaprogramming.hpp:54
restinio::utils::metaprogramming::rename_t
typename impl::rename< From, To >::type rename_t
Allows to pass all template arguments from one type to another.
Definition: metaprogramming.hpp:203
restinio::utils::metaprogramming::impl::debug_print
Definition: metaprogramming.hpp:41
restinio::utils::metaprogramming::put_front_t
typename impl::put_front< T, Rest >::type put_front_t
Metafunction to insert a type to the front of a type_list.
Definition: metaprogramming.hpp:165
restinio::utils::metaprogramming::impl::rename
Definition: metaprogramming.hpp:174
restinio::utils::metaprogramming::transform_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...
Definition: metaprogramming.hpp:263
restinio::utils::metaprogramming::impl::head_of
Definition: metaprogramming.hpp:64
restinio::utils::metaprogramming::all_of_v
constexpr bool all_of_v
Applies the predicate to all types from the list and return true only if all types satisty that predi...
Definition: metaprogramming.hpp:325
restinio::utils::metaprogramming::impl::put_front< T, L< Rest... > >::type
L< T, Rest... > type
Definition: metaprogramming.hpp:143
restinio::utils::metaprogramming::impl::put_front
Definition: metaprogramming.hpp:138
restinio::utils::metaprogramming::impl::head_of< T >::type
T type
Definition: metaprogramming.hpp:71
restinio::utils::metaprogramming::make_void::type
void type
Definition: metaprogramming.hpp:27
restinio::utils::metaprogramming::head_of_t
typename impl::head_of< L... >::type head_of_t
Metafunction to get the first item from a list of types.
Definition: metaprogramming.hpp:91
restinio::utils::metaprogramming::tail_of_t
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.
Definition: metaprogramming.hpp:129
restinio::utils::metaprogramming::impl::all_of::value
static constexpr bool value
Definition: metaprogramming.hpp:277
restinio::utils::metaprogramming::impl::tail_of
Definition: metaprogramming.hpp:101
restinio::utils::metaprogramming::void_t
typename make_void< Ts... >::type void_t
Definition: metaprogramming.hpp:28
restinio::utils::metaprogramming::impl::transform
Definition: metaprogramming.hpp:216
restinio
Definition: asio_include.hpp:21
restinio::utils::metaprogramming::impl::transform< Transform_F, From<>, To< Results... > >::type
To< Results... > type
Definition: metaprogramming.hpp:240
restinio::utils::metaprogramming::impl::rename< From< Types... >, To >::type
To< Types... > type
Definition: metaprogramming.hpp:182
restinio::utils::metaprogramming::impl::head_of::type
T type
Definition: metaprogramming.hpp:65
restinio::utils::metaprogramming::impl::transform< Transform_F, From< Sources... >, To< Results... > >::type
typename transform< Transform_F, tail_of_t< Sources... >, To< Results..., typename Transform_F< head_of_t< Sources... > >::type > >::type type
Definition: metaprogramming.hpp:230
restinio::utils::metaprogramming::impl::all_of
Definition: metaprogramming.hpp:276
restinio::utils::metaprogramming::make_void
Definition: metaprogramming.hpp:27