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/functional/iterate.hpp>
6 
7 #include <boost/hana/assert.hpp>
8 #include <boost/hana/equal.hpp>
9 
10 #include <laws/base.hpp>
11 
12 #include <vector>
13 namespace hana = boost::hana;
14 using hana::test::ct_eq;
15 
16 
17 struct undefined { };
18 
incr(int i)19 constexpr int incr(int i) { return i + 1; }
20 
main()21 int main() {
22     hana::test::_injection<0> f{};
23 
24     // "real usage" tests
25     static_assert(hana::iterate<3>(incr, 0) == 3, "");
26     {
27         std::vector<int> vec;
28         hana::iterate<10>([&](int i) { vec.push_back(i); return i + 1; }, 0);
29         BOOST_HANA_RUNTIME_CHECK(
30             vec == std::vector<int>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
31         );
32     }
33 
34     // equivalence between iterate<n>(f, x) and iterate<n>(f)(x)
35     BOOST_HANA_CONSTANT_CHECK(hana::equal(
36         hana::iterate<0>(undefined{})(ct_eq<0>{}),
37         hana::iterate<0>(undefined{}, ct_eq<0>{})
38     ));
39 
40     BOOST_HANA_CONSTANT_CHECK(hana::equal(
41         hana::iterate<4>(f)(ct_eq<0>{}),
42         hana::iterate<4>(f, ct_eq<0>{})
43     ));
44 
45     BOOST_HANA_CONSTANT_CHECK(hana::equal(
46         hana::iterate<10>(f)(ct_eq<0>{}),
47         hana::iterate<10>(f, ct_eq<0>{})
48     ));
49 
50     // systematic tests
51     BOOST_HANA_CONSTANT_CHECK(hana::equal(
52         hana::iterate<0>(undefined{}, ct_eq<0>{}),
53         ct_eq<0>{}
54     ));
55 
56     BOOST_HANA_CONSTANT_CHECK(hana::equal(
57         hana::iterate<1>(f, ct_eq<0>{}),
58         f(ct_eq<0>{})
59     ));
60 
61     BOOST_HANA_CONSTANT_CHECK(hana::equal(
62         hana::iterate<2>(f, ct_eq<0>{}),
63         f(f(ct_eq<0>{}))
64     ));
65 
66     BOOST_HANA_CONSTANT_CHECK(hana::equal(
67         hana::iterate<3>(f, ct_eq<0>{}),
68         f(f(f(ct_eq<0>{})))
69     ));
70 
71     BOOST_HANA_CONSTANT_CHECK(hana::equal(
72         hana::iterate<4>(f, ct_eq<0>{}),
73         f(f(f(f(ct_eq<0>{}))))
74     ));
75 
76     BOOST_HANA_CONSTANT_CHECK(hana::equal(
77         hana::iterate<5>(f, ct_eq<0>{}),
78         f(f(f(f(f(ct_eq<0>{})))))
79     ));
80 
81     BOOST_HANA_CONSTANT_CHECK(hana::equal(
82         hana::iterate<6>(f, ct_eq<0>{}),
83         f(f(f(f(f(f(ct_eq<0>{}))))))
84     ));
85 
86     BOOST_HANA_CONSTANT_CHECK(hana::equal(
87         hana::iterate<7>(f, ct_eq<0>{}),
88         f(f(f(f(f(f(f(ct_eq<0>{})))))))
89     ));
90 
91     BOOST_HANA_CONSTANT_CHECK(hana::equal(
92         hana::iterate<11>(f, ct_eq<0>{}),
93         f(f(f(f(f(f(f(f(f(f(f(ct_eq<0>{})))))))))))
94     ));
95 
96     BOOST_HANA_CONSTANT_CHECK(hana::equal(
97         hana::iterate<12>(f, ct_eq<0>{}),
98         f(f(f(f(f(f(f(f(f(f(f(f(ct_eq<0>{}))))))))))))
99     ));
100 
101     BOOST_HANA_CONSTANT_CHECK(hana::equal(
102         hana::iterate<13>(f, ct_eq<0>{}),
103         f(f(f(f(f(f(f(f(f(f(f(f(f(ct_eq<0>{})))))))))))))
104     ));
105 
106     // We can't nest too many calls to f, because that uses a hana::tuple
107     // internally and some implementation (libstdc++) have trouble with
108     // deeply-nested calls to `std::is_constructible`, which is required by
109     // hana::tuple. Hence, we use an homogeneous function for the remaining
110     // tests.
111     static_assert(hana::iterate<23>(incr, 0) == 23, "");
112     static_assert(hana::iterate<24>(incr, 0) == 24, "");
113     static_assert(hana::iterate<25>(incr, 0) == 25, "");
114     static_assert(hana::iterate<26>(incr, 0) == 26, "");
115     static_assert(hana::iterate<27>(incr, 0) == 27, "");
116     static_assert(hana::iterate<28>(incr, 0) == 28, "");
117     static_assert(hana::iterate<29>(incr, 0) == 29, "");
118 
119     static_assert(hana::iterate<30>(incr, 0) == 30, "");
120     static_assert(hana::iterate<31>(incr, 0) == 31, "");
121     static_assert(hana::iterate<32>(incr, 0) == 32, "");
122     static_assert(hana::iterate<33>(incr, 0) == 33, "");
123     static_assert(hana::iterate<34>(incr, 0) == 34, "");
124     static_assert(hana::iterate<35>(incr, 0) == 35, "");
125     static_assert(hana::iterate<36>(incr, 0) == 36, "");
126     static_assert(hana::iterate<37>(incr, 0) == 37, "");
127     static_assert(hana::iterate<38>(incr, 0) == 38, "");
128     static_assert(hana::iterate<39>(incr, 0) == 39, "");
129 
130     static_assert(hana::iterate<40>(incr, 0) == 40, "");
131     static_assert(hana::iterate<41>(incr, 0) == 41, "");
132     static_assert(hana::iterate<42>(incr, 0) == 42, "");
133     static_assert(hana::iterate<43>(incr, 0) == 43, "");
134     static_assert(hana::iterate<44>(incr, 0) == 44, "");
135     static_assert(hana::iterate<45>(incr, 0) == 45, "");
136     static_assert(hana::iterate<46>(incr, 0) == 46, "");
137     static_assert(hana::iterate<47>(incr, 0) == 47, "");
138     static_assert(hana::iterate<48>(incr, 0) == 48, "");
139     static_assert(hana::iterate<49>(incr, 0) == 49, "");
140 
141     static_assert(hana::iterate<50>(incr, 0) == 50, "");
142     static_assert(hana::iterate<51>(incr, 0) == 51, "");
143     static_assert(hana::iterate<52>(incr, 0) == 52, "");
144     static_assert(hana::iterate<53>(incr, 0) == 53, "");
145     static_assert(hana::iterate<54>(incr, 0) == 54, "");
146     static_assert(hana::iterate<55>(incr, 0) == 55, "");
147     static_assert(hana::iterate<56>(incr, 0) == 56, "");
148     static_assert(hana::iterate<57>(incr, 0) == 57, "");
149     static_assert(hana::iterate<58>(incr, 0) == 58, "");
150     static_assert(hana::iterate<59>(incr, 0) == 59, "");
151 }
152