]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/hana/test/functional.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / hana / test / functional.cpp
CommitLineData
b32b8144 1// Copyright Louis Dionne 2013-2017
7c673cae
FG
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
4
5#include <boost/hana/assert.hpp>
6#include <boost/hana/config.hpp>
7#include <boost/hana/functional.hpp>
8
9#include <laws/base.hpp>
10#include <support/tracked.hpp>
11
12#include <utility>
13namespace hana = boost::hana;
14
15
16template <int i = 0>
17struct nonpod : Tracked {
18 nonpod() : Tracked{i} { }
19};
20
21template <int i = 0>
22struct undefined { };
23
24struct move_only {
25 move_only(move_only&&) = default;
26 move_only(move_only const&) = delete;
27};
28
29
30int main() {
31 hana::test::_injection<0> f{};
32 hana::test::_injection<1> g{};
33 hana::test::_injection<2> h{};
34 using hana::test::ct_eq;
35
36 // always
37 {
38 auto z = ct_eq<0>{};
39 BOOST_HANA_CONSTANT_CHECK(hana::equal(
40 hana::always(z)(), z
41 ));
42 BOOST_HANA_CONSTANT_CHECK(hana::equal(
43 hana::always(z)(undefined<1>{}), z
44 ));
45 BOOST_HANA_CONSTANT_CHECK(hana::equal(
46 hana::always(z)(undefined<1>{}, undefined<2>{}), z
47 ));
48 BOOST_HANA_CONSTANT_CHECK(hana::equal(
49 hana::always(z)(undefined<1>{}, undefined<2>{}, undefined<3>{}), z
50 ));
51 BOOST_HANA_CONSTANT_CHECK(hana::equal(
52 hana::always(z)(undefined<1>{}, undefined<2>{}, undefined<3>{}, undefined<4>{}), z
53 ));
54
55 hana::always(z)(nonpod<>{});
56 auto m = hana::always(move_only{})(undefined<1>{}); (void)m;
57 }
58
59 // apply (tested separately)
60 {
61
62 }
63
64 // arg
65 {
66 // moveonly friendliness:
67 move_only z = hana::arg<1>(move_only{}); (void)z;
68
69 BOOST_HANA_CONSTANT_CHECK(hana::equal(
70 hana::arg<1>(ct_eq<1>{}),
71 ct_eq<1>{}
72 ));
73 BOOST_HANA_CONSTANT_CHECK(hana::equal(
74 hana::arg<1>(ct_eq<1>{}, undefined<2>{}),
75 ct_eq<1>{}
76 ));
77 BOOST_HANA_CONSTANT_CHECK(hana::equal(
78 hana::arg<1>(ct_eq<1>{}, undefined<2>{}, undefined<3>{}),
79 ct_eq<1>{}
80 ));
81 hana::arg<1>(nonpod<1>{});
82 hana::arg<1>(nonpod<1>{}, nonpod<2>{});
83
84
85 BOOST_HANA_CONSTANT_CHECK(hana::equal(
86 hana::arg<2>(undefined<1>{}, ct_eq<2>{}),
87 ct_eq<2>{}
88 ));
89 BOOST_HANA_CONSTANT_CHECK(hana::equal(
90 hana::arg<2>(undefined<1>{}, ct_eq<2>{}, undefined<3>{}),
91 ct_eq<2>{}
92 ));
93 hana::arg<2>(nonpod<1>{}, nonpod<2>{});
94 hana::arg<2>(nonpod<1>{}, nonpod<2>{}, nonpod<3>{});
95
96
97 BOOST_HANA_CONSTANT_CHECK(hana::equal(
98 hana::arg<3>(undefined<1>{}, undefined<2>{}, ct_eq<3>{}),
99 ct_eq<3>{}
100 ));
101 BOOST_HANA_CONSTANT_CHECK(hana::equal(
102 hana::arg<3>(undefined<1>{}, undefined<2>{}, ct_eq<3>{}, undefined<4>{}),
103 ct_eq<3>{}
104 ));
105 hana::arg<3>(nonpod<1>{}, nonpod<2>{}, nonpod<3>{});
106 hana::arg<3>(nonpod<1>{}, nonpod<2>{}, nonpod<3>{}, nonpod<4>{});
107
108
109 BOOST_HANA_CONSTANT_CHECK(hana::equal(
110 hana::arg<4>(undefined<1>{}, undefined<2>{}, undefined<3>{}, ct_eq<4>{}),
111 ct_eq<4>{}
112 ));
113 BOOST_HANA_CONSTANT_CHECK(hana::equal(
114 hana::arg<4>(undefined<1>{}, undefined<2>{}, undefined<3>{}, ct_eq<4>{}, undefined<5>{}),
115 ct_eq<4>{}
116 ));
117 hana::arg<4>(nonpod<1>{}, nonpod<2>{}, nonpod<3>{}, nonpod<4>{});
118 hana::arg<4>(nonpod<1>{}, nonpod<2>{}, nonpod<3>{}, nonpod<4>{}, nonpod<5>{});
119
120
121 BOOST_HANA_CONSTANT_CHECK(hana::equal(
122 hana::arg<5>(undefined<1>{}, undefined<2>{}, undefined<3>{}, undefined<4>{}, ct_eq<5>{}),
123 ct_eq<5>{}
124 ));
125 BOOST_HANA_CONSTANT_CHECK(hana::equal(
126 hana::arg<5>(undefined<1>{}, undefined<2>{}, undefined<3>{}, undefined<4>{}, ct_eq<5>{}, undefined<6>{}),
127 ct_eq<5>{}
128 ));
129 hana::arg<5>(nonpod<1>{}, nonpod<2>{}, nonpod<3>{}, nonpod<4>{}, nonpod<5>{});
130 hana::arg<5>(nonpod<1>{}, nonpod<2>{}, nonpod<3>{}, nonpod<4>{}, nonpod<5>{}, nonpod<6>{});
131
132
133 BOOST_HANA_CONSTANT_CHECK(hana::equal(
134 hana::arg<6>(undefined<1>{}, undefined<2>{}, undefined<3>{}, undefined<4>{}, undefined<5>{}, ct_eq<6>{}),
135 ct_eq<6>{}
136 ));
137 BOOST_HANA_CONSTANT_CHECK(hana::equal(
138 hana::arg<6>(undefined<1>{}, undefined<2>{}, undefined<3>{}, undefined<4>{}, undefined<5>{}, ct_eq<6>{}, undefined<7>{}),
139 ct_eq<6>{}
140 ));
141 hana::arg<6>(nonpod<1>{}, nonpod<2>{}, nonpod<3>{}, nonpod<4>{}, nonpod<5>{}, nonpod<6>{});
142 hana::arg<6>(nonpod<1>{}, nonpod<2>{}, nonpod<3>{}, nonpod<4>{}, nonpod<5>{}, nonpod<6>{}, nonpod<7>{});
143 }
144
145 // compose
146 {
147 BOOST_HANA_CONSTANT_CHECK(hana::equal(
148 hana::compose(f, g)(ct_eq<0>{}),
149 f(g(ct_eq<0>{}))
150 ));
151 BOOST_HANA_CONSTANT_CHECK(hana::equal(
152 hana::compose(f, g)(ct_eq<0>{}, ct_eq<1>{}),
153 f(g(ct_eq<0>{}), ct_eq<1>{})
154 ));
155 BOOST_HANA_CONSTANT_CHECK(hana::equal(
156 hana::compose(f, g)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
157 f(g(ct_eq<0>{}), ct_eq<1>{}, ct_eq<2>{})
158 ));
159
160 BOOST_HANA_CONSTANT_CHECK(hana::equal(
161 hana::compose(f, g, h)(ct_eq<0>{}),
162 f(g(h(ct_eq<0>{})))
163 ));
164 BOOST_HANA_CONSTANT_CHECK(hana::equal(
165 hana::compose(f, g, h)(ct_eq<0>{}, ct_eq<1>{}),
166 f(g(h(ct_eq<0>{})), ct_eq<1>{})
167 ));
168 BOOST_HANA_CONSTANT_CHECK(hana::equal(
169 hana::compose(f, g, h)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
170 f(g(h(ct_eq<0>{})), ct_eq<1>{}, ct_eq<2>{})
171 ));
172
173 auto h = [capture = move_only{}](int) { return 1; };
174 auto i = [](int) { return 1; };
175 hana::compose(std::move(h), i)(1);
176
177 {
178 // Compose move-only functions.
179 auto f = [capture = move_only{}] (int) { return 1; };
180 auto g = [capture = move_only{}] (int) { return 1; };
181 auto c = hana::compose(std::move(f), std::move(g)); (void)c;
182 }
183 }
184
185 // curry
186 {
187 BOOST_HANA_CONSTANT_CHECK(hana::equal(
188 hana::curry<0>(f)(),
189 f()
190 ));
191
192 BOOST_HANA_CONSTANT_CHECK(hana::equal(
193 hana::curry<1>(f)(ct_eq<1>{}),
194 f(ct_eq<1>{})
195 ));
196
197 BOOST_HANA_CONSTANT_CHECK(hana::equal(
198 hana::curry<2>(f)(ct_eq<1>{})(ct_eq<2>{}),
199 f(ct_eq<1>{}, ct_eq<2>{})
200 ));
201 BOOST_HANA_CONSTANT_CHECK(hana::equal(
202 hana::curry<2>(f)(ct_eq<1>{}, ct_eq<2>{}),
203 f(ct_eq<1>{}, ct_eq<2>{})
204 ));
205
206 BOOST_HANA_CONSTANT_CHECK(hana::equal(
207 hana::curry<3>(f)(ct_eq<1>{})(ct_eq<2>{})(ct_eq<3>{}),
208 f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
209 ));
210 BOOST_HANA_CONSTANT_CHECK(hana::equal(
211 hana::curry<3>(f)(ct_eq<1>{})(ct_eq<2>{}, ct_eq<3>{}),
212 f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
213 ));
214 BOOST_HANA_CONSTANT_CHECK(hana::equal(
215 hana::curry<3>(f)(ct_eq<1>{}, ct_eq<2>{})(ct_eq<3>{}),
216 f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
217 ));
218 BOOST_HANA_CONSTANT_CHECK(hana::equal(
219 hana::curry<3>(f)(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
220 f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
221 ));
222
223
224 // Make sure curry is idempotent; this is important because it allows
225 // currying a function in generic contexts where it is unknown whether
226 // the function is already curried.
227 BOOST_HANA_CONSTANT_CHECK(hana::equal(
228 hana::curry<0>(hana::curry<0>(f))(),
229 f()
230 ));
231
232 BOOST_HANA_CONSTANT_CHECK(hana::equal(
233 hana::curry<1>(hana::curry<1>(f))(ct_eq<1>{}),
234 f(ct_eq<1>{})
235 ));
236
237 BOOST_HANA_CONSTANT_CHECK(hana::equal(
238 hana::curry<2>(hana::curry<2>(f))(ct_eq<1>{})(ct_eq<2>{}),
239 f(ct_eq<1>{}, ct_eq<2>{})
240 ));
241 BOOST_HANA_CONSTANT_CHECK(hana::equal(
242 hana::curry<2>(hana::curry<2>(f))(ct_eq<1>{}, ct_eq<2>{}),
243 f(ct_eq<1>{}, ct_eq<2>{})
244 ));
245
246 BOOST_HANA_CONSTANT_CHECK(hana::equal(
247 hana::curry<3>(hana::curry<3>(f))(ct_eq<1>{})(ct_eq<2>{})(ct_eq<3>{}),
248 f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
249 ));
250 BOOST_HANA_CONSTANT_CHECK(hana::equal(
251 hana::curry<3>(hana::curry<3>(f))(ct_eq<1>{})(ct_eq<2>{}, ct_eq<3>{}),
252 f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
253 ));
254 BOOST_HANA_CONSTANT_CHECK(hana::equal(
255 hana::curry<3>(hana::curry<3>(f))(ct_eq<1>{}, ct_eq<2>{})(ct_eq<3>{}),
256 f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
257 ));
258 BOOST_HANA_CONSTANT_CHECK(hana::equal(
259 hana::curry<3>(hana::curry<3>(f))(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
260 f(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
261 ));
262 }
263
264 // demux (tested separately)
265 {
266
267 }
268
269 // fix (tested separately)
270 {
271
272 }
273
274 // flip
275 {
276 BOOST_HANA_CONSTANT_CHECK(hana::equal(
277 hana::flip(f)(ct_eq<1>{}, ct_eq<2>{}),
278 f(ct_eq<2>{}, ct_eq<1>{})
279 ));
280 BOOST_HANA_CONSTANT_CHECK(hana::equal(
281 hana::flip(f)(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
282 f(ct_eq<2>{}, ct_eq<1>{}, ct_eq<3>{})
283 ));
284 BOOST_HANA_CONSTANT_CHECK(hana::equal(
285 hana::flip(f)(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}),
286 f(ct_eq<2>{}, ct_eq<1>{}, ct_eq<3>{}, ct_eq<4>{})
287 ));
288 BOOST_HANA_CONSTANT_CHECK(hana::equal(
289 hana::flip(f)(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{}),
290 f(ct_eq<2>{}, ct_eq<1>{}, ct_eq<3>{}, ct_eq<4>{}, ct_eq<5>{})
291 ));
292 }
293
294 // id
295 {
296 BOOST_HANA_CONSTANT_CHECK(hana::equal(
297 hana::id(ct_eq<0>{}),
298 ct_eq<0>{}
299 ));
300 BOOST_HANA_CONSTANT_CHECK(hana::equal(
301 hana::id(ct_eq<1>{}),
302 ct_eq<1>{}
303 ));
304
305 (void)hana::id(move_only{});
306
307 // make sure we don't return a dangling reference
308 auto f = []() -> decltype(auto) { return hana::id(Tracked{1}); };
309 auto z = f(); (void)z;
310 }
311
312 // lockstep (tested separately)
313 {
314
315 }
316
317 // infix
318 {
319 auto g = hana::infix(f);
320
321 // disregard associativity
322 BOOST_HANA_CONSTANT_CHECK(hana::equal(
323 ct_eq<0>{} ^g^ ct_eq<1>{},
324 f(ct_eq<0>{}, ct_eq<1>{})
325 ));
326 BOOST_HANA_CONSTANT_CHECK(hana::equal(
327 (ct_eq<0>{} ^g)^ ct_eq<1>{},
328 f(ct_eq<0>{}, ct_eq<1>{})
329 ));
330 BOOST_HANA_CONSTANT_CHECK(hana::equal(
331 ct_eq<0>{} ^(g^ ct_eq<1>{}),
332 f(ct_eq<0>{}, ct_eq<1>{})
333 ));
334
335 // left partial application
336 BOOST_HANA_CONSTANT_CHECK(hana::equal(
337 (ct_eq<0>{}^g)(ct_eq<1>{}),
338 f(ct_eq<0>{}, ct_eq<1>{})
339 ));
340 BOOST_HANA_CONSTANT_CHECK(hana::equal(
341 (ct_eq<0>{}^g)(ct_eq<1>{}, ct_eq<2>{}),
342 f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
343 ));
344 BOOST_HANA_CONSTANT_CHECK(hana::equal(
345 (ct_eq<0>{}^g)(ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
346 f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
347 ));
348
349 // right partial application
350 BOOST_HANA_CONSTANT_CHECK(hana::equal(
351 (g^ct_eq<1>{})(ct_eq<0>{}),
352 f(ct_eq<0>{}, ct_eq<1>{})
353 ));
354 BOOST_HANA_CONSTANT_CHECK(hana::equal(
355 (g^ct_eq<2>{})(ct_eq<0>{}, ct_eq<1>{}),
356 f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
357 ));
358 BOOST_HANA_CONSTANT_CHECK(hana::equal(
359 (g^ct_eq<3>{})(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
360 f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
361 ));
362
363 // equivalence with the base function
364 BOOST_HANA_CONSTANT_CHECK(hana::equal(
365 g(ct_eq<0>{}, ct_eq<1>{}),
366 f(ct_eq<0>{}, ct_eq<1>{})
367 ));
368 BOOST_HANA_CONSTANT_CHECK(hana::equal(
369 g(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
370 f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})
371 ));
372 BOOST_HANA_CONSTANT_CHECK(hana::equal(
373 g(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
374 f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{})
375 ));
376 }
377
378 // on
379 {
380 BOOST_HANA_CONSTANT_CHECK(hana::equal(
381 hana::on(f, g)(),
382 f()
383 ));
384 BOOST_HANA_CONSTANT_CHECK(hana::equal(
385 hana::on(f, g)(ct_eq<0>{}),
386 f(g(ct_eq<0>{}))
387 ));
388 BOOST_HANA_CONSTANT_CHECK(hana::equal(
389 hana::on(f, g)(ct_eq<0>{}, ct_eq<1>{}),
390 f(g(ct_eq<0>{}), g(ct_eq<1>{}))
391 ));
392 BOOST_HANA_CONSTANT_CHECK(hana::equal(
393 hana::on(f, g)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
394 f(g(ct_eq<0>{}), g(ct_eq<1>{}), g(ct_eq<2>{}))
395 ));
396 BOOST_HANA_CONSTANT_CHECK(hana::equal(
397 hana::on(f, g)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
398 f(g(ct_eq<0>{}), g(ct_eq<1>{}), g(ct_eq<2>{}), g(ct_eq<3>{}))
399 ));
400
401 // check the infix version
402 BOOST_HANA_CONSTANT_CHECK(hana::equal(
403 (f ^hana::on^ g)(),
404 f()
405 ));
406 BOOST_HANA_CONSTANT_CHECK(hana::equal(
407 (f ^hana::on^ g)(ct_eq<0>{}),
408 f(g(ct_eq<0>{}))
409 ));
410 BOOST_HANA_CONSTANT_CHECK(hana::equal(
411 (f ^hana::on^ g)(ct_eq<0>{}, ct_eq<1>{}),
412 f(g(ct_eq<0>{}), g(ct_eq<1>{}))
413 ));
414 BOOST_HANA_CONSTANT_CHECK(hana::equal(
415 (f ^hana::on^ g)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}),
416 f(g(ct_eq<0>{}), g(ct_eq<1>{}), g(ct_eq<2>{}))
417 ));
418 BOOST_HANA_CONSTANT_CHECK(hana::equal(
419 (f ^hana::on^ g)(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}),
420 f(g(ct_eq<0>{}), g(ct_eq<1>{}), g(ct_eq<2>{}), g(ct_eq<3>{}))
421 ));
422 }
423
424 // overload
425 {
426 // 1 function
427 {
428 auto f = hana::overload([](int) { return ct_eq<1>{}; });
429 BOOST_HANA_CONSTANT_CHECK(hana::equal(f(int{}), ct_eq<1>{}));
430 }
431
432 // 2 functions
433 {
434 auto f = hana::overload(
435 [](int) { return ct_eq<1>{}; },
436 [](float) { return ct_eq<2>{}; }
437 );
438 BOOST_HANA_CONSTANT_CHECK(hana::equal(f(int{}), ct_eq<1>{}));
439 BOOST_HANA_CONSTANT_CHECK(hana::equal(f(float{}), ct_eq<2>{}));
440 }
441
442 // 3 functions
443 {
444 auto f = hana::overload(
445 [](int) { return ct_eq<1>{}; },
446 [](float) { return ct_eq<2>{}; },
447 static_cast<ct_eq<3>(*)(char)>([](char) { return ct_eq<3>{}; })
448 );
449 BOOST_HANA_CONSTANT_CHECK(hana::equal(f(int{}), ct_eq<1>{}));
450 BOOST_HANA_CONSTANT_CHECK(hana::equal(f(float{}), ct_eq<2>{}));
451 BOOST_HANA_CONSTANT_CHECK(hana::equal(f(char{}), ct_eq<3>{}));
452 }
453
454 // 4 functions
455 {
456 auto f = hana::overload(
457 [](int) { return ct_eq<1>{}; },
458 [](float) { return ct_eq<2>{}; },
459 static_cast<ct_eq<3>(*)(char)>([](char) { return ct_eq<3>{}; }),
460 [](auto) { return ct_eq<4>{}; }
461 );
462
463 struct otherwise { };
464 BOOST_HANA_CONSTANT_CHECK(hana::equal(f(int{}), ct_eq<1>{}));
465 BOOST_HANA_CONSTANT_CHECK(hana::equal(f(float{}), ct_eq<2>{}));
466 BOOST_HANA_CONSTANT_CHECK(hana::equal(f(char{}), ct_eq<3>{}));
467 BOOST_HANA_CONSTANT_CHECK(hana::equal(f(otherwise{}), ct_eq<4>{}));
468 }
469
470 // check move-only friendliness for bare functions
471 {
472 void (*g)(move_only) = [](move_only) { };
473 hana::overload(g)(move_only{});
474 }
475
476 // check non-strict matches which require a conversion
477 {
478 struct convertible_to_int { operator int() const { return 1; } };
479 auto f = [](int) { return ct_eq<0>{}; };
480
481 BOOST_HANA_CONSTANT_CHECK(hana::equal(
482 hana::overload(f)(convertible_to_int{}),
483 ct_eq<0>{}
484 ));
485
486 BOOST_HANA_CONSTANT_CHECK(hana::equal(
487 hana::overload(static_cast<ct_eq<0>(*)(int)>(f))(convertible_to_int{}),
488 ct_eq<0>{}
489 ));
490 }
491 }
492
493 // partial (tested separately)
494 {
495
496 }
497
498 // placeholder (tested separately)
499 {
500
501 }
502}