]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/test/_include/laws/applicative.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / hana / test / _include / laws / applicative.hpp
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_APPLICATIVE_HPP
6 #define BOOST_HANA_TEST_LAWS_APPLICATIVE_HPP
7
8 #include <boost/hana/ap.hpp>
9 #include <boost/hana/assert.hpp>
10 #include <boost/hana/bool.hpp>
11 #include <boost/hana/concept/applicative.hpp>
12 #include <boost/hana/concept/comparable.hpp>
13 #include <boost/hana/core/make.hpp>
14 #include <boost/hana/core/when.hpp>
15 #include <boost/hana/equal.hpp>
16 #include <boost/hana/for_each.hpp>
17 #include <boost/hana/functional/capture.hpp>
18 #include <boost/hana/functional/compose.hpp>
19 #include <boost/hana/functional/curry.hpp>
20 #include <boost/hana/functional/id.hpp>
21 #include <boost/hana/functional/placeholder.hpp>
22 #include <boost/hana/integral_constant.hpp>
23 #include <boost/hana/lift.hpp>
24 #include <boost/hana/take_front.hpp>
25 #include <boost/hana/transform.hpp>
26
27 #include <laws/base.hpp>
28
29
30 namespace boost { namespace hana { namespace test {
31 template <typename F, typename = when<true>>
32 struct TestApplicative : TestApplicative<F, laws> {
33 using TestApplicative<F, laws>::TestApplicative;
34 };
35
36 template <typename F>
37 struct TestApplicative<F, laws> {
38 template <typename Applicatives>
39 TestApplicative(Applicatives applicatives) {
40 hana::for_each(applicatives, [](auto a) {
41 static_assert(Applicative<decltype(a)>{}, "");
42 });
43
44 auto functions1 = hana::take_front(
45 hana::transform(applicatives, [](auto xs) {
46 return hana::transform(xs, hana::curry<2>(test::_injection<0>{}));
47 }), hana::int_c<3>);
48
49 auto functions2 = hana::take_front(
50 hana::transform(applicatives, [](auto xs) {
51 return hana::transform(xs, hana::curry<2>(test::_injection<1>{}));
52 }), hana::int_c<3>);
53
54 // identity
55 {
56 hana::for_each(applicatives, [](auto xs) {
57 BOOST_HANA_CHECK(hana::equal(
58 hana::ap(hana::lift<F>(hana::id), xs),
59 xs
60 ));
61 });
62 }
63
64 // composition
65 {
66 hana::for_each(applicatives, hana::capture(functions1, functions2)(
67 [](auto functions1, auto functions2, auto xs) {
68 hana::for_each(functions1, hana::capture(functions2, xs)(
69 [](auto functions2, auto xs, auto fs) {
70 hana::for_each(functions2, hana::capture(xs, fs)(
71 [](auto xs, auto fs, auto gs) {
72 BOOST_HANA_CHECK(hana::equal(
73 hana::ap(hana::ap(hana::lift<F>(compose), fs, gs), xs),
74 hana::ap(fs, hana::ap(gs, xs))
75 ));
76 }));}));}));
77 }
78
79 // homomorphism
80 {
81 test::_injection<0> f{};
82 test::ct_eq<3> x{};
83 BOOST_HANA_CONSTANT_CHECK(hana::equal(
84 hana::ap(hana::lift<F>(f), hana::lift<F>(x)),
85 hana::lift<F>(f(x))
86 ));
87 }
88
89 // interchange
90 {
91 hana::for_each(functions1, [](auto fs) {
92 test::ct_eq<4> x{};
93 BOOST_HANA_CHECK(hana::equal(
94 hana::ap(fs, hana::lift<F>(x)),
95 hana::ap(hana::lift<F>(hana::_(x)), fs)
96 ));
97 });
98 }
99
100 // definition of transform
101 {
102 hana::for_each(applicatives, [](auto xs) {
103 test::_injection<0> f{};
104 BOOST_HANA_CHECK(hana::equal(
105 hana::transform(xs, f),
106 hana::ap(hana::lift<F>(f), xs)
107 ));
108 });
109 }
110 }
111 };
112
113 template <typename S>
114 struct TestApplicative<S, when<Sequence<S>::value>>
115 : TestApplicative<S, laws>
116 {
117 template <typename Applicatives>
118 TestApplicative(Applicatives applicatives)
119 : TestApplicative<S, laws>{applicatives}
120 {
121 _injection<0> f{};
122 _injection<1> g{};
123 using test::ct_eq;
124 constexpr auto list = make<S>;
125
126 //////////////////////////////////////////////////////////////////
127 // ap
128 //////////////////////////////////////////////////////////////////
129 BOOST_HANA_CONSTANT_CHECK(hana::equal(
130 hana::ap(list(), list()),
131 list()
132 ));
133 BOOST_HANA_CONSTANT_CHECK(hana::equal(
134 hana::ap(list(), list(ct_eq<0>{})),
135 list()
136 ));
137 BOOST_HANA_CONSTANT_CHECK(hana::equal(
138 hana::ap(list(), list(ct_eq<0>{}, ct_eq<1>{})),
139 list()
140 ));
141 BOOST_HANA_CONSTANT_CHECK(hana::equal(
142 hana::ap(list(), list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
143 list()
144 ));
145
146 BOOST_HANA_CONSTANT_CHECK(hana::equal(
147 hana::ap(list(f), list()),
148 list()
149 ));
150 BOOST_HANA_CONSTANT_CHECK(hana::equal(
151 hana::ap(list(f), list(ct_eq<0>{})),
152 list(f(ct_eq<0>{}))
153 ));
154 BOOST_HANA_CONSTANT_CHECK(hana::equal(
155 hana::ap(list(f), list(ct_eq<0>{}, ct_eq<1>{})),
156 list(f(ct_eq<0>{}), f(ct_eq<1>{}))
157 ));
158 BOOST_HANA_CONSTANT_CHECK(hana::equal(
159 hana::ap(list(f), list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
160 list(f(ct_eq<0>{}), f(ct_eq<1>{}), f(ct_eq<2>{}))
161 ));
162
163 BOOST_HANA_CONSTANT_CHECK(hana::equal(
164 hana::ap(list(f, g), list()),
165 list()
166 ));
167 BOOST_HANA_CONSTANT_CHECK(hana::equal(
168 hana::ap(list(f, g), list(ct_eq<0>{})),
169 list(f(ct_eq<0>{}), g(ct_eq<0>{}))
170 ));
171 BOOST_HANA_CONSTANT_CHECK(hana::equal(
172 hana::ap(list(f, g), list(ct_eq<0>{}, ct_eq<1>{})),
173 list(f(ct_eq<0>{}), f(ct_eq<1>{}), g(ct_eq<0>{}), g(ct_eq<1>{}))
174 ));
175 BOOST_HANA_CONSTANT_CHECK(hana::equal(
176 hana::ap(list(f, g), list(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})),
177 list(f(ct_eq<0>{}), f(ct_eq<1>{}), f(ct_eq<2>{}),
178 g(ct_eq<0>{}), g(ct_eq<1>{}), g(ct_eq<2>{}))
179 ));
180
181 //////////////////////////////////////////////////////////////////
182 // lift
183 //////////////////////////////////////////////////////////////////
184 BOOST_HANA_CONSTANT_CHECK(hana::equal(
185 lift<S>(ct_eq<0>{}),
186 list(ct_eq<0>{})
187 ));
188 BOOST_HANA_CONSTANT_CHECK(hana::equal(
189 lift<S>(ct_eq<1>{}),
190 list(ct_eq<1>{})
191 ));
192 }
193 };
194 }}} // end namespace boost::hana::test
195
196 #endif // !BOOST_HANA_TEST_LAWS_APPLICATIVE_HPP