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) 4 5 #ifndef BOOST_HANA_TEST_LAWS_FOLDABLE_HPP 6 #define BOOST_HANA_TEST_LAWS_FOLDABLE_HPP 7 8 #include <boost/hana/assert.hpp> 9 #include <boost/hana/chain.hpp> 10 #include <boost/hana/concept/comparable.hpp> 11 #include <boost/hana/concept/foldable.hpp> 12 #include <boost/hana/concept/product.hpp> 13 #include <boost/hana/concept/sequence.hpp> 14 #include <boost/hana/config.hpp> 15 #include <boost/hana/core/make.hpp> 16 #include <boost/hana/core/when.hpp> 17 #include <boost/hana/count.hpp> 18 #include <boost/hana/count_if.hpp> 19 #include <boost/hana/equal.hpp> 20 #include <boost/hana/first.hpp> 21 #include <boost/hana/fold.hpp> 22 #include <boost/hana/fold_left.hpp> 23 #include <boost/hana/fold_right.hpp> 24 #include <boost/hana/for_each.hpp> 25 #include <boost/hana/functional/capture.hpp> 26 #include <boost/hana/functional/curry.hpp> 27 #include <boost/hana/functional/demux.hpp> 28 #include <boost/hana/functional/flip.hpp> 29 #include <boost/hana/integral_constant.hpp> 30 #include <boost/hana/lazy.hpp> 31 #include <boost/hana/length.hpp> 32 #include <boost/hana/lift.hpp> 33 #include <boost/hana/maximum.hpp> 34 #include <boost/hana/minimum.hpp> 35 #include <boost/hana/monadic_fold_left.hpp> 36 #include <boost/hana/monadic_fold_right.hpp> 37 #include <boost/hana/not_equal.hpp> 38 #include <boost/hana/product.hpp> 39 #include <boost/hana/reverse_fold.hpp> 40 #include <boost/hana/second.hpp> 41 #include <boost/hana/size.hpp> 42 #include <boost/hana/sum.hpp> 43 #include <boost/hana/unpack.hpp> 44 #include <boost/hana/value.hpp> 45 46 #include <laws/base.hpp> 47 #include <support/identity.hpp> 48 49 #include <vector> 50 51 52 namespace boost { namespace hana { namespace test { 53 template <typename F, typename = when<true>> 54 struct TestFoldable : TestFoldable<F, laws> { 55 using TestFoldable<F, laws>::TestFoldable; 56 }; 57 58 template <typename F> 59 struct TestFoldable<F, laws> { 60 template <typename Foldables> TestFoldableboost::hana::test::TestFoldable61 TestFoldable(Foldables foldables) { 62 hana::for_each(foldables, [](auto xs) { 63 static_assert(Foldable<decltype(xs)>{}, ""); 64 65 _injection<0> f{}; 66 ct_eq<999> s{}; 67 68 // equivalence of size(xs) and length(xs) 69 BOOST_HANA_CHECK(hana::equal( 70 hana::length(xs), 71 hana::size(xs) 72 )); 73 74 // equivalence of fold with fold_left and 75 // of reverse_fold with fold_right 76 BOOST_HANA_CHECK(hana::equal( 77 hana::fold(xs, s, f), 78 hana::fold_left(xs, s, f) 79 )); 80 81 BOOST_HANA_CHECK(hana::equal( 82 hana::reverse_fold(xs, s, f), 83 hana::fold_right(xs, s, hana::flip(f)) 84 )); 85 86 only_when_(hana::not_equal(hana::length(xs), hana::size_c<0>), 87 hana::make_lazy([](auto f, auto xs) { 88 BOOST_HANA_CHECK(hana::equal( 89 hana::fold(xs, f), 90 hana::fold_left(xs, f) 91 )); 92 93 BOOST_HANA_CHECK(hana::equal( 94 hana::reverse_fold(xs, f), 95 hana::fold_right(xs, hana::flip(f)) 96 )); 97 })(f, xs)); 98 99 // equivalence of count(xs, val) and count_if(xs, equal.to(val)) 100 struct not_there { }; 101 BOOST_HANA_CHECK(hana::equal( 102 hana::count(xs, not_there{}), 103 hana::count_if(xs, equal.to(not_there{})) 104 )); 105 106 hana::for_each(xs, hana::capture(xs)([](auto xs, auto value) { 107 BOOST_HANA_CHECK(hana::equal( 108 hana::count(xs, value), 109 hana::count_if(xs, equal.to(value)) 110 )); 111 })); 112 }); 113 } 114 }; 115 116 template <typename P> 117 struct TestFoldable<P, when<Product<P>::value>> 118 : TestFoldable<P, laws> 119 { 120 template <typename Products> TestFoldableboost::hana::test::TestFoldable121 TestFoldable(Products products) : TestFoldable<P, laws>{products} { __anon0fd87a2e0402boost::hana::test::TestFoldable122 hana::for_each(products, [](auto p) { 123 _injection<0> f{}; 124 125 BOOST_HANA_CHECK(hana::equal( 126 hana::unpack(p, f), 127 f(hana::first(p), hana::second(p)) 128 )); 129 }); 130 } 131 }; 132 133 template <typename S> 134 struct TestFoldable<S, when<Sequence<S>::value>> 135 : TestFoldable<S, laws> 136 { 137 template <int i> 138 using x = _constant<i>; 139 140 template <int i> 141 using ord = _constant<i>; 142 143 struct undefined { }; 144 145 template <typename Xs> TestFoldableboost::hana::test::TestFoldable146 TestFoldable(Xs xs) : TestFoldable<S, laws>{xs} { 147 _injection<0> f{}; 148 auto z = x<999>{}; 149 constexpr auto list = make<S>; 150 151 ////////////////////////////////////////////////////////////////// 152 // fold_left (with initial state) 153 ////////////////////////////////////////////////////////////////// 154 BOOST_HANA_CONSTANT_CHECK(equal( 155 fold_left(list(), z, undefined{}), 156 z 157 )); 158 159 BOOST_HANA_CONSTANT_CHECK(equal( 160 fold_left(list(x<1>{}), z, f), 161 f(z, x<1>{}) 162 )); 163 BOOST_HANA_CONSTANT_CHECK(equal( 164 fold_left(list(x<1>{}, x<2>{}), z, f), 165 f(f(z, x<1>{}), x<2>{}) 166 )); 167 BOOST_HANA_CONSTANT_CHECK(equal( 168 fold_left(list(x<1>{}, x<2>{}, x<3>{}), z, f), 169 f(f(f(z, x<1>{}), x<2>{}), x<3>{}) 170 )); 171 BOOST_HANA_CONSTANT_CHECK(equal( 172 fold_left(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}), z, f), 173 f(f(f(f(z, x<1>{}), x<2>{}), x<3>{}), x<4>{}) 174 )); 175 176 BOOST_HANA_CONSTEXPR_CHECK(equal( 177 fold_left(list(1), z, f), 178 f(z, 1) 179 )); 180 BOOST_HANA_CONSTEXPR_CHECK(equal( 181 fold_left(list(1, '2'), z, f), 182 f(f(z, 1), '2') 183 )); 184 BOOST_HANA_CONSTEXPR_CHECK(equal( 185 fold_left(list(1, '2', 3.3), z, f), 186 f(f(f(z, 1), '2'), 3.3) 187 )); 188 BOOST_HANA_CONSTEXPR_CHECK(equal( 189 fold_left(list(1, '2', 3.3, 4.4f), z, f), 190 f(f(f(f(z, 1), '2'), 3.3), 4.4f) 191 )); 192 193 ////////////////////////////////////////////////////////////////// 194 // fold_left (without initial state) 195 ////////////////////////////////////////////////////////////////// 196 BOOST_HANA_CONSTANT_CHECK(equal( 197 fold_left(list(z), undefined{}), 198 z 199 )); 200 BOOST_HANA_CONSTANT_CHECK(equal( 201 fold_left(list(z, x<2>{}), f), 202 f(z, x<2>{}) 203 )); 204 BOOST_HANA_CONSTANT_CHECK(equal( 205 fold_left(list(z, x<2>{}, x<3>{}), f), 206 f(f(z, x<2>{}), x<3>{}) 207 )); 208 BOOST_HANA_CONSTANT_CHECK(equal( 209 fold_left(list(z, x<2>{}, x<3>{}, x<4>{}), f), 210 f(f(f(z, x<2>{}), x<3>{}), x<4>{}) 211 )); 212 213 ////////////////////////////////////////////////////////////////// 214 // fold_right (with initial state) 215 ////////////////////////////////////////////////////////////////// 216 BOOST_HANA_CONSTANT_CHECK(equal( 217 fold_right(list(), z, undefined{}), 218 z 219 )); 220 221 BOOST_HANA_CONSTANT_CHECK(equal( 222 fold_right(list(x<0>{}), z, f), 223 f(x<0>{}, z) 224 )); 225 BOOST_HANA_CONSTANT_CHECK(equal( 226 fold_right(list(x<0>{}, x<1>{}), z, f), 227 f(x<0>{}, f(x<1>{}, z)) 228 )); 229 BOOST_HANA_CONSTANT_CHECK(equal( 230 fold_right(list(x<0>{}, x<1>{}, x<2>{}), z, f), 231 f(x<0>{}, f(x<1>{}, f(x<2>{}, z))) 232 )); 233 BOOST_HANA_CONSTANT_CHECK(equal( 234 fold_right(list(x<0>{}, x<1>{}, x<2>{}, x<3>{}), z, f), 235 f(x<0>{}, f(x<1>{}, f(x<2>{}, f(x<3>{}, z)))) 236 )); 237 238 239 BOOST_HANA_CONSTEXPR_CHECK(equal( 240 fold_right(list(1), z, f), 241 f(1, z) 242 )); 243 BOOST_HANA_CONSTEXPR_CHECK(equal( 244 fold_right(list(1, '2'), z, f), 245 f(1, f('2', z)) 246 )); 247 BOOST_HANA_CONSTEXPR_CHECK(equal( 248 fold_right(list(1, '2', 3.3), z, f), 249 f(1, f('2', f(3.3, z))) 250 )); 251 BOOST_HANA_CONSTEXPR_CHECK(equal( 252 fold_right(list(1, '2', 3.3, 4.4f), z, f), 253 f(1, f('2', f(3.3, f(4.4f, z)))) 254 )); 255 256 ////////////////////////////////////////////////////////////////// 257 // fold_right (without initial state) 258 ////////////////////////////////////////////////////////////////// 259 BOOST_HANA_CONSTANT_CHECK(equal( 260 fold_right(list(z), undefined{}), 261 z 262 )); 263 BOOST_HANA_CONSTANT_CHECK(equal( 264 fold_right(list(x<1>{}, z), f), 265 f(x<1>{}, z) 266 )); 267 BOOST_HANA_CONSTANT_CHECK(equal( 268 fold_right(list(x<1>{}, x<2>{}, z), f), 269 f(x<1>{}, f(x<2>{}, z)) 270 )); 271 BOOST_HANA_CONSTANT_CHECK(equal( 272 fold_right(list(x<1>{}, x<2>{}, x<3>{}, z), f), 273 f(x<1>{}, f(x<2>{}, f(x<3>{}, z))) 274 )); 275 276 ////////////////////////////////////////////////////////////////// 277 // monadic_fold_left (with initial state) 278 ////////////////////////////////////////////////////////////////// 279 { 280 using M = ::Identity; 281 auto f = hana::demux(::identity)(test::_injection<0>{}); 282 auto s = x<999>{}; 283 auto fp = hana::curry<2>(hana::flip(f)); 284 constexpr auto mfold = monadic_fold_left<M>; 285 286 BOOST_HANA_CONSTANT_CHECK(equal( 287 mfold(list(), s, undefined{}), 288 lift<M>(s) 289 )); 290 291 BOOST_HANA_CONSTANT_CHECK(equal( 292 mfold(list(x<1>{}), s, f), 293 f(s, x<1>{}) 294 )); 295 296 BOOST_HANA_CONSTANT_CHECK(equal( 297 mfold(list(x<1>{}, x<2>{}), s, f), 298 chain(f(s, x<1>{}), fp(x<2>{})) 299 )); 300 301 BOOST_HANA_CONSTANT_CHECK(equal( 302 mfold(list(x<1>{}, x<2>{}, x<3>{}), s, f), 303 chain(chain(f(s, x<1>{}), fp(x<2>{})), fp(x<3>{})) 304 )); 305 306 BOOST_HANA_CONSTANT_CHECK(equal( 307 mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}), s, f), 308 chain(chain(chain(f(s, x<1>{}), fp(x<2>{})), fp(x<3>{})), fp(x<4>{})) 309 )); 310 311 BOOST_HANA_CONSTANT_CHECK(equal( 312 mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}), s, f), 313 chain(chain(chain(chain(f(s, x<1>{}), fp(x<2>{})), fp(x<3>{})), fp(x<4>{})), fp(x<5>{})) 314 )); 315 } 316 317 ////////////////////////////////////////////////////////////////// 318 // monadic_fold_left (without initial state) 319 ////////////////////////////////////////////////////////////////// 320 { 321 using M = ::Identity; 322 auto f = hana::demux(::identity)(test::_injection<0>{}); 323 auto fp = hana::curry<2>(hana::flip(f)); 324 constexpr auto mfold = monadic_fold_left<M>; 325 326 BOOST_HANA_CONSTANT_CHECK(equal( 327 mfold(list(x<1>{}), undefined{}), 328 lift<M>(x<1>{}) 329 )); 330 331 BOOST_HANA_CONSTANT_CHECK(equal( 332 mfold(list(x<1>{}, x<2>{}), f), 333 f(x<1>{}, x<2>{}) 334 )); 335 336 BOOST_HANA_CONSTANT_CHECK(equal( 337 mfold(list(x<1>{}, x<2>{}, x<3>{}), f), 338 chain(f(x<1>{}, x<2>{}), fp(x<3>{})) 339 )); 340 341 BOOST_HANA_CONSTANT_CHECK(equal( 342 mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}), f), 343 chain(chain(f(x<1>{}, x<2>{}), fp(x<3>{})), fp(x<4>{})) 344 )); 345 346 BOOST_HANA_CONSTANT_CHECK(equal( 347 mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}), f), 348 chain(chain(chain(f(x<1>{}, x<2>{}), fp(x<3>{})), fp(x<4>{})), fp(x<5>{})) 349 )); 350 } 351 352 ////////////////////////////////////////////////////////////////// 353 // monadic_fold_right (with initial state) 354 ////////////////////////////////////////////////////////////////// 355 { 356 using M = ::Identity; 357 auto f = hana::demux(::identity)(test::_injection<0>{}); 358 auto s = x<999>{}; 359 auto fp = hana::curry<2>(f); 360 // flipping `chain` makes the right associativity easier to see 361 auto chain = hana::flip(hana::chain); 362 constexpr auto mfold = monadic_fold_right<M>; 363 364 BOOST_HANA_CONSTANT_CHECK(equal( 365 mfold(list(), s, undefined{}), 366 lift<M>(s) 367 )); 368 369 BOOST_HANA_CONSTANT_CHECK(equal( 370 mfold(list(x<1>{}), s, f), 371 f(x<1>{}, s) 372 )); 373 374 BOOST_HANA_CONSTANT_CHECK(equal( 375 mfold(list(x<1>{}, x<2>{}), s, f), 376 chain(fp(x<1>{}), f(x<2>{}, s)) 377 )); 378 379 BOOST_HANA_CONSTANT_CHECK(equal( 380 mfold(list(x<1>{}, x<2>{}, x<3>{}), s, f), 381 chain(fp(x<1>{}), chain(fp(x<2>{}), f(x<3>{}, s))) 382 )); 383 384 BOOST_HANA_CONSTANT_CHECK(equal( 385 mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}), s, f), 386 chain(fp(x<1>{}), chain(fp(x<2>{}), chain(fp(x<3>{}), f(x<4>{}, s)))) 387 )); 388 389 BOOST_HANA_CONSTANT_CHECK(equal( 390 mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}), s, f), 391 chain(fp(x<1>{}), chain(fp(x<2>{}), chain(fp(x<3>{}), chain(fp(x<4>{}), f(x<5>{}, s))))) 392 )); 393 } 394 395 ////////////////////////////////////////////////////////////////// 396 // monadic_fold_right (without initial state) 397 ////////////////////////////////////////////////////////////////// 398 { 399 using M = ::Identity; 400 auto f = hana::demux(::identity)(test::_injection<0>{}); 401 auto fp = hana::curry<2>(f); 402 // flipping `chain` makes the right associativity easier to see 403 auto chain = hana::flip(hana::chain); 404 constexpr auto mfold = monadic_fold_right<M>; 405 406 BOOST_HANA_CONSTANT_CHECK(equal( 407 mfold(list(x<1>{}), undefined{}), 408 lift<M>(x<1>{}) 409 )); 410 411 BOOST_HANA_CONSTANT_CHECK(equal( 412 mfold(list(x<1>{}, x<2>{}), f), 413 f(x<1>{}, x<2>{}) 414 )); 415 416 BOOST_HANA_CONSTANT_CHECK(equal( 417 mfold(list(x<1>{}, x<2>{}, x<3>{}), f), 418 chain(fp(x<1>{}), f(x<2>{}, x<3>{})) 419 )); 420 421 BOOST_HANA_CONSTANT_CHECK(equal( 422 mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}), f), 423 chain(fp(x<1>{}), chain(fp(x<2>{}), f(x<3>{}, x<4>{}))) 424 )); 425 426 BOOST_HANA_CONSTANT_CHECK(equal( 427 mfold(list(x<1>{}, x<2>{}, x<3>{}, x<4>{}, x<5>{}), f), 428 chain(fp(x<1>{}), chain(fp(x<2>{}), chain(fp(x<3>{}), f(x<4>{}, x<5>{})))) 429 )); 430 } 431 432 ////////////////////////////////////////////////////////////////// 433 // length 434 ////////////////////////////////////////////////////////////////// 435 BOOST_HANA_CONSTANT_CHECK(equal( 436 length(list()), size_c<0> 437 )); 438 BOOST_HANA_CONSTANT_CHECK(equal( 439 length(list(undefined{})), size_c<1> 440 )); 441 BOOST_HANA_CONSTANT_CHECK(equal( 442 length(list(undefined{}, undefined{})), size_c<2> 443 )); 444 BOOST_HANA_CONSTANT_CHECK(equal( 445 length(list(undefined{}, undefined{}, undefined{})), size_c<3> 446 )); 447 448 int i = 0; // non-constexpr 449 BOOST_HANA_CONSTANT_CHECK(equal( 450 length(list(i, i)), 451 size_c<2> 452 )); 453 454 ////////////////////////////////////////////////////////////////// 455 // maximum (without a custom predicate) 456 ////////////////////////////////////////////////////////////////// 457 { 458 BOOST_HANA_CONSTANT_CHECK(equal( 459 maximum(list(ord<0>{})), 460 ord<0>{} 461 )); 462 463 BOOST_HANA_CONSTANT_CHECK(equal( 464 maximum(list(ord<0>{}, ord<1>{})), 465 ord<1>{} 466 )); 467 BOOST_HANA_CONSTANT_CHECK(equal( 468 maximum(list(ord<1>{}, ord<0>{})), 469 ord<1>{} 470 )); 471 472 BOOST_HANA_CONSTANT_CHECK(equal( 473 maximum(list(ord<0>{}, ord<1>{}, ord<2>{})), 474 ord<2>{} 475 )); 476 BOOST_HANA_CONSTANT_CHECK(equal( 477 maximum(list(ord<1>{}, ord<0>{}, ord<2>{})), 478 ord<2>{} 479 )); 480 BOOST_HANA_CONSTANT_CHECK(equal( 481 maximum(list(ord<1>{}, ord<2>{}, ord<0>{})), 482 ord<2>{} 483 )); 484 BOOST_HANA_CONSTANT_CHECK(equal( 485 maximum(list(ord<2>{}, ord<1>{}, ord<0>{})), 486 ord<2>{} 487 )); 488 BOOST_HANA_CONSTANT_CHECK(equal( 489 maximum(list(ord<2>{}, ord<0>{}, ord<1>{})), 490 ord<2>{} 491 )); 492 493 BOOST_HANA_CONSTANT_CHECK(equal( 494 maximum(list(ord<0>{}, ord<1>{}, ord<2>{}, ord<3>{})), 495 ord<3>{} 496 )); 497 BOOST_HANA_CONSTANT_CHECK(equal( 498 maximum(list(ord<1>{}, ord<0>{}, ord<2>{}, ord<3>{})), 499 ord<3>{} 500 )); 501 BOOST_HANA_CONSTANT_CHECK(equal( 502 maximum(list(ord<1>{}, ord<2>{}, ord<0>{}, ord<3>{})), 503 ord<3>{} 504 )); 505 BOOST_HANA_CONSTANT_CHECK(equal( 506 maximum(list(ord<1>{}, ord<2>{}, ord<3>{}, ord<0>{})), 507 ord<3>{} 508 )); 509 BOOST_HANA_CONSTANT_CHECK(equal( 510 maximum(list(ord<2>{}, ord<1>{}, ord<3>{}, ord<0>{})), 511 ord<3>{} 512 )); 513 BOOST_HANA_CONSTANT_CHECK(equal( 514 maximum(list(ord<2>{}, ord<3>{}, ord<1>{}, ord<0>{})), 515 ord<3>{} 516 )); 517 BOOST_HANA_CONSTANT_CHECK(equal( 518 maximum(list(ord<2>{}, ord<3>{}, ord<0>{}, ord<1>{})), 519 ord<3>{} 520 )); 521 BOOST_HANA_CONSTANT_CHECK(equal( 522 maximum(list(ord<3>{}, ord<2>{}, ord<0>{}, ord<1>{})), 523 ord<3>{} 524 )); 525 BOOST_HANA_CONSTANT_CHECK(equal( 526 maximum(list(ord<3>{}, ord<0>{}, ord<2>{}, ord<1>{})), 527 ord<3>{} 528 )); 529 BOOST_HANA_CONSTANT_CHECK(equal( 530 maximum(list(ord<3>{}, ord<0>{}, ord<1>{}, ord<2>{})), 531 ord<3>{} 532 )); 533 BOOST_HANA_CONSTANT_CHECK(equal( 534 maximum(list(ord<0>{}, ord<2>{}, ord<3>{}, ord<1>{})), 535 ord<3>{} 536 )); 537 BOOST_HANA_CONSTANT_CHECK(equal( 538 maximum(list(ord<0>{}, ord<3>{}, ord<1>{}, ord<2>{})), 539 ord<3>{} 540 )); 541 542 543 BOOST_HANA_CONSTEXPR_CHECK(equal( 544 maximum(list(int{0})), 545 int{0} 546 )); 547 548 BOOST_HANA_CONSTEXPR_CHECK(equal( 549 maximum(list(int{0}, long{1})), 550 long{1} 551 )); 552 BOOST_HANA_CONSTEXPR_CHECK(equal( 553 maximum(list(int{1}, long{0})), 554 int{1} 555 )); 556 557 BOOST_HANA_CONSTEXPR_CHECK(equal( 558 maximum(list(int{0}, 1ll, long{2})), 559 long{2} 560 )); 561 BOOST_HANA_CONSTEXPR_CHECK(equal( 562 maximum(list(int{1}, 0ll, long{2})), 563 long{2} 564 )); 565 BOOST_HANA_CONSTEXPR_CHECK(equal( 566 maximum(list(int{1}, 2ll, long{0})), 567 2ll 568 )); 569 BOOST_HANA_CONSTEXPR_CHECK(equal( 570 maximum(list(int{2}, 1ll, long{0})), 571 int{2} 572 )); 573 BOOST_HANA_CONSTEXPR_CHECK(equal( 574 maximum(list(int{2}, 0ll, long{1})), 575 int{2} 576 )); 577 578 BOOST_HANA_CONSTEXPR_CHECK(equal( 579 maximum(list(int{0}, 1ll, long{2}, short{3})), 580 short{3} 581 )); 582 BOOST_HANA_CONSTEXPR_CHECK(equal( 583 maximum(list(int{1}, 0ll, long{2}, short{3})), 584 short{3} 585 )); 586 BOOST_HANA_CONSTEXPR_CHECK(equal( 587 maximum(list(int{1}, 2ll, long{0}, short{3})), 588 short{3} 589 )); 590 BOOST_HANA_CONSTEXPR_CHECK(equal( 591 maximum(list(int{1}, 2ll, long{3}, short{0})), 592 long{3} 593 )); 594 BOOST_HANA_CONSTEXPR_CHECK(equal( 595 maximum(list(int{2}, 1ll, long{3}, short{0})), 596 long{3} 597 )); 598 BOOST_HANA_CONSTEXPR_CHECK(equal( 599 maximum(list(int{2}, 3ll, long{1}, short{0})), 600 3ll 601 )); 602 BOOST_HANA_CONSTEXPR_CHECK(equal( 603 maximum(list(int{2}, 3ll, long{0}, short{1})), 604 3ll 605 )); 606 BOOST_HANA_CONSTEXPR_CHECK(equal( 607 maximum(list(int{3}, 2ll, long{0}, short{1})), 608 int{3} 609 )); 610 BOOST_HANA_CONSTEXPR_CHECK(equal( 611 maximum(list(int{3}, 0ll, long{2}, short{1})), 612 int{3} 613 )); 614 BOOST_HANA_CONSTEXPR_CHECK(equal( 615 maximum(list(int{3}, 0ll, long{1}, short{2})), 616 int{3} 617 )); 618 BOOST_HANA_CONSTEXPR_CHECK(equal( 619 maximum(list(int{0}, 2ll, long{3}, short{1})), 620 long{3} 621 )); 622 BOOST_HANA_CONSTEXPR_CHECK(equal( 623 maximum(list(int{0}, 3ll, long{1}, short{2})), 624 3ll 625 )); 626 627 628 BOOST_HANA_CONSTEXPR_CHECK(equal( 629 maximum(list(int{0}, 1ll, long_c<2>)), 630 long{2} 631 )); 632 BOOST_HANA_CONSTEXPR_CHECK(equal( 633 maximum(list(int{0}, long_c<1>, 2ll)), 634 2ll 635 )); 636 } 637 638 ////////////////////////////////////////////////////////////////// 639 // minimum (without a custom predicate) 640 ////////////////////////////////////////////////////////////////// 641 { 642 BOOST_HANA_CONSTANT_CHECK(equal( 643 minimum(list(ord<6>{})), 644 ord<6>{} 645 )); 646 647 BOOST_HANA_CONSTANT_CHECK(equal( 648 minimum(list(ord<6>{}, ord<7>{})), 649 ord<6>{} 650 )); 651 BOOST_HANA_CONSTANT_CHECK(equal( 652 minimum(list(ord<7>{}, ord<6>{})), 653 ord<6>{} 654 )); 655 656 BOOST_HANA_CONSTANT_CHECK(equal( 657 minimum(list(ord<6>{}, ord<7>{}, ord<8>{})), 658 ord<6>{} 659 )); 660 BOOST_HANA_CONSTANT_CHECK(equal( 661 minimum(list(ord<7>{}, ord<6>{}, ord<8>{})), 662 ord<6>{} 663 )); 664 BOOST_HANA_CONSTANT_CHECK(equal( 665 minimum(list(ord<7>{}, ord<8>{}, ord<6>{})), 666 ord<6>{} 667 )); 668 BOOST_HANA_CONSTANT_CHECK(equal( 669 minimum(list(ord<8>{}, ord<7>{}, ord<6>{})), 670 ord<6>{} 671 )); 672 BOOST_HANA_CONSTANT_CHECK(equal( 673 minimum(list(ord<8>{}, ord<6>{}, ord<7>{})), 674 ord<6>{} 675 )); 676 677 BOOST_HANA_CONSTANT_CHECK(equal( 678 minimum(list(ord<6>{}, ord<7>{}, ord<8>{}, ord<9>{})), 679 ord<6>{} 680 )); 681 BOOST_HANA_CONSTANT_CHECK(equal( 682 minimum(list(ord<7>{}, ord<6>{}, ord<8>{}, ord<9>{})), 683 ord<6>{} 684 )); 685 BOOST_HANA_CONSTANT_CHECK(equal( 686 minimum(list(ord<7>{}, ord<8>{}, ord<6>{}, ord<9>{})), 687 ord<6>{} 688 )); 689 BOOST_HANA_CONSTANT_CHECK(equal( 690 minimum(list(ord<7>{}, ord<8>{}, ord<9>{}, ord<6>{})), 691 ord<6>{} 692 )); 693 BOOST_HANA_CONSTANT_CHECK(equal( 694 minimum(list(ord<8>{}, ord<7>{}, ord<9>{}, ord<6>{})), 695 ord<6>{} 696 )); 697 BOOST_HANA_CONSTANT_CHECK(equal( 698 minimum(list(ord<8>{}, ord<9>{}, ord<7>{}, ord<6>{})), 699 ord<6>{} 700 )); 701 BOOST_HANA_CONSTANT_CHECK(equal( 702 minimum(list(ord<8>{}, ord<9>{}, ord<6>{}, ord<7>{})), 703 ord<6>{} 704 )); 705 BOOST_HANA_CONSTANT_CHECK(equal( 706 minimum(list(ord<9>{}, ord<8>{}, ord<6>{}, ord<7>{})), 707 ord<6>{} 708 )); 709 BOOST_HANA_CONSTANT_CHECK(equal( 710 minimum(list(ord<9>{}, ord<6>{}, ord<8>{}, ord<7>{})), 711 ord<6>{} 712 )); 713 BOOST_HANA_CONSTANT_CHECK(equal( 714 minimum(list(ord<9>{}, ord<6>{}, ord<7>{}, ord<8>{})), 715 ord<6>{} 716 )); 717 BOOST_HANA_CONSTANT_CHECK(equal( 718 minimum(list(ord<6>{}, ord<8>{}, ord<9>{}, ord<7>{})), 719 ord<6>{} 720 )); 721 BOOST_HANA_CONSTANT_CHECK(equal( 722 minimum(list(ord<6>{}, ord<9>{}, ord<7>{}, ord<8>{})), 723 ord<6>{} 724 )); 725 726 727 BOOST_HANA_CONSTEXPR_CHECK(equal( 728 minimum(list(int{4})), 729 int{4} 730 )); 731 732 BOOST_HANA_CONSTEXPR_CHECK(equal( 733 minimum(list(int{4}, short{5})), 734 int{4} 735 )); 736 BOOST_HANA_CONSTEXPR_CHECK(equal( 737 minimum(list(int{5}, short{4})), 738 short{4} 739 )); 740 741 BOOST_HANA_CONSTEXPR_CHECK(equal( 742 minimum(list(int{4}, short{5}, long{6})), 743 int{4} 744 )); 745 BOOST_HANA_CONSTEXPR_CHECK(equal( 746 minimum(list(int{7}, short{6}, long{8})), 747 short{6} 748 )); 749 BOOST_HANA_CONSTEXPR_CHECK(equal( 750 minimum(list(int{7}, short{8}, long{6})), 751 long{6} 752 )); 753 BOOST_HANA_CONSTEXPR_CHECK(equal( 754 minimum(list(int{8}, short{7}, long{6})), 755 long{6} 756 )); 757 BOOST_HANA_CONSTEXPR_CHECK(equal( 758 minimum(list(int{8}, short{6}, long{7})), 759 short{6} 760 )); 761 762 BOOST_HANA_CONSTEXPR_CHECK(equal( 763 minimum(list(int{6}, short{7}, long{8}, 9ll)), 764 int{6} 765 )); 766 BOOST_HANA_CONSTEXPR_CHECK(equal( 767 minimum(list(int{7}, short{6}, long{8}, 9ll)), 768 short{6} 769 )); 770 BOOST_HANA_CONSTEXPR_CHECK(equal( 771 minimum(list(int{7}, short{8}, long{6}, 9ll)), 772 long{6} 773 )); 774 BOOST_HANA_CONSTEXPR_CHECK(equal( 775 minimum(list(int{7}, short{8}, long{9}, 6ll)), 776 6ll 777 )); 778 BOOST_HANA_CONSTEXPR_CHECK(equal( 779 minimum(list(int{8}, short{7}, long{9}, 6ll)), 780 6ll 781 )); 782 BOOST_HANA_CONSTEXPR_CHECK(equal( 783 minimum(list(int{8}, short{9}, long{7}, 6ll)), 784 6ll 785 )); 786 BOOST_HANA_CONSTEXPR_CHECK(equal( 787 minimum(list(int{8}, short{9}, long{6}, 7ll)), 788 long{6} 789 )); 790 BOOST_HANA_CONSTEXPR_CHECK(equal( 791 minimum(list(int{9}, short{8}, long{6}, 7ll)), 792 long{6} 793 )); 794 BOOST_HANA_CONSTEXPR_CHECK(equal( 795 minimum(list(int{9}, short{6}, long{8}, 7ll)), 796 short{6} 797 )); 798 BOOST_HANA_CONSTEXPR_CHECK(equal( 799 minimum(list(int{9}, short{6}, long{7}, 8ll)), 800 short{6} 801 )); 802 BOOST_HANA_CONSTEXPR_CHECK(equal( 803 minimum(list(int{6}, short{8}, long{9}, 7ll)), 804 int{6} 805 )); 806 BOOST_HANA_CONSTEXPR_CHECK(equal( 807 minimum(list(int{6}, short{9}, long{7}, 8ll)), 808 int{6} 809 )); 810 811 812 BOOST_HANA_CONSTEXPR_CHECK(equal( 813 minimum(list(int{3}, short{4}, long_c<5>)), 814 int{3} 815 )); 816 BOOST_HANA_CONSTEXPR_CHECK(equal( 817 minimum(list(ord<33>{}, short{45}, long{46})), 818 ord<33>{} 819 )); 820 } 821 822 823 ////////////////////////////////////////////////////////////////// 824 // count_if 825 ////////////////////////////////////////////////////////////////// 826 BOOST_HANA_CONSTANT_CHECK(equal( 827 count_if(list(), id), size_c<0> 828 )); 829 BOOST_HANA_CONSTANT_CHECK(equal( 830 count_if(list(int_c<1>), id), size_c<1> 831 )); 832 BOOST_HANA_CONSTANT_CHECK(equal( 833 count_if(list(int_c<0>), id), size_c<0> 834 )); 835 836 BOOST_HANA_CONSTANT_CHECK(equal( 837 count_if(list(int_c<1>, char_c<1>), id), size_c<2> 838 )); 839 BOOST_HANA_CONSTANT_CHECK(equal( 840 count_if(list(int_c<1>, char_c<0>), id), size_c<1> 841 )); 842 BOOST_HANA_CONSTANT_CHECK(equal( 843 count_if(list(int_c<0>, char_c<1>), id), size_c<1> 844 )); 845 BOOST_HANA_CONSTANT_CHECK(equal( 846 count_if(list(int_c<0>, char_c<0>), id), size_c<0> 847 )); 848 849 BOOST_HANA_CONSTANT_CHECK(equal( 850 count_if(list(int_c<1>, char_c<1>, long_c<1>), id), size_c<3> 851 )); 852 BOOST_HANA_CONSTANT_CHECK(equal( 853 count_if(list(int_c<1>, char_c<1>, long_c<0>), id), size_c<2> 854 )); 855 BOOST_HANA_CONSTANT_CHECK(equal( 856 count_if(list(int_c<1>, char_c<0>, long_c<1>), id), size_c<2> 857 )); 858 BOOST_HANA_CONSTANT_CHECK(equal( 859 count_if(list(int_c<1>, char_c<0>, long_c<0>), id), size_c<1> 860 )); 861 BOOST_HANA_CONSTANT_CHECK(equal( 862 count_if(list(int_c<0>, char_c<1>, long_c<1>), id), size_c<2> 863 )); 864 BOOST_HANA_CONSTANT_CHECK(equal( 865 count_if(list(int_c<0>, char_c<1>, long_c<0>), id), size_c<1> 866 )); 867 BOOST_HANA_CONSTANT_CHECK(equal( 868 count_if(list(int_c<0>, char_c<0>, long_c<1>), id), size_c<1> 869 )); 870 BOOST_HANA_CONSTANT_CHECK(equal( 871 count_if(list(int_c<0>, char_c<0>, long_c<0>), id), size_c<0> 872 )); 873 874 875 BOOST_HANA_CONSTEXPR_CHECK(equal( 876 count_if(list(int{1}), id), 1u 877 )); 878 BOOST_HANA_CONSTEXPR_CHECK(equal( 879 count_if(list(int{0}), id), 0u 880 )); 881 882 BOOST_HANA_CONSTEXPR_CHECK(equal( 883 count_if(list(int{1}, char{1}), id), 2u 884 )); 885 BOOST_HANA_CONSTEXPR_CHECK(equal( 886 count_if(list(int{1}, char{0}), id), 1u 887 )); 888 BOOST_HANA_CONSTEXPR_CHECK(equal( 889 count_if(list(int{0}, char{1}), id), 1u 890 )); 891 BOOST_HANA_CONSTEXPR_CHECK(equal( 892 count_if(list(int{0}, char{0}), id), 0u 893 )); 894 895 BOOST_HANA_CONSTEXPR_CHECK(equal( 896 count_if(list(int{1}, char{1}, double{1}), id), 3u 897 )); 898 BOOST_HANA_CONSTEXPR_CHECK(equal( 899 count_if(list(int{1}, char{1}, double{0}), id), 2u 900 )); 901 BOOST_HANA_CONSTEXPR_CHECK(equal( 902 count_if(list(int{1}, char{0}, double{1}), id), 2u 903 )); 904 BOOST_HANA_CONSTEXPR_CHECK(equal( 905 count_if(list(int{1}, char{0}, double{0}), id), 1u 906 )); 907 BOOST_HANA_CONSTEXPR_CHECK(equal( 908 count_if(list(int{0}, char{1}, double{1}), id), 2u 909 )); 910 BOOST_HANA_CONSTEXPR_CHECK(equal( 911 count_if(list(int{0}, char{1}, double{0}), id), 1u 912 )); 913 BOOST_HANA_CONSTEXPR_CHECK(equal( 914 count_if(list(int{0}, char{0}, double{1}), id), 1u 915 )); 916 BOOST_HANA_CONSTEXPR_CHECK(equal( 917 count_if(list(int{0}, char{0}, double{0}), id), 0u 918 )); 919 920 __anon0fd87a2e0502boost::hana::test::TestFoldable921 BOOST_HANA_CONSTEXPR_LAMBDA auto is_even = [](auto x) { 922 return x % 2 == 0; 923 }; 924 BOOST_HANA_CONSTEXPR_CHECK(equal( 925 count_if(list(), is_even), 0u 926 )); 927 BOOST_HANA_CONSTEXPR_CHECK(equal( 928 count_if(list(1), is_even), 0u 929 )); 930 BOOST_HANA_CONSTEXPR_CHECK(equal( 931 count_if(list(2), is_even), 1u 932 )); 933 BOOST_HANA_CONSTEXPR_CHECK(equal( 934 count_if(list(1, 2), is_even), 1u 935 )); 936 BOOST_HANA_CONSTEXPR_CHECK(equal( 937 count_if(list(1, 2, 3), is_even), 1u 938 )); 939 BOOST_HANA_CONSTEXPR_CHECK(equal( 940 count_if(list(1, 2, 3, 4), is_even), 2u 941 )); 942 943 ////////////////////////////////////////////////////////////////// 944 // count 945 ////////////////////////////////////////////////////////////////// 946 BOOST_HANA_CONSTANT_CHECK(hana::equal( 947 hana::count(list(), undefined{}), 948 size_c<0> 949 )); 950 951 BOOST_HANA_CONSTANT_CHECK(hana::equal( 952 hana::count(list(ct_eq<0>{}), undefined{}), 953 size_c<0> 954 )); 955 BOOST_HANA_CONSTANT_CHECK(hana::equal( 956 hana::count(list(ct_eq<0>{}), ct_eq<0>{}), 957 size_c<1> 958 )); 959 960 BOOST_HANA_CONSTANT_CHECK(hana::equal( 961 hana::count(list(ct_eq<0>{}, ct_eq<1>{}), undefined{}), 962 size_c<0> 963 )); 964 BOOST_HANA_CONSTANT_CHECK(hana::equal( 965 hana::count(list(ct_eq<0>{}, ct_eq<1>{}), ct_eq<0>{}), 966 size_c<1> 967 )); 968 BOOST_HANA_CONSTANT_CHECK(hana::equal( 969 hana::count(list(ct_eq<0>{}, ct_eq<1>{}), ct_eq<1>{}), 970 size_c<1> 971 )); 972 BOOST_HANA_CONSTANT_CHECK(hana::equal( 973 hana::count(list(ct_eq<0>{}, ct_eq<0>{}), ct_eq<0>{}), 974 size_c<2> 975 )); 976 977 ////////////////////////////////////////////////////////////////// 978 // product 979 ////////////////////////////////////////////////////////////////// 980 BOOST_HANA_CONSTANT_CHECK(equal( 981 product<integral_constant_tag<int>>(list()), 982 int_c<1> 983 )); 984 BOOST_HANA_CONSTANT_CHECK(equal( 985 product<integral_constant_tag<int>>(list(int_c<2>)), 986 int_c<2> 987 )); 988 BOOST_HANA_CONSTANT_CHECK(equal( 989 product<integral_constant_tag<int>>(list(int_c<2>, int_c<3>)), 990 int_c<2 * 3> 991 )); 992 BOOST_HANA_CONSTANT_CHECK(equal( 993 product<integral_constant_tag<int>>(list(int_c<2>, int_c<3>, int_c<4>)), 994 int_c<2 * 3 * 4> 995 )); 996 BOOST_HANA_CONSTANT_CHECK(equal( 997 product<integral_constant_tag<int>>(list(int_c<2>, int_c<3>, int_c<4>, int_c<5>)), 998 int_c<2 * 3 * 4 * 5> 999 )); 1000 1001 BOOST_HANA_CONSTANT_CHECK(equal( 1002 product<integral_constant_tag<unsigned long>>(list()), 1003 ulong_c<1> 1004 )); 1005 BOOST_HANA_CONSTANT_CHECK(equal( 1006 product<integral_constant_tag<unsigned long>>(list(ulong_c<2>, ulong_c<3>, ulong_c<4>)), 1007 ulong_c<2 * 3 * 4> 1008 )); 1009 1010 BOOST_HANA_CONSTEXPR_CHECK(equal( 1011 product<int>(list(2)), 1012 2 1013 )); 1014 BOOST_HANA_CONSTEXPR_CHECK(equal( 1015 product<int>(list(2, 3)), 1016 2 * 3 1017 )); 1018 BOOST_HANA_CONSTEXPR_CHECK(equal( 1019 product<int>(list(2, 3, 4)), 1020 2 * 3 * 4 1021 )); 1022 BOOST_HANA_CONSTEXPR_CHECK(equal( 1023 product<int>(list(2, 3, 4, 5)), 1024 2 * 3 * 4 * 5 1025 )); 1026 1027 1028 ////////////////////////////////////////////////////////////////// 1029 // sum 1030 ////////////////////////////////////////////////////////////////// 1031 BOOST_HANA_CONSTANT_CHECK(equal( 1032 sum<integral_constant_tag<int>>(list()), 1033 int_c<0> 1034 )); 1035 BOOST_HANA_CONSTANT_CHECK(equal( 1036 sum<integral_constant_tag<int>>(list(int_c<1>)), 1037 int_c<1> 1038 )); 1039 BOOST_HANA_CONSTANT_CHECK(equal( 1040 sum<integral_constant_tag<int>>(list(int_c<1>, int_c<2>)), 1041 int_c<1 + 2> 1042 )); 1043 BOOST_HANA_CONSTANT_CHECK(equal( 1044 sum<integral_constant_tag<int>>(list(int_c<1>, int_c<2>, int_c<3>)), 1045 int_c<1 + 2 + 3> 1046 )); 1047 BOOST_HANA_CONSTANT_CHECK(equal( 1048 sum<integral_constant_tag<int>>(list(int_c<1>, int_c<2>, int_c<3>, int_c<4>)), 1049 int_c<1 + 2 + 3 + 4> 1050 )); 1051 1052 1053 BOOST_HANA_CONSTANT_CHECK(equal( 1054 sum<integral_constant_tag<unsigned long>>(list()), 1055 ulong_c<0> 1056 )); 1057 BOOST_HANA_CONSTANT_CHECK(equal( 1058 sum<integral_constant_tag<unsigned long>>(list(ulong_c<1>, ulong_c<2>, ulong_c<3>)), 1059 ulong_c<1 + 2 + 3> 1060 )); 1061 1062 1063 BOOST_HANA_CONSTEXPR_CHECK(equal( 1064 sum<int>(list(1)), 1 1065 )); 1066 BOOST_HANA_CONSTEXPR_CHECK(equal( 1067 sum<int>(list(1, 2)), 1 + 2 1068 )); 1069 BOOST_HANA_CONSTEXPR_CHECK(equal( 1070 sum<int>(list(1, 2, 3)), 1 + 2 + 3 1071 )); 1072 BOOST_HANA_CONSTEXPR_CHECK(equal( 1073 sum<int>(list(1, 2, 3, 4)), 1 + 2 + 3 + 4 1074 )); 1075 1076 1077 ////////////////////////////////////////////////////////////////// 1078 // unpack 1079 ////////////////////////////////////////////////////////////////// 1080 BOOST_HANA_CONSTANT_CHECK(equal( 1081 unpack(list(), f), 1082 f() 1083 )); 1084 BOOST_HANA_CONSTANT_CHECK(equal( 1085 unpack(list(x<0>{}), f), 1086 f(x<0>{}) 1087 )); 1088 BOOST_HANA_CONSTANT_CHECK(equal( 1089 unpack(list(x<0>{}, x<1>{}), f), 1090 f(x<0>{}, x<1>{}) 1091 )); 1092 BOOST_HANA_CONSTANT_CHECK(equal( 1093 unpack(list(x<0>{}, x<1>{}, x<2>{}), f), 1094 f(x<0>{}, x<1>{}, x<2>{}) 1095 )); 1096 BOOST_HANA_CONSTANT_CHECK(equal( 1097 unpack(list(x<0>{}, x<1>{}, x<2>{}, x<3>{}), f), 1098 f(x<0>{}, x<1>{}, x<2>{}, x<3>{}) 1099 )); 1100 } 1101 }; 1102 }}} // end namespace boost::hana::test 1103 1104 #endif // !BOOST_HANA_TEST_LAWS_FOLDABLE_HPP 1105