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