]> git.lyx.org Git - lyx.git/blob - 3rdparty/boost/boost/mp11/list.hpp
Update to boost 1.72
[lyx.git] / 3rdparty / boost / boost / mp11 / list.hpp
1 #ifndef BOOST_MP11_LIST_HPP_INCLUDED
2 #define BOOST_MP11_LIST_HPP_INCLUDED
3
4 //  Copyright 2015-2017 Peter Dimov.
5 //
6 //  Distributed under the Boost Software License, Version 1.0.
7 //
8 //  See accompanying file LICENSE_1_0.txt or copy at
9 //  http://www.boost.org/LICENSE_1_0.txt
10
11 #include <boost/mp11/integral.hpp>
12 #include <boost/mp11/detail/mp_list.hpp>
13 #include <boost/mp11/detail/mp_is_list.hpp>
14 #include <boost/mp11/detail/mp_append.hpp>
15 #include <boost/mp11/detail/config.hpp>
16 #include <type_traits>
17
18 namespace boost
19 {
20 namespace mp11
21 {
22
23 // mp_list_c<T, I...>
24 template<class T, T... I> using mp_list_c = mp_list<std::integral_constant<T, I>...>;
25
26 // mp_is_list<L>
27 //   in detail/mp_is_list.hpp
28
29 // mp_size<L>
30 namespace detail
31 {
32
33 template<class L> struct mp_size_impl
34 {
35 // An error "no type named 'type'" here means that the argument to mp_size is not a list
36 };
37
38 template<template<class...> class L, class... T> struct mp_size_impl<L<T...>>
39 {
40     using type = mp_size_t<sizeof...(T)>;
41 };
42
43 } // namespace detail
44
45 template<class L> using mp_size = typename detail::mp_size_impl<L>::type;
46
47 // mp_empty<L>
48 template<class L> using mp_empty = mp_bool< mp_size<L>::value == 0 >;
49
50 // mp_assign<L1, L2>
51 namespace detail
52 {
53
54 template<class L1, class L2> struct mp_assign_impl;
55
56 template<template<class...> class L1, class... T, template<class...> class L2, class... U> struct mp_assign_impl<L1<T...>, L2<U...>>
57 {
58     using type = L1<U...>;
59 };
60
61 } // namespace detail
62
63 template<class L1, class L2> using mp_assign = typename detail::mp_assign_impl<L1, L2>::type;
64
65 // mp_clear<L>
66 template<class L> using mp_clear = mp_assign<L, mp_list<>>;
67
68 // mp_front<L>
69 namespace detail
70 {
71
72 template<class L> struct mp_front_impl
73 {
74 // An error "no type named 'type'" here means that the argument to mp_front
75 // is either not a list, or is an empty list
76 };
77
78 template<template<class...> class L, class T1, class... T> struct mp_front_impl<L<T1, T...>>
79 {
80     using type = T1;
81 };
82
83 } // namespace detail
84
85 template<class L> using mp_front = typename detail::mp_front_impl<L>::type;
86
87 // mp_pop_front<L>
88 namespace detail
89 {
90
91 template<class L> struct mp_pop_front_impl
92 {
93 // An error "no type named 'type'" here means that the argument to mp_pop_front
94 // is either not a list, or is an empty list
95 };
96
97 template<template<class...> class L, class T1, class... T> struct mp_pop_front_impl<L<T1, T...>>
98 {
99     using type = L<T...>;
100 };
101
102 } // namespace detail
103
104 template<class L> using mp_pop_front = typename detail::mp_pop_front_impl<L>::type;
105
106 // mp_first<L>
107 template<class L> using mp_first = mp_front<L>;
108
109 // mp_rest<L>
110 template<class L> using mp_rest = mp_pop_front<L>;
111
112 // mp_second<L>
113 namespace detail
114 {
115
116 template<class L> struct mp_second_impl
117 {
118 // An error "no type named 'type'" here means that the argument to mp_second
119 // is either not a list, or has fewer than two elements
120 };
121
122 template<template<class...> class L, class T1, class T2, class... T> struct mp_second_impl<L<T1, T2, T...>>
123 {
124     using type = T2;
125 };
126
127 } // namespace detail
128
129 template<class L> using mp_second = typename detail::mp_second_impl<L>::type;
130
131 // mp_third<L>
132 namespace detail
133 {
134
135 template<class L> struct mp_third_impl
136 {
137 // An error "no type named 'type'" here means that the argument to mp_third
138 // is either not a list, or has fewer than three elements
139 };
140
141 template<template<class...> class L, class T1, class T2, class T3, class... T> struct mp_third_impl<L<T1, T2, T3, T...>>
142 {
143     using type = T3;
144 };
145
146 } // namespace detail
147
148 template<class L> using mp_third = typename detail::mp_third_impl<L>::type;
149
150 // mp_push_front<L, T...>
151 namespace detail
152 {
153
154 template<class L, class... T> struct mp_push_front_impl
155 {
156 // An error "no type named 'type'" here means that the first argument to mp_push_front is not a list
157 };
158
159 template<template<class...> class L, class... U, class... T> struct mp_push_front_impl<L<U...>, T...>
160 {
161     using type = L<T..., U...>;
162 };
163
164 } // namespace detail
165
166 template<class L, class... T> using mp_push_front = typename detail::mp_push_front_impl<L, T...>::type;
167
168 // mp_push_back<L, T...>
169 namespace detail
170 {
171
172 template<class L, class... T> struct mp_push_back_impl
173 {
174 // An error "no type named 'type'" here means that the first argument to mp_push_back is not a list
175 };
176
177 template<template<class...> class L, class... U, class... T> struct mp_push_back_impl<L<U...>, T...>
178 {
179     using type = L<U..., T...>;
180 };
181
182 } // namespace detail
183
184 template<class L, class... T> using mp_push_back = typename detail::mp_push_back_impl<L, T...>::type;
185
186 // mp_rename<L, B>
187 namespace detail
188 {
189
190 template<class A, template<class...> class B> struct mp_rename_impl
191 {
192 // An error "no type named 'type'" here means that the first argument to mp_rename is not a list
193 };
194
195 template<template<class...> class A, class... T, template<class...> class B> struct mp_rename_impl<A<T...>, B>
196 {
197     using type = B<T...>;
198 };
199
200 } // namespace detail
201
202 template<class A, template<class...> class B> using mp_rename = typename detail::mp_rename_impl<A, B>::type;
203
204 template<template<class...> class F, class L> using mp_apply = typename detail::mp_rename_impl<L, F>::type;
205
206 template<class Q, class L> using mp_apply_q = typename detail::mp_rename_impl<L, Q::template fn>::type;
207
208 // mp_replace_front<L, T>
209 namespace detail
210 {
211
212 template<class L, class T> struct mp_replace_front_impl
213 {
214 // An error "no type named 'type'" here means that the first argument to mp_replace_front
215 // is either not a list, or is an empty list
216 };
217
218 template<template<class...> class L, class U1, class... U, class T> struct mp_replace_front_impl<L<U1, U...>, T>
219 {
220     using type = L<T, U...>;
221 };
222
223 } // namespace detail
224
225 template<class L, class T> using mp_replace_front = typename detail::mp_replace_front_impl<L, T>::type;
226
227 // mp_replace_first<L, T>
228 template<class L, class T> using mp_replace_first = typename detail::mp_replace_front_impl<L, T>::type;
229
230 // mp_replace_second<L, T>
231 namespace detail
232 {
233
234 template<class L, class T> struct mp_replace_second_impl
235 {
236 // An error "no type named 'type'" here means that the first argument to mp_replace_second
237 // is either not a list, or has fewer than two elements
238 };
239
240 template<template<class...> class L, class U1, class U2, class... U, class T> struct mp_replace_second_impl<L<U1, U2, U...>, T>
241 {
242     using type = L<U1, T, U...>;
243 };
244
245 } // namespace detail
246
247 template<class L, class T> using mp_replace_second = typename detail::mp_replace_second_impl<L, T>::type;
248
249 // mp_replace_third<L, T>
250 namespace detail
251 {
252
253 template<class L, class T> struct mp_replace_third_impl
254 {
255 // An error "no type named 'type'" here means that the first argument to mp_replace_third
256 // is either not a list, or has fewer than three elements
257 };
258
259 template<template<class...> class L, class U1, class U2, class U3, class... U, class T> struct mp_replace_third_impl<L<U1, U2, U3, U...>, T>
260 {
261     using type = L<U1, U2, T, U...>;
262 };
263
264 } // namespace detail
265
266 template<class L, class T> using mp_replace_third = typename detail::mp_replace_third_impl<L, T>::type;
267
268 // mp_transform_front<L, F>
269 namespace detail
270 {
271
272 template<class L, template<class...> class F> struct mp_transform_front_impl
273 {
274 // An error "no type named 'type'" here means that the first argument to mp_transform_front
275 // is either not a list, or is an empty list
276 };
277
278 template<template<class...> class L, class U1, class... U, template<class...> class F> struct mp_transform_front_impl<L<U1, U...>, F>
279 {
280     using type = L<F<U1>, U...>;
281 };
282
283 } // namespace detail
284
285 template<class L, template<class...> class F> using mp_transform_front = typename detail::mp_transform_front_impl<L, F>::type;
286 template<class L, class Q> using mp_transform_front_q = mp_transform_front<L, Q::template fn>;
287
288 // mp_transform_first<L, F>
289 template<class L, template<class...> class F> using mp_transform_first = typename detail::mp_transform_front_impl<L, F>::type;
290 template<class L, class Q> using mp_transform_first_q = mp_transform_first<L, Q::template fn>;
291
292 // mp_transform_second<L, F>
293 namespace detail
294 {
295
296 template<class L, template<class...> class F> struct mp_transform_second_impl
297 {
298 // An error "no type named 'type'" here means that the first argument to mp_transform_second
299 // is either not a list, or has fewer than two elements
300 };
301
302 template<template<class...> class L, class U1, class U2, class... U, template<class...> class F> struct mp_transform_second_impl<L<U1, U2, U...>, F>
303 {
304     using type = L<U1, F<U2>, U...>;
305 };
306
307 } // namespace detail
308
309 template<class L, template<class...> class F> using mp_transform_second = typename detail::mp_transform_second_impl<L, F>::type;
310 template<class L, class Q> using mp_transform_second_q = mp_transform_second<L, Q::template fn>;
311
312 // mp_transform_third<L, F>
313 namespace detail
314 {
315
316 template<class L, template<class...> class F> struct mp_transform_third_impl
317 {
318 // An error "no type named 'type'" here means that the first argument to mp_transform_third
319 // is either not a list, or has fewer than three elements
320 };
321
322 template<template<class...> class L, class U1, class U2, class U3, class... U, template<class...> class F> struct mp_transform_third_impl<L<U1, U2, U3, U...>, F>
323 {
324     using type = L<U1, U2, F<U3>, U...>;
325 };
326
327 } // namespace detail
328
329 template<class L, template<class...> class F> using mp_transform_third = typename detail::mp_transform_third_impl<L, F>::type;
330 template<class L, class Q> using mp_transform_third_q = mp_transform_third<L, Q::template fn>;
331
332 } // namespace mp11
333 } // namespace boost
334
335 #endif // #ifndef BOOST_MP11_LIST_HPP_INCLUDED