• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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