]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/test/functional.cpp
1 // Copyright Louis Dionne 2013-2017
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)
5 #include <boost/hana/assert.hpp>
6 #include <boost/hana/config.hpp>
7 #include <boost/hana/functional.hpp>
9 #include <laws/base.hpp>
10 #include <support/tracked.hpp>
13 namespace hana
= boost::hana
;
17 struct nonpod
: Tracked
{
18 nonpod() : Tracked
{i
} { }
25 move_only(move_only
&&) = default;
26 move_only(move_only
const&) = delete;
31 hana::test::_injection
<0> f
{};
32 hana::test::_injection
<1> g
{};
33 hana::test::_injection
<2> h
{};
34 using hana::test::ct_eq
;
39 BOOST_HANA_CONSTANT_CHECK(hana::equal(
42 BOOST_HANA_CONSTANT_CHECK(hana::equal(
43 hana::always(z
)(undefined
<1>{}), z
45 BOOST_HANA_CONSTANT_CHECK(hana::equal(
46 hana::always(z
)(undefined
<1>{}, undefined
<2>{}), z
48 BOOST_HANA_CONSTANT_CHECK(hana::equal(
49 hana::always(z
)(undefined
<1>{}, undefined
<2>{}, undefined
<3>{}), z
51 BOOST_HANA_CONSTANT_CHECK(hana::equal(
52 hana::always(z
)(undefined
<1>{}, undefined
<2>{}, undefined
<3>{}, undefined
<4>{}), z
55 hana::always(z
)(nonpod
<>{});
56 auto m
= hana::always(move_only
{})(undefined
<1>{}); (void)m
;
59 // apply (tested separately)
66 // moveonly friendliness:
67 move_only z
= hana::arg
<1>(move_only
{}); (void)z
;
69 BOOST_HANA_CONSTANT_CHECK(hana::equal(
70 hana::arg
<1>(ct_eq
<1>{}),
73 BOOST_HANA_CONSTANT_CHECK(hana::equal(
74 hana::arg
<1>(ct_eq
<1>{}, undefined
<2>{}),
77 BOOST_HANA_CONSTANT_CHECK(hana::equal(
78 hana::arg
<1>(ct_eq
<1>{}, undefined
<2>{}, undefined
<3>{}),
81 hana::arg
<1>(nonpod
<1>{});
82 hana::arg
<1>(nonpod
<1>{}, nonpod
<2>{});
85 BOOST_HANA_CONSTANT_CHECK(hana::equal(
86 hana::arg
<2>(undefined
<1>{}, ct_eq
<2>{}),
89 BOOST_HANA_CONSTANT_CHECK(hana::equal(
90 hana::arg
<2>(undefined
<1>{}, ct_eq
<2>{}, undefined
<3>{}),
93 hana::arg
<2>(nonpod
<1>{}, nonpod
<2>{});
94 hana::arg
<2>(nonpod
<1>{}, nonpod
<2>{}, nonpod
<3>{});
97 BOOST_HANA_CONSTANT_CHECK(hana::equal(
98 hana::arg
<3>(undefined
<1>{}, undefined
<2>{}, ct_eq
<3>{}),
101 BOOST_HANA_CONSTANT_CHECK(hana::equal(
102 hana::arg
<3>(undefined
<1>{}, undefined
<2>{}, ct_eq
<3>{}, undefined
<4>{}),
105 hana::arg
<3>(nonpod
<1>{}, nonpod
<2>{}, nonpod
<3>{});
106 hana::arg
<3>(nonpod
<1>{}, nonpod
<2>{}, nonpod
<3>{}, nonpod
<4>{});
109 BOOST_HANA_CONSTANT_CHECK(hana::equal(
110 hana::arg
<4>(undefined
<1>{}, undefined
<2>{}, undefined
<3>{}, ct_eq
<4>{}),
113 BOOST_HANA_CONSTANT_CHECK(hana::equal(
114 hana::arg
<4>(undefined
<1>{}, undefined
<2>{}, undefined
<3>{}, ct_eq
<4>{}, undefined
<5>{}),
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>{});
121 BOOST_HANA_CONSTANT_CHECK(hana::equal(
122 hana::arg
<5>(undefined
<1>{}, undefined
<2>{}, undefined
<3>{}, undefined
<4>{}, ct_eq
<5>{}),
125 BOOST_HANA_CONSTANT_CHECK(hana::equal(
126 hana::arg
<5>(undefined
<1>{}, undefined
<2>{}, undefined
<3>{}, undefined
<4>{}, ct_eq
<5>{}, undefined
<6>{}),
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>{});
133 BOOST_HANA_CONSTANT_CHECK(hana::equal(
134 hana::arg
<6>(undefined
<1>{}, undefined
<2>{}, undefined
<3>{}, undefined
<4>{}, undefined
<5>{}, ct_eq
<6>{}),
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>{}),
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>{});
147 BOOST_HANA_CONSTANT_CHECK(hana::equal(
148 hana::compose(f
, g
)(ct_eq
<0>{}),
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>{})
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>{})
160 BOOST_HANA_CONSTANT_CHECK(hana::equal(
161 hana::compose(f
, g
, h
)(ct_eq
<0>{}),
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>{})
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>{})
173 auto h
= [capture
= move_only
{}](int) { return 1; };
174 auto i
= [](int) { return 1; };
175 hana::compose(std::move(h
), i
)(1);
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
;
187 BOOST_HANA_CONSTANT_CHECK(hana::equal(
192 BOOST_HANA_CONSTANT_CHECK(hana::equal(
193 hana::curry
<1>(f
)(ct_eq
<1>{}),
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>{})
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>{})
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>{})
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>{})
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>{})
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>{})
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
))(),
232 BOOST_HANA_CONSTANT_CHECK(hana::equal(
233 hana::curry
<1>(hana::curry
<1>(f
))(ct_eq
<1>{}),
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>{})
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>{})
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>{})
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>{})
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>{})
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>{})
264 // demux (tested separately)
269 // fix (tested separately)
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>{})
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>{})
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>{})
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>{})
296 BOOST_HANA_CONSTANT_CHECK(hana::equal(
297 hana::id(ct_eq
<0>{}),
300 BOOST_HANA_CONSTANT_CHECK(hana::equal(
301 hana::id(ct_eq
<1>{}),
305 (void)hana::id(move_only
{});
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
;
312 // lockstep (tested separately)
319 auto g
= hana::infix(f
);
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>{})
326 BOOST_HANA_CONSTANT_CHECK(hana::equal(
327 (ct_eq
<0>{} ^g
)^ ct_eq
<1>{},
328 f(ct_eq
<0>{}, ct_eq
<1>{})
330 BOOST_HANA_CONSTANT_CHECK(hana::equal(
331 ct_eq
<0>{} ^(g
^ ct_eq
<1>{}),
332 f(ct_eq
<0>{}, ct_eq
<1>{})
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>{})
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>{})
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>{})
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>{})
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>{})
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>{})
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>{})
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>{})
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>{})
380 BOOST_HANA_CONSTANT_CHECK(hana::equal(
384 BOOST_HANA_CONSTANT_CHECK(hana::equal(
385 hana::on(f
, g
)(ct_eq
<0>{}),
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>{}))
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>{}))
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>{}))
401 // check the infix version
402 BOOST_HANA_CONSTANT_CHECK(hana::equal(
406 BOOST_HANA_CONSTANT_CHECK(hana::equal(
407 (f
^hana::on
^ g
)(ct_eq
<0>{}),
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>{}))
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>{}))
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>{}))
428 auto f
= hana::overload([](int) { return ct_eq
<1>{}; });
429 BOOST_HANA_CONSTANT_CHECK(hana::equal(f(int{}), ct_eq
<1>{}));
434 auto f
= hana::overload(
435 [](int) { return ct_eq
<1>{}; },
436 [](float) { return ct_eq
<2>{}; }
438 BOOST_HANA_CONSTANT_CHECK(hana::equal(f(int{}), ct_eq
<1>{}));
439 BOOST_HANA_CONSTANT_CHECK(hana::equal(f(float{}), ct_eq
<2>{}));
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>{}; })
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>{}));
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>{}; }
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>{}));
470 // check move-only friendliness for bare functions
472 void (*g
)(move_only
) = [](move_only
) { };
473 hana::overload(g
)(move_only
{});
476 // check non-strict matches which require a conversion
478 struct convertible_to_int
{ operator int() const { return 1; } };
479 auto f
= [](int) { return ct_eq
<0>{}; };
481 BOOST_HANA_CONSTANT_CHECK(hana::equal(
482 hana::overload(f
)(convertible_to_int
{}),
486 BOOST_HANA_CONSTANT_CHECK(hana::equal(
487 hana::overload(static_cast<ct_eq
<0>(*)(int)>(f
))(convertible_to_int
{}),
493 // partial (tested separately)
498 // placeholder (tested separately)