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/assert.hpp>
6 #include <boost/hana/at_key.hpp>
7 #include <boost/hana/equal.hpp>
8 #include <boost/hana/map.hpp>
9 #include <boost/hana/pair.hpp>
10
11 #include <laws/base.hpp>
12 #include <support/constexpr_move_only.hpp>
13 #include <support/minimal_product.hpp>
14 #include <support/tracked_move_only.hpp>
15
16 #include <string>
17 #include <vector>
18 namespace hana = boost::hana;
19
20
21 template <int i>
22 using pair = ::product_t<hana::test::ct_eq<i>, hana::test::ct_eq<-i>>;
23
24 // Check with move-only literal types.
in_constexpr_context()25 constexpr bool in_constexpr_context() {
26 hana::map<hana::pair<ConstexprMoveOnly<2>, ConstexprMoveOnly<20>>,
27 hana::pair<ConstexprMoveOnly<3>, ConstexprMoveOnly<30>>> map{
28 hana::make_pair(ConstexprMoveOnly<2>{}, ConstexprMoveOnly<20>{}),
29 hana::make_pair(ConstexprMoveOnly<3>{}, ConstexprMoveOnly<30>{})
30 };
31 (void)map;
32 return true;
33 }
34
35 static_assert(in_constexpr_context(), "");
36
main()37 int main() {
38 // Basic check with non trivial runtime state
39 {
40 std::vector<std::string> v{"Hello", "world", "!"};
41
42 hana::map<
43 hana::pair<hana::test::ct_eq<1>, std::string>,
44 hana::pair<hana::test::ct_eq<2>, std::vector<std::string>>
45 > map{
46 hana::make_pair(hana::test::ct_eq<1>{}, std::string{"Hello world!"}),
47 hana::make_pair(hana::test::ct_eq<2>{}, v)
48 };
49
50 BOOST_HANA_RUNTIME_CHECK(
51 hana::at_key(map, hana::test::ct_eq<1>{}) == std::string{"Hello world!"}
52 );
53
54 BOOST_HANA_RUNTIME_CHECK(
55 hana::at_key(map, hana::test::ct_eq<2>{}) == v
56 );
57 }
58
59 {
60 hana::map<> map{};
61 BOOST_HANA_CONSTANT_CHECK(hana::equal(
62 map,
63 hana::make_map()
64 ));
65 }
66
67 {
68 hana::map<pair<0>> map{pair<0>{}};
69 BOOST_HANA_CONSTANT_CHECK(hana::equal(
70 map,
71 hana::make_map(pair<0>{})
72 ));
73 }
74
75 {
76 hana::map<pair<0>, pair<1>> map{pair<0>{}, pair<1>{}};
77 BOOST_HANA_CONSTANT_CHECK(hana::equal(
78 map,
79 hana::make_map(pair<0>{}, pair<1>{})
80 ));
81 }
82
83 {
84 hana::map<pair<0>, pair<1>, pair<2>> map{pair<0>{}, pair<1>{}, pair<2>{}};
85 BOOST_HANA_CONSTANT_CHECK(hana::equal(
86 map,
87 hana::make_map(pair<0>{}, pair<1>{}, pair<2>{})
88 ));
89 }
90
91 {
92 hana::map<pair<0>, pair<1>, pair<2>, pair<3>> map{
93 pair<0>{}, pair<1>{}, pair<2>{}, pair<3>{}
94 };
95 BOOST_HANA_CONSTANT_CHECK(hana::equal(
96 map,
97 hana::make_map(pair<0>{}, pair<1>{}, pair<2>{}, pair<3>{})
98 ));
99 }
100
101 {
102 hana::map<pair<0>, pair<1>, pair<2>, pair<3>, pair<4>> map{
103 pair<0>{}, pair<1>{}, pair<2>{}, pair<3>{}, pair<4>{}
104 };
105 BOOST_HANA_CONSTANT_CHECK(hana::equal(
106 map,
107 hana::make_map(pair<0>{}, pair<1>{}, pair<2>{}, pair<3>{}, pair<4>{})
108 ));
109 }
110
111 {
112 hana::map<pair<0>, pair<1>, pair<2>, pair<3>, pair<4>, pair<5>> map{
113 pair<0>{}, pair<1>{}, pair<2>{}, pair<3>{}, pair<4>{}, pair<5>{}
114 };
115 BOOST_HANA_CONSTANT_CHECK(hana::equal(
116 map,
117 hana::make_map(pair<0>{}, pair<1>{}, pair<2>{}, pair<3>{}, pair<4>{}, pair<5>{})
118 ));
119 }
120
121 // Use parenthesis syntax instead of braces
122 {
123 hana::map<> map = hana::map<>();
124 BOOST_HANA_CONSTANT_CHECK(hana::equal(
125 map,
126 hana::make_map()
127 ));
128 }
129
130 {
131 hana::map<pair<0>> map(
132 pair<0>{}
133 );
134 BOOST_HANA_CONSTANT_CHECK(hana::equal(
135 map,
136 hana::make_map(pair<0>{})
137 ));
138 }
139
140 {
141 hana::map<pair<0>, pair<1>> map(
142 pair<0>{}, pair<1>{}
143 );
144 BOOST_HANA_CONSTANT_CHECK(hana::equal(
145 map,
146 hana::make_map(pair<0>{}, pair<1>{})
147 ));
148 }
149
150 {
151 hana::map<pair<0>, pair<1>, pair<2>> map(
152 pair<0>{}, pair<1>{}, pair<2>{}
153 );
154 BOOST_HANA_CONSTANT_CHECK(hana::equal(
155 map,
156 hana::make_map(pair<0>{}, pair<1>{}, pair<2>{})
157 ));
158 }
159
160 {
161 hana::map<pair<0>, pair<1>, pair<2>, pair<3>> map(
162 pair<0>{}, pair<1>{}, pair<2>{}, pair<3>{}
163 );
164 BOOST_HANA_CONSTANT_CHECK(hana::equal(
165 map,
166 hana::make_map(pair<0>{}, pair<1>{}, pair<2>{}, pair<3>{})
167 ));
168 }
169
170 // Check with move-only types
171 {
172 hana::map<hana::pair<TrackedMoveOnly<1>, TrackedMoveOnly<10>>,
173 hana::pair<TrackedMoveOnly<2>, TrackedMoveOnly<20>>> map{
174 hana::make_pair(TrackedMoveOnly<1>{}, TrackedMoveOnly<10>{}),
175 hana::make_pair(TrackedMoveOnly<2>{}, TrackedMoveOnly<20>{})
176 };
177 }
178
179 // The following used to fail when we did not constrain the
180 // constructor properly:
181 {
182 hana::map<pair<1>> map{};
183 hana::test::_injection<0> f{};
184 auto x = f(map);
185 }
186 }
187