]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/mp11/list.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / 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_append.hpp>
14 #include <boost/config.hpp>
15 #include <boost/detail/workaround.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 namespace detail
28 {
29
30 template<class L> struct mp_is_list_impl
31 {
32 using type = mp_false;
33 };
34
35 template<template<class...> class L, class... T> struct mp_is_list_impl<L<T...>>
36 {
37 using type = mp_true;
38 };
39
40 } // namespace detail
41
42 template<class L> using mp_is_list = typename detail::mp_is_list_impl<L>::type;
43
44 // mp_size<L>
45 namespace detail
46 {
47
48 template<class L> struct mp_size_impl
49 {
50 // An error "no type named 'type'" here means that the argument to mp_size is not a list
51 };
52
53 template<template<class...> class L, class... T> struct mp_size_impl<L<T...>>
54 {
55 using type = mp_size_t<sizeof...(T)>;
56 };
57
58 } // namespace detail
59
60 template<class L> using mp_size = typename detail::mp_size_impl<L>::type;
61
62 // mp_empty<L>
63 template<class L> using mp_empty = mp_bool< mp_size<L>::value == 0 >;
64
65 // mp_assign<L1, L2>
66 namespace detail
67 {
68
69 template<class L1, class L2> struct mp_assign_impl;
70
71 template<template<class...> class L1, class... T, template<class...> class L2, class... U> struct mp_assign_impl<L1<T...>, L2<U...>>
72 {
73 using type = L1<U...>;
74 };
75
76 } // namespace detail
77
78 template<class L1, class L2> using mp_assign = typename detail::mp_assign_impl<L1, L2>::type;
79
80 // mp_clear<L>
81 template<class L> using mp_clear = mp_assign<L, mp_list<>>;
82
83 // mp_front<L>
84 namespace detail
85 {
86
87 template<class L> struct mp_front_impl
88 {
89 // An error "no type named 'type'" here means that the argument to mp_front
90 // is either not a list, or is an empty list
91 };
92
93 template<template<class...> class L, class T1, class... T> struct mp_front_impl<L<T1, T...>>
94 {
95 using type = T1;
96 };
97
98 } // namespace detail
99
100 template<class L> using mp_front = typename detail::mp_front_impl<L>::type;
101
102 // mp_pop_front<L>
103 namespace detail
104 {
105
106 template<class L> struct mp_pop_front_impl
107 {
108 // An error "no type named 'type'" here means that the argument to mp_pop_front
109 // is either not a list, or is an empty list
110 };
111
112 template<template<class...> class L, class T1, class... T> struct mp_pop_front_impl<L<T1, T...>>
113 {
114 using type = L<T...>;
115 };
116
117 } // namespace detail
118
119 template<class L> using mp_pop_front = typename detail::mp_pop_front_impl<L>::type;
120
121 // mp_first<L>
122 template<class L> using mp_first = mp_front<L>;
123
124 // mp_rest<L>
125 template<class L> using mp_rest = mp_pop_front<L>;
126
127 // mp_second<L>
128 namespace detail
129 {
130
131 template<class L> struct mp_second_impl
132 {
133 // An error "no type named 'type'" here means that the argument to mp_second
134 // is either not a list, or has fewer than two elements
135 };
136
137 template<template<class...> class L, class T1, class T2, class... T> struct mp_second_impl<L<T1, T2, T...>>
138 {
139 using type = T2;
140 };
141
142 } // namespace detail
143
144 template<class L> using mp_second = typename detail::mp_second_impl<L>::type;
145
146 // mp_third<L>
147 namespace detail
148 {
149
150 template<class L> struct mp_third_impl
151 {
152 // An error "no type named 'type'" here means that the argument to mp_third
153 // is either not a list, or has fewer than three elements
154 };
155
156 template<template<class...> class L, class T1, class T2, class T3, class... T> struct mp_third_impl<L<T1, T2, T3, T...>>
157 {
158 using type = T3;
159 };
160
161 } // namespace detail
162
163 template<class L> using mp_third = typename detail::mp_third_impl<L>::type;
164
165 // mp_push_front<L, T...>
166 namespace detail
167 {
168
169 template<class L, class... T> struct mp_push_front_impl
170 {
171 // An error "no type named 'type'" here means that the first argument to mp_push_front is not a list
172 };
173
174 template<template<class...> class L, class... U, class... T> struct mp_push_front_impl<L<U...>, T...>
175 {
176 using type = L<T..., U...>;
177 };
178
179 } // namespace detail
180
181 template<class L, class... T> using mp_push_front = typename detail::mp_push_front_impl<L, T...>::type;
182
183 // mp_push_back<L, T...>
184 namespace detail
185 {
186
187 template<class L, class... T> struct mp_push_back_impl
188 {
189 // An error "no type named 'type'" here means that the first argument to mp_push_back is not a list
190 };
191
192 template<template<class...> class L, class... U, class... T> struct mp_push_back_impl<L<U...>, T...>
193 {
194 using type = L<U..., T...>;
195 };
196
197 } // namespace detail
198
199 template<class L, class... T> using mp_push_back = typename detail::mp_push_back_impl<L, T...>::type;
200
201 // mp_rename<L, B>
202 namespace detail
203 {
204
205 template<class A, template<class...> class B> struct mp_rename_impl
206 {
207 // An error "no type named 'type'" here means that the first argument to mp_rename is not a list
208 };
209
210 template<template<class...> class A, class... T, template<class...> class B> struct mp_rename_impl<A<T...>, B>
211 {
212 using type = B<T...>;
213 };
214
215 } // namespace detail
216
217 template<class A, template<class...> class B> using mp_rename = typename detail::mp_rename_impl<A, B>::type;
218
219 template<template<class...> class F, class L> using mp_apply = typename detail::mp_rename_impl<L, F>::type;
220
221 template<class Q, class L> using mp_apply_q = typename detail::mp_rename_impl<L, Q::template fn>::type;
222
223 // mp_replace_front<L, T>
224 namespace detail
225 {
226
227 template<class L, class T> struct mp_replace_front_impl
228 {
229 // An error "no type named 'type'" here means that the first argument to mp_replace_front
230 // is either not a list, or is an empty list
231 };
232
233 template<template<class...> class L, class U1, class... U, class T> struct mp_replace_front_impl<L<U1, U...>, T>
234 {
235 using type = L<T, U...>;
236 };
237
238 } // namespace detail
239
240 template<class L, class T> using mp_replace_front = typename detail::mp_replace_front_impl<L, T>::type;
241
242 // mp_replace_first<L, T>
243 template<class L, class T> using mp_replace_first = typename detail::mp_replace_front_impl<L, T>::type;
244
245 // mp_replace_second<L, T>
246 namespace detail
247 {
248
249 template<class L, class T> struct mp_replace_second_impl
250 {
251 // An error "no type named 'type'" here means that the first argument to mp_replace_second
252 // is either not a list, or has fewer than two elements
253 };
254
255 template<template<class...> class L, class U1, class U2, class... U, class T> struct mp_replace_second_impl<L<U1, U2, U...>, T>
256 {
257 using type = L<U1, T, U...>;
258 };
259
260 } // namespace detail
261
262 template<class L, class T> using mp_replace_second = typename detail::mp_replace_second_impl<L, T>::type;
263
264 // mp_replace_third<L, T>
265 namespace detail
266 {
267
268 template<class L, class T> struct mp_replace_third_impl
269 {
270 // An error "no type named 'type'" here means that the first argument to mp_replace_third
271 // is either not a list, or has fewer than three elements
272 };
273
274 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>
275 {
276 using type = L<U1, U2, T, U...>;
277 };
278
279 } // namespace detail
280
281 template<class L, class T> using mp_replace_third = typename detail::mp_replace_third_impl<L, T>::type;
282
283 } // namespace mp11
284 } // namespace boost
285
286 #endif // #ifndef BOOST_MP11_LIST_HPP_INCLUDED