]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/util/sequence.hpp
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / boost / boost / geometry / util / sequence.hpp
1 // Boost.Geometry
2
3 // Copyright (c) 2020-2021, Oracle and/or its affiliates.
4
5 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
6
7 // Licensed under the Boost Software License version 1.0.
8 // http://www.boost.org/users/license.html
9
10 #ifndef BOOST_GEOMETRY_UTIL_SEQUENCE_HPP
11 #define BOOST_GEOMETRY_UTIL_SEQUENCE_HPP
12
13
14 #include <type_traits>
15
16
17 namespace boost { namespace geometry
18 {
19
20 namespace util
21 {
22
23
24 // An alternative would be to use std:tuple and std::pair
25 // but it would add dependency.
26
27
28 template <typename ...Ts>
29 struct type_sequence {};
30
31
32 // true if T is a sequence
33 template <typename T>
34 struct is_sequence : std::false_type {};
35
36 template <typename ...Ts>
37 struct is_sequence<type_sequence<Ts...>> : std::true_type {};
38
39 template <typename T, T ...Is>
40 struct is_sequence<std::integer_sequence<T, Is...>> : std::true_type {};
41
42
43 // number of elements in a sequence
44 template <typename Sequence>
45 struct sequence_size {};
46
47 template <typename ...Ts>
48 struct sequence_size<type_sequence<Ts...>>
49 : std::integral_constant<std::size_t, sizeof...(Ts)>
50 {};
51
52 template <typename T, T ...Is>
53 struct sequence_size<std::integer_sequence<T, Is...>>
54 : std::integral_constant<std::size_t, sizeof...(Is)>
55 {};
56
57
58 // element of a sequence
59 template <std::size_t I, typename Sequence>
60 struct sequence_element {};
61
62 template <std::size_t I, typename T, typename ...Ts>
63 struct sequence_element<I, type_sequence<T, Ts...>>
64 {
65 using type = typename sequence_element<I - 1, type_sequence<Ts...>>::type;
66 };
67
68 template <typename T, typename ...Ts>
69 struct sequence_element<0, type_sequence<T, Ts...>>
70 {
71 using type = T;
72 };
73
74 template <std::size_t I, typename T, T J, T ...Js>
75 struct sequence_element<I, std::integer_sequence<T, J, Js...>>
76 : std::integral_constant
77 <
78 T,
79 sequence_element<I - 1, std::integer_sequence<T, Js...>>::value
80 >
81 {};
82
83 template <typename T, T J, T ...Js>
84 struct sequence_element<0, std::integer_sequence<T, J, Js...>>
85 : std::integral_constant<T, J>
86 {};
87
88
89 template <typename ...Ts>
90 struct pack_front
91 {
92 static_assert(sizeof...(Ts) > 0, "Parameter pack can not be empty.");
93 };
94
95 template <typename T, typename ... Ts>
96 struct pack_front<T, Ts...>
97 {
98 typedef T type;
99 };
100
101
102 template <typename Sequence>
103 struct sequence_front
104 : sequence_element<0, Sequence>
105 {
106 static_assert(sequence_size<Sequence>::value > 0, "Sequence can not be empty.");
107 };
108
109
110 template <typename Sequence>
111 struct sequence_back
112 : sequence_element<sequence_size<Sequence>::value - 1, Sequence>
113 {
114 static_assert(sequence_size<Sequence>::value > 0, "Sequence can not be empty.");
115 };
116
117
118 template <typename Sequence>
119 struct sequence_empty
120 : std::integral_constant
121 <
122 bool,
123 sequence_size<Sequence>::value == 0
124 >
125 {};
126
127
128 // Defines type member for the first type in sequence that satisfies UnaryPred.
129 template
130 <
131 typename Sequence,
132 template <typename> class UnaryPred
133 >
134 struct sequence_find_if {};
135
136 template
137 <
138 typename T, typename ...Ts,
139 template <typename> class UnaryPred
140 >
141 struct sequence_find_if<type_sequence<T, Ts...>, UnaryPred>
142 : std::conditional
143 <
144 UnaryPred<T>::value,
145 T,
146 // TODO: prevent instantiation for the rest of the sequence if value is true
147 typename sequence_find_if<type_sequence<Ts...>, UnaryPred>::type
148 >
149 {};
150
151 template <template <typename> class UnaryPred>
152 struct sequence_find_if<type_sequence<>, UnaryPred>
153 {
154 // TODO: This is technically incorrect because void can be stored in a type_sequence
155 using type = void;
156 };
157
158
159 // sequence_merge<type_sequence<A, B>, type_sequence<C, D>>::type is
160 // type_sequence<A, B, C, D>
161 // sequence_merge<integer_sequence<A, B>, integer_sequence<C, D>>::type is
162 // integer_sequence<A, B, C, D>
163 template <typename ...Sequences>
164 struct sequence_merge;
165
166 template <typename S>
167 struct sequence_merge<S>
168 {
169 using type = S;
170 };
171
172 template <typename ...T1s, typename ...T2s>
173 struct sequence_merge<type_sequence<T1s...>, type_sequence<T2s...>>
174 {
175 using type = type_sequence<T1s..., T2s...>;
176 };
177
178 template <typename T, T ...I1s, T ...I2s>
179 struct sequence_merge<std::integer_sequence<T, I1s...>, std::integer_sequence<T, I2s...>>
180 {
181 using type = std::integer_sequence<T, I1s..., I2s...>;
182 };
183
184 template <typename S1, typename S2, typename ...Sequences>
185 struct sequence_merge<S1, S2, Sequences...>
186 {
187 using type = typename sequence_merge
188 <
189 typename sequence_merge<S1, S2>::type,
190 typename sequence_merge<Sequences...>::type
191 >::type;
192 };
193
194
195 // sequence_combine<type_sequence<A, B>, type_sequence<C, D>>::type is
196 // type_sequence<type_sequence<A, C>, type_sequence<A, D>,
197 // type_sequence<B, C>, type_sequence<B, D>>
198 template <typename Sequence1, typename Sequence2>
199 struct sequence_combine;
200
201 template <typename ...T1s, typename ...T2s>
202 struct sequence_combine<type_sequence<T1s...>, type_sequence<T2s...>>
203 {
204 template <typename T1>
205 using type_sequence_t = type_sequence<type_sequence<T1, T2s>...>;
206
207 using type = typename sequence_merge<type_sequence_t<T1s>...>::type;
208 };
209
210 // sequence_combine<integer_sequence<T, 1, 2>, integer_sequence<T, 3, 4>>::type is
211 // type_sequence<integer_sequence<T, 1, 3>, integer_sequence<T, 1, 4>,
212 // integer_sequence<T, 2, 3>, integer_sequence<T, 2, 4>>
213 template <typename T, T ...I1s, T ...I2s>
214 struct sequence_combine<std::integer_sequence<T, I1s...>, std::integer_sequence<T, I2s...>>
215 {
216 template <T I1>
217 using type_sequence_t = type_sequence<std::integer_sequence<T, I1, I2s>...>;
218
219 using type = typename sequence_merge<type_sequence_t<I1s>...>::type;
220 };
221
222
223 // Selects least element from a parameter pack based on
224 // LessPred<T1, T2>::value comparison, similar to std::min_element
225 template
226 <
227 template <typename, typename> class LessPred,
228 typename ...Ts
229 >
230 struct pack_min_element;
231
232 template
233 <
234 template <typename, typename> class LessPred,
235 typename T
236 >
237 struct pack_min_element<LessPred, T>
238 {
239 using type = T;
240 };
241
242 template
243 <
244 template <typename, typename> class LessPred,
245 typename T1, typename T2
246 >
247 struct pack_min_element<LessPred, T1, T2>
248 {
249 using type = std::conditional_t<LessPred<T1, T2>::value, T1, T2>;
250 };
251
252 template
253 <
254 template <typename, typename> class LessPred,
255 typename T1, typename T2, typename ...Ts
256 >
257 struct pack_min_element<LessPred, T1, T2, Ts...>
258 {
259 using type = typename pack_min_element
260 <
261 LessPred,
262 typename pack_min_element<LessPred, T1, T2>::type,
263 typename pack_min_element<LessPred, Ts...>::type
264 >::type;
265 };
266
267
268 // Selects least element from a sequence based on
269 // LessPred<T1, T2>::value comparison, similar to std::min_element
270 template
271 <
272 typename Sequence,
273 template <typename, typename> class LessPred
274 >
275 struct sequence_min_element;
276
277 template
278 <
279 typename ...Ts,
280 template <typename, typename> class LessPred
281 >
282 struct sequence_min_element<type_sequence<Ts...>, LessPred>
283 {
284 using type = typename pack_min_element<LessPred, Ts...>::type;
285 };
286
287
288 // TODO: Since there are two kinds of parameter packs and sequences there probably should be two
289 // versions of sequence_find_if as well as parameter_pack_min_element and sequence_min_element.
290 // Currently these utilities support only types.
291
292
293 } // namespace util
294
295
296 }} // namespace boost::geometry
297
298
299 #endif // BOOST_GEOMETRY_UTIL_SEQUENCE_HPP