• 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/adjust_if.hpp>
6 #include <boost/hana/ap.hpp>
7 #include <boost/hana/assert.hpp>
8 #include <boost/hana/chain.hpp>
9 #include <boost/hana/equal.hpp>
10 #include <boost/hana/fill.hpp>
11 #include <boost/hana/functional/always.hpp>
12 #include <boost/hana/functional/compose.hpp>
13 #include <boost/hana/lift.hpp>
14 #include <boost/hana/replace_if.hpp>
15 #include <boost/hana/tap.hpp>
16 #include <boost/hana/then.hpp>
17 #include <boost/hana/transform.hpp>
18 #include <boost/hana/tuple.hpp>
19 
20 #include <laws/applicative.hpp>
21 #include <laws/base.hpp>
22 #include <laws/functor.hpp>
23 #include <laws/monad.hpp>
24 #include <support/cnumeric.hpp>
25 #include <support/identity.hpp>
26 namespace hana = boost::hana;
27 using hana::test::ct_eq;
28 
29 
main()30 int main() {
31     hana::test::_injection<0> f{};
32 
33     // Functor
34     {
35         auto functor = ::identity;
36         // adjust_if
37         {
38             BOOST_HANA_CONSTANT_CHECK(hana::equal(
39                 hana::adjust_if(functor(ct_eq<0>{}), hana::always(cnumeric<bool, true>), f),
40                 functor(f(ct_eq<0>{}))
41             ));
42 
43             BOOST_HANA_CONSTANT_CHECK(hana::equal(
44                 hana::adjust_if(functor(ct_eq<0>{}), hana::always(cnumeric<bool, false>), f),
45                 functor(ct_eq<0>{})
46             ));
47         }
48 
49         // fill
50         {
51             BOOST_HANA_CONSTANT_CHECK(hana::equal(
52                 hana::fill(functor(ct_eq<0>{}), ct_eq<1>{}),
53                 functor(ct_eq<1>{})
54             ));
55         }
56 
57         // transform
58         {
59             BOOST_HANA_CONSTANT_CHECK(hana::equal(
60                 hana::transform(functor(ct_eq<0>{}), f),
61                 functor(f(ct_eq<0>{}))
62             ));
63         }
64 
65         // replace_if
66         {
67             BOOST_HANA_CONSTANT_CHECK(hana::equal(
68                 hana::replace_if(functor(ct_eq<0>{}), hana::always(cnumeric<bool, true>), ct_eq<1>{}),
69                 functor(ct_eq<1>{})
70             ));
71 
72             BOOST_HANA_CONSTANT_CHECK(hana::equal(
73                 hana::replace_if(functor(ct_eq<0>{}), hana::always(cnumeric<bool, false>), ct_eq<1>{}),
74                 functor(ct_eq<0>{})
75             ));
76         }
77     }
78 
79     // Applicative
80     {
81         auto a = ::identity;
82         using A = ::Identity;
83 
84         // ap
85         {
86             BOOST_HANA_CONSTANT_CHECK(hana::equal(
87                 hana::ap(a(f), a(ct_eq<0>{})),
88                 a(f(ct_eq<0>{}))
89             ));
90 
91             BOOST_HANA_CONSTANT_CHECK(hana::equal(
92                 hana::ap(a(f), a(ct_eq<0>{}), a(ct_eq<1>{})),
93                 a(f(ct_eq<0>{}, ct_eq<1>{}))
94             ));
95 
96             BOOST_HANA_CONSTANT_CHECK(hana::equal(
97                 hana::ap(a(f), a(ct_eq<0>{}), a(ct_eq<1>{}), a(ct_eq<2>{})),
98                 a(f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}))
99             ));
100 
101             BOOST_HANA_CONSTANT_CHECK(hana::equal(
102                 hana::ap(a(f), a(ct_eq<0>{}), a(ct_eq<1>{}), a(ct_eq<2>{}), a(ct_eq<3>{})),
103                 a(f(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}, ct_eq<3>{}))
104             ));
105         }
106 
107         // lift
108         {
109             BOOST_HANA_CONSTANT_CHECK(hana::equal(
110                 hana::lift<A>(ct_eq<0>{}),
111                 a(ct_eq<0>{})
112             ));
113         }
114     }
115 
116     // Monad
117     {
118         auto monad = ::identity;
119         using M = ::Identity;
120         auto f = hana::compose(monad, hana::test::_injection<0>{});
121 
122         // chain
123         {
124             BOOST_HANA_CONSTANT_CHECK(hana::equal(
125                 hana::chain(monad(ct_eq<1>{}), f),
126                 f(ct_eq<1>{})
127             ));
128         }
129 
130         // tap
131         {
132             bool executed = false;
133             auto exec = [&](auto) { executed = true; };
134             BOOST_HANA_CONSTANT_CHECK(hana::equal(
135                 hana::chain(monad(ct_eq<0>{}), hana::tap<M>(exec)),
136                 monad(ct_eq<0>{})
137             ));
138             BOOST_HANA_RUNTIME_CHECK(executed);
139         }
140 
141         // then
142         {
143             struct invalid { };
144             BOOST_HANA_CONSTANT_CHECK(hana::equal(
145                 hana::then(monad(invalid{}), monad(ct_eq<0>{})),
146                 monad(ct_eq<0>{})
147             ));
148         }
149     }
150 }
151