• 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 #include <boost/hana/and.hpp>
6 #include <boost/hana/assert.hpp>
7 #include <boost/hana/comparing.hpp>
8 #include <boost/hana/div.hpp>
9 #include <boost/hana/equal.hpp>
10 #include <boost/hana/eval_if.hpp>
11 #include <boost/hana/greater.hpp>
12 #include <boost/hana/greater_equal.hpp>
13 #include <boost/hana/if.hpp>
14 #include <boost/hana/less.hpp>
15 #include <boost/hana/less_equal.hpp>
16 #include <boost/hana/max.hpp>
17 #include <boost/hana/min.hpp>
18 #include <boost/hana/minus.hpp>
19 #include <boost/hana/mod.hpp>
20 #include <boost/hana/mult.hpp>
21 #include <boost/hana/negate.hpp>
22 #include <boost/hana/not.hpp>
23 #include <boost/hana/not_equal.hpp>
24 #include <boost/hana/one.hpp>
25 #include <boost/hana/or.hpp>
26 #include <boost/hana/ordering.hpp>
27 #include <boost/hana/plus.hpp>
28 #include <boost/hana/power.hpp>
29 #include <boost/hana/tuple.hpp>
30 #include <boost/hana/while.hpp>
31 #include <boost/hana/zero.hpp>
32 
33 #include <laws/base.hpp>
34 #include <laws/comparable.hpp>
35 #include <laws/euclidean_ring.hpp>
36 #include <laws/group.hpp>
37 #include <laws/logical.hpp>
38 #include <laws/monoid.hpp>
39 #include <laws/orderable.hpp>
40 #include <support/cnumeric.hpp>
41 #include <support/numeric.hpp>
42 
43 #include <cstdlib>
44 #include <vector>
45 namespace hana = boost::hana;
46 
47 
48 struct invalid {
49     template <typename T>
operator T constinvalid50     operator T const() { std::abort(); }
51 };
52 
main()53 int main() {
54     //////////////////////////////////////////////////////////////////////////
55     // Comparable
56     //////////////////////////////////////////////////////////////////////////
57     {
58         hana::test::_injection<0> f{};
59         auto x = numeric(1);
60         auto y = numeric(2);
61 
62         // equal
63         {
64             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(x, x));
65             BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::equal(x, y)));
66         }
67 
68         // not_equal
69         {
70             BOOST_HANA_CONSTEXPR_CHECK(hana::not_equal(x, y));
71             BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::not_equal(x, x)));
72         }
73 
74         // comparing
75         {
76             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
77                 hana::comparing(f)(x, x),
78                 hana::equal(f(x), f(x))
79             ));
80 
81             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
82                 hana::comparing(f)(x, y),
83                 hana::equal(f(x), f(y))
84             ));
85         }
86     }
87 
88     //////////////////////////////////////////////////////////////////////////
89     // Orderable
90     //////////////////////////////////////////////////////////////////////////
91     {
92         auto ord = numeric;
93 
94         // _injection is also monotonic
95         hana::test::_injection<0> f{};
96 
97         // less
98         {
99             BOOST_HANA_CONSTEXPR_CHECK(hana::less(ord(0), ord(1)));
100             BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::less(ord(0), ord(0))));
101             BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::less(ord(1), ord(0))));
102         }
103 
104         // less_equal
105         {
106             BOOST_HANA_CONSTEXPR_CHECK(hana::less_equal(ord(0), ord(1)));
107             BOOST_HANA_CONSTEXPR_CHECK(hana::less_equal(ord(0), ord(0)));
108             BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::less_equal(ord(1), ord(0))));
109         }
110 
111         // greater_equal
112         {
113             BOOST_HANA_CONSTEXPR_CHECK(hana::greater_equal(ord(1), ord(0)));
114             BOOST_HANA_CONSTEXPR_CHECK(hana::greater_equal(ord(0), ord(0)));
115             BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::greater_equal(ord(0), ord(1))));
116         }
117 
118         // greater
119         {
120             BOOST_HANA_CONSTEXPR_CHECK(hana::greater(ord(1), ord(0)));
121             BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::greater(ord(0), ord(0))));
122             BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::greater(ord(0), ord(1))));
123         }
124 
125         // max
126         {
127             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
128                 hana::max(ord(0), ord(0)), ord(0)
129             ));
130             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
131                 hana::max(ord(1), ord(0)), ord(1)
132             ));
133             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
134                 hana::max(ord(0), ord(1)), ord(1)
135             ));
136         }
137 
138         // min
139         {
140             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
141                 hana::min(ord(0), ord(0)),
142                 ord(0)
143             ));
144             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
145                 hana::min(ord(1), ord(0)),
146                 ord(0)
147             ));
148             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
149                 hana::min(ord(0), ord(1)),
150                 ord(0)
151             ));
152         }
153 
154         // ordering
155         {
156             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
157                 hana::ordering(f)(ord(1), ord(0)),
158                 hana::less(f(ord(1)), f(ord(0)))
159             ));
160 
161             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
162                 hana::ordering(f)(ord(0), ord(1)),
163                 hana::less(f(ord(0)), f(ord(1)))
164             ));
165 
166             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
167                 hana::ordering(f)(ord(0), ord(0)),
168                 hana::less(f(ord(0)), f(ord(0)))
169             ));
170         }
171     }
172 
173     //////////////////////////////////////////////////////////////////////////
174     // Monoid
175     //////////////////////////////////////////////////////////////////////////
176     {
177         constexpr int x = 2, y = 3;
178 
179         // zero
180         {
181             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
182                 hana::zero<Numeric>(), numeric(0)
183             ));
184         }
185 
186         // plus
187         {
188             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
189                 hana::plus(numeric(x), numeric(y)),
190                 numeric(x + y)
191             ));
192         }
193     }
194 
195     //////////////////////////////////////////////////////////////////////////
196     // Group
197     //////////////////////////////////////////////////////////////////////////
198     {
199         constexpr int x = 2, y = 3;
200 
201         // minus
202         {
203             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
204                 hana::minus(numeric(x), numeric(y)),
205                 numeric(x - y)
206             ));
207         }
208 
209         // negate
210         {
211             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
212                 hana::negate(numeric(x)),
213                 numeric(-x)
214             ));
215         }
216     }
217 
218     //////////////////////////////////////////////////////////////////////////
219     // Ring
220     //////////////////////////////////////////////////////////////////////////
221     {
222         constexpr int x = 2, y = 3;
223 
224         // one
225         {
226             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
227                 hana::one<Numeric>(),
228                 numeric(1)
229             ));
230         }
231 
232         // mult
233         {
234             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
235                 hana::mult(numeric(x), numeric(y)),
236                 numeric(x * y)
237             ));
238         }
239 
240         // power
241         {
242             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
243                 hana::power(numeric(x), hana::zero<CNumeric<int>>()),
244                 hana::one<Numeric>()
245             ));
246 
247             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
248                 hana::power(numeric(x), hana::one<CNumeric<int>>()),
249                 numeric(x)
250             ));
251 
252             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
253                 hana::power(numeric(x), cnumeric<int, 2>),
254                 hana::mult(numeric(x), numeric(x))
255             ));
256 
257             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
258                 hana::power(numeric(x), cnumeric<int, 3>),
259                 hana::mult(hana::mult(numeric(x), numeric(x)), numeric(x))
260             ));
261         }
262     }
263 
264     //////////////////////////////////////////////////////////////////////////
265     // EuclideanRing
266     //////////////////////////////////////////////////////////////////////////
267     {
268         constexpr int x = 6, y = 3, z = 4;
269 
270         // div
271         {
272             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
273                 hana::div(numeric(x), numeric(y)),
274                 numeric(x / y)
275             ));
276 
277             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
278                 hana::div(numeric(x), numeric(z)),
279                  numeric(x/ z)
280             ));
281         }
282 
283         // mod
284         {
285             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
286                 hana::mod(numeric(x), numeric(y)),
287                 numeric(x % y)
288             ));
289 
290             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
291                 hana::mod(numeric(x), numeric(z)),
292                 numeric(x % z)
293             ));
294         }
295     }
296 
297     //////////////////////////////////////////////////////////////////////////
298     // Logical
299     //////////////////////////////////////////////////////////////////////////
300     {
301         auto logical = numeric;
302         auto comparable = numeric;
303 
304         // not_
305         {
306             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
307                 hana::not_(logical(true)),
308                 logical(false)
309             ));
310         }
311 
312         // and_
313         {
314             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
315                 hana::and_(logical(true)),
316                 logical(true)
317             ));
318             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
319                 hana::and_(logical(false)),
320                 logical(false)
321             ));
322 
323             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
324                 hana::and_(logical(true), logical(true)),
325                 logical(true)
326             ));
327             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
328                 hana::and_(logical(true), logical(false)),
329                 logical(false)
330             ));
331             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
332                 hana::and_(logical(false), invalid{}),
333                 logical(false)
334             ));
335 
336             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
337                 hana::and_(logical(true), logical(true), logical(true)),
338                 logical(true)
339             ));
340             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
341                 hana::and_(logical(true), logical(true), logical(false)),
342                 logical(false)
343             ));
344             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
345                 hana::and_(logical(true), logical(false), invalid{}),
346                 logical(false)
347             ));
348             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
349                 hana::and_(logical(false), invalid{}, invalid{}),
350                 logical(false)
351             ));
352         }
353 
354         // or_
355         {
356             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
357                 hana::or_(logical(true)),
358                 logical(true)
359             ));
360             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
361                 hana::or_(logical(false)),
362                 logical(false)
363             ));
364 
365             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
366                 hana::or_(logical(false), logical(false)),
367                 logical(false)
368             ));
369             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
370                 hana::or_(logical(false), logical(true)),
371                 logical(true)
372             ));
373             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
374                 hana::or_(logical(true), invalid{}),
375                 logical(true)
376             ));
377 
378             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
379                 hana::or_(logical(false), logical(false), logical(false)),
380                 logical(false)
381             ));
382             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
383                 hana::or_(logical(false), logical(false), logical(true)),
384                 logical(true)
385             ));
386             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
387                 hana::or_(logical(false), logical(true), invalid{}),
388                 logical(true)
389             ));
390             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
391                 hana::or_(logical(true), invalid{}, invalid{}),
392                 logical(true)
393             ));
394         }
395 
396         // if_
397         {
398             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
399                 hana::if_(logical(true), comparable(0), comparable(1)),
400                 comparable(0)
401             ));
402 
403             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
404                 hana::if_(logical(false), comparable(0), comparable(1)),
405                 comparable(1)
406             ));
407         }
408 
409         // eval_if
410         {
411             auto t = [=](auto) { return comparable(0); };
412             auto e = [=](auto) { return comparable(1); };
413 
414             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
415                 hana::eval_if(logical(true), t, e),
416                 comparable(0)
417             ));
418 
419             BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
420                 hana::eval_if(logical(false), t, e),
421                 comparable(1)
422             ));
423         }
424 
425         // while_
426         {
427             auto smaller_than = [](auto n) {
428                 return [n](auto v) { return v.size() < n; };
429             };
430             auto f = [](auto v) {
431                 v.push_back(v.size());
432                 return v;
433             };
434 
435             BOOST_HANA_RUNTIME_CHECK(hana::equal(
436                 hana::while_(smaller_than(0u), std::vector<int>{}, f),
437                 std::vector<int>{}
438             ));
439 
440             BOOST_HANA_RUNTIME_CHECK(hana::equal(
441                 hana::while_(smaller_than(1u), std::vector<int>{}, f),
442                 std::vector<int>{0}
443             ));
444 
445             BOOST_HANA_RUNTIME_CHECK(hana::equal(
446                 hana::while_(smaller_than(2u), std::vector<int>{}, f),
447                 std::vector<int>{0, 1}
448             ));
449 
450             BOOST_HANA_RUNTIME_CHECK(hana::equal(
451                 hana::while_(smaller_than(3u), std::vector<int>{}, f),
452                 std::vector<int>{0, 1, 2}
453             ));
454 
455             BOOST_HANA_RUNTIME_CHECK(hana::equal(
456                 hana::while_(smaller_than(4u), std::vector<int>{}, f),
457                 std::vector<int>{0, 1, 2, 3}
458             ));
459 
460             // Make sure it can be called with an lvalue state:
461             std::vector<int> v{};
462             BOOST_HANA_RUNTIME_CHECK(hana::equal(
463                 hana::while_(smaller_than(4u), v, f),
464                 std::vector<int>{0, 1, 2, 3}
465             ));
466         }
467 
468         // while_
469         {
470             auto less_than = [](auto n) {
471                 return [n](auto v) { return v.size() < n; };
472             };
473             auto f = [](auto v) {
474                 v.push_back(v.size());
475                 return v;
476             };
477 
478             BOOST_HANA_RUNTIME_CHECK(hana::equal(
479                 hana::while_(less_than(0u), std::vector<int>{}, f),
480                 std::vector<int>{}
481             ));
482 
483             BOOST_HANA_RUNTIME_CHECK(hana::equal(
484                 hana::while_(less_than(1u), std::vector<int>{}, f),
485                 std::vector<int>{0}
486             ));
487 
488             BOOST_HANA_RUNTIME_CHECK(hana::equal(
489                 hana::while_(less_than(2u), std::vector<int>{}, f),
490                 std::vector<int>{0, 1}
491             ));
492 
493             BOOST_HANA_RUNTIME_CHECK(hana::equal(
494                 hana::while_(less_than(3u), std::vector<int>{}, f),
495                 std::vector<int>{0, 1, 2}
496             ));
497 
498             BOOST_HANA_RUNTIME_CHECK(hana::equal(
499                 hana::while_(less_than(4u), std::vector<int>{}, f),
500                 std::vector<int>{0, 1, 2, 3}
501             ));
502 
503             // Make sure it can be called with an lvalue state:
504             std::vector<int> v{};
505             BOOST_HANA_RUNTIME_CHECK(hana::equal(
506                 hana::while_(less_than(4u), v, f),
507                 std::vector<int>{0, 1, 2, 3}
508             ));
509         }
510     }
511 }
512