Imported Upstream version 1.64.0
[platform/upstream/boost.git] / libs / hana / test / _include / auto / unfolds.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_AUTO_UNFOLDS_HPP
6 #define BOOST_HANA_TEST_AUTO_UNFOLDS_HPP
7
8 #include <boost/hana/assert.hpp>
9 #include <boost/hana/equal.hpp>
10 #include <boost/hana/fold_left.hpp>
11 #include <boost/hana/fold_right.hpp>
12 #include <boost/hana/if.hpp>
13 #include <boost/hana/integral_constant.hpp>
14 #include <boost/hana/optional.hpp>
15 #include <boost/hana/plus.hpp>
16 #include <boost/hana/unfold_left.hpp>
17 #include <boost/hana/unfold_right.hpp>
18
19 #include <laws/base.hpp>
20 #include <support/minimal_product.hpp>
21 #include "test_case.hpp"
22
23
24 TestCase test_unfold_left{[]{
25     namespace hana = boost::hana;
26
27     hana::test::_injection<0> f{};
28     auto stop_at = [=](auto stop) {
29         return [=](auto x) {
30             return hana::if_(hana::equal(stop, x),
31                 hana::nothing,
32                 hana::just(::minimal_product(x + hana::int_c<1>, f(x)))
33             );
34         };
35     };
36
37     BOOST_HANA_CONSTANT_CHECK(hana::equal(
38         hana::unfold_left<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<0>)),
39         MAKE_TUPLE()
40     ));
41     BOOST_HANA_CONSTANT_CHECK(hana::equal(
42         hana::unfold_left<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<1>)),
43         MAKE_TUPLE(f(hana::int_c<0>))
44     ));
45     BOOST_HANA_CONSTANT_CHECK(hana::equal(
46         hana::unfold_left<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<2>)),
47         MAKE_TUPLE(f(hana::int_c<1>), f(hana::int_c<0>))
48     ));
49     BOOST_HANA_CONSTANT_CHECK(hana::equal(
50         hana::unfold_left<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<3>)),
51         MAKE_TUPLE(f(hana::int_c<2>), f(hana::int_c<1>), f(hana::int_c<0>))
52     ));
53     BOOST_HANA_CONSTANT_CHECK(hana::equal(
54         hana::unfold_left<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<4>)),
55         MAKE_TUPLE(f(hana::int_c<3>), f(hana::int_c<2>), f(hana::int_c<1>), f(hana::int_c<0>))
56     ));
57 }};
58
59
60 TestCase test_unfold_right{[]{
61     namespace hana = boost::hana;
62
63     hana::test::_injection<0> f{};
64     auto stop_at = [=](auto stop) {
65         return [=](auto x) {
66             return hana::if_(hana::equal(stop, x),
67                 hana::nothing,
68                 hana::just(::minimal_product(f(x), x + hana::int_c<1>))
69             );
70         };
71     };
72
73     BOOST_HANA_CONSTANT_CHECK(hana::equal(
74         hana::unfold_right<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<0>)),
75         MAKE_TUPLE()
76     ));
77     BOOST_HANA_CONSTANT_CHECK(hana::equal(
78         hana::unfold_right<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<1>)),
79         MAKE_TUPLE(f(hana::int_c<0>))
80     ));
81     BOOST_HANA_CONSTANT_CHECK(hana::equal(
82         hana::unfold_right<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<2>)),
83         MAKE_TUPLE(f(hana::int_c<0>), f(hana::int_c<1>))
84     ));
85     BOOST_HANA_CONSTANT_CHECK(hana::equal(
86         hana::unfold_right<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<3>)),
87         MAKE_TUPLE(f(hana::int_c<0>), f(hana::int_c<1>), f(hana::int_c<2>))
88     ));
89     BOOST_HANA_CONSTANT_CHECK(hana::equal(
90         hana::unfold_right<TUPLE_TAG>(hana::int_c<0>, stop_at(hana::int_c<4>)),
91         MAKE_TUPLE(f(hana::int_c<0>), f(hana::int_c<1>), f(hana::int_c<2>), f(hana::int_c<3>))
92     ));
93 }};
94
95 // Make sure unfolds can be reversed under certain conditions.
96 TestCase test_unfold_undo{[]{
97     namespace hana = boost::hana;
98     using hana::test::ct_eq;
99
100     auto z = ct_eq<999>{};
101     auto f = ::minimal_product;
102     auto g = [=](auto k) {
103         return hana::if_(hana::equal(k, z),
104             hana::nothing,
105             hana::just(k)
106         );
107     };
108
109     // Make sure the special conditions are met
110     BOOST_HANA_CONSTANT_CHECK(hana::equal(
111         g(z),
112         hana::nothing
113     ));
114     BOOST_HANA_CONSTANT_CHECK(hana::equal(
115         g(f(ct_eq<0>{}, z)),
116         hana::just(::minimal_product(ct_eq<0>{}, z))
117     ));
118     BOOST_HANA_CONSTANT_CHECK(hana::equal(
119         g(f(z, ct_eq<0>{})),
120         hana::just(::minimal_product(z, ct_eq<0>{}))
121     ));
122
123     // Make sure the reversing works
124     {
125         auto xs = MAKE_TUPLE();
126         BOOST_HANA_CONSTANT_CHECK(hana::equal(
127             hana::unfold_left<TUPLE_TAG>(hana::fold_left(xs, z, f), g),
128             xs
129         ));
130         BOOST_HANA_CONSTANT_CHECK(hana::equal(
131             hana::unfold_right<TUPLE_TAG>(hana::fold_right(xs, z, f), g),
132             xs
133         ));
134     }
135     {
136         auto xs = MAKE_TUPLE(ct_eq<0>{});
137         BOOST_HANA_CONSTANT_CHECK(hana::equal(
138             hana::unfold_left<TUPLE_TAG>(hana::fold_left(xs, z, f), g),
139             xs
140         ));
141         BOOST_HANA_CONSTANT_CHECK(hana::equal(
142             hana::unfold_right<TUPLE_TAG>(hana::fold_right(xs, z, f), g),
143             xs
144         ));
145     }
146     {
147         auto xs = MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{});
148         BOOST_HANA_CONSTANT_CHECK(hana::equal(
149             hana::unfold_left<TUPLE_TAG>(hana::fold_left(xs, z, f), g),
150             xs
151         ));
152         BOOST_HANA_CONSTANT_CHECK(hana::equal(
153             hana::unfold_right<TUPLE_TAG>(hana::fold_right(xs, z, f), g),
154             xs
155         ));
156     }
157     {
158         auto xs = MAKE_TUPLE(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{});
159         BOOST_HANA_CONSTANT_CHECK(hana::equal(
160             hana::unfold_left<TUPLE_TAG>(hana::fold_left(xs, z, f), g),
161             xs
162         ));
163         BOOST_HANA_CONSTANT_CHECK(hana::equal(
164             hana::unfold_right<TUPLE_TAG>(hana::fold_right(xs, z, f), g),
165             xs
166         ));
167     }
168 }};
169
170 #endif // !BOOST_HANA_TEST_AUTO_UNFOLDS_HPP