1 | // Boost.TypeErasure library |
2 | // |
3 | // Copyright 2011 Steven Watanabe |
4 | // |
5 | // Distributed under the Boost Software License Version 1.0. (See |
6 | // accompanying file LICENSE_1_0.txt or copy at |
7 | // http://www.boost.org/LICENSE_1_0.txt) |
8 | // |
9 | // $Id$ |
10 | |
11 | #include <boost/type_erasure/any.hpp> |
12 | #include <boost/type_erasure/builtin.hpp> |
13 | #include <boost/type_erasure/operators.hpp> |
14 | #include <boost/type_erasure/any_cast.hpp> |
15 | #include <boost/type_erasure/relaxed.hpp> |
16 | #include <boost/mpl/vector.hpp> |
17 | |
18 | #define BOOST_TEST_MAIN |
19 | #include <boost/test/unit_test.hpp> |
20 | |
21 | using namespace boost::type_erasure; |
22 | |
23 | template<class T = _self> |
24 | struct common : ::boost::mpl::vector< |
25 | copy_constructible<T>, |
26 | typeid_<T> |
27 | > {}; |
28 | |
29 | template<class T> |
30 | T as_rvalue(const T& arg) { return arg; } |
31 | template<class T> |
32 | const T& as_const(const T& arg) { return arg; } |
33 | |
34 | BOOST_AUTO_TEST_CASE(test_implicit) { |
35 | int i = 4; |
36 | any<common<>, const _self&> x = i; |
37 | BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i); |
38 | } |
39 | |
40 | BOOST_AUTO_TEST_CASE(test_from_int_with_binding) |
41 | { |
42 | typedef ::boost::mpl::vector<common<> > test_concept; |
43 | int i = 4; |
44 | any<test_concept, const _self&> x(i, make_binding<boost::mpl::map<boost::mpl::pair<_self, int> > >()); |
45 | BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i); |
46 | } |
47 | |
48 | BOOST_AUTO_TEST_CASE(test_copy) |
49 | { |
50 | typedef ::boost::mpl::vector<typeid_<> > test_concept; |
51 | int i = 4; |
52 | any<test_concept, const _self&> x(i); |
53 | BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i); |
54 | any<test_concept, const _self&> y(x); |
55 | BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i); |
56 | any<test_concept, const _self&> z = as_rvalue(arg: x); |
57 | BOOST_CHECK_EQUAL(any_cast<const int*>(&z), &i); |
58 | any<test_concept, const _self&> w = as_const(arg: x); |
59 | BOOST_CHECK_EQUAL(any_cast<const int*>(&w), &i); |
60 | } |
61 | |
62 | BOOST_AUTO_TEST_CASE(test_convert) |
63 | { |
64 | typedef ::boost::mpl::vector<common<>, typeid_<> > src_concept; |
65 | typedef ::boost::mpl::vector<typeid_<> > dst_concept; |
66 | int i = 4; |
67 | any<src_concept, const _self&> x(i); |
68 | BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i); |
69 | any<dst_concept, const _self&> y(x); |
70 | BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i); |
71 | any<dst_concept, const _self&> z = as_rvalue(arg: x); |
72 | BOOST_CHECK_EQUAL(any_cast<const int*>(&z), &i); |
73 | any<dst_concept, const _self&> w = as_const(arg: x); |
74 | BOOST_CHECK_EQUAL(any_cast<const int*>(&w), &i); |
75 | } |
76 | |
77 | BOOST_AUTO_TEST_CASE(test_rebind) |
78 | { |
79 | typedef ::boost::mpl::vector<typeid_<> > src_concept; |
80 | typedef ::boost::mpl::vector<typeid_<_a> > dst_concept; |
81 | int i = 4; |
82 | any<src_concept, const _self&> x(i); |
83 | BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i); |
84 | any<dst_concept, const _a&> y(x); |
85 | BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i); |
86 | any<dst_concept, const _a&> z = as_rvalue(arg: x); |
87 | BOOST_CHECK_EQUAL(any_cast<const int*>(&z), &i); |
88 | any<dst_concept, const _a&> w = as_const(arg: x); |
89 | BOOST_CHECK_EQUAL(any_cast<const int*>(&w), &i); |
90 | } |
91 | |
92 | BOOST_AUTO_TEST_CASE(test_rebind_and_convert) |
93 | { |
94 | typedef ::boost::mpl::vector<common<>, typeid_<> > src_concept; |
95 | typedef ::boost::mpl::vector<typeid_<_a> > dst_concept; |
96 | int i = 4; |
97 | any<src_concept, const _self&> x(i); |
98 | BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i); |
99 | any<dst_concept, const _a&> y(x); |
100 | BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i); |
101 | any<dst_concept, const _a&> z = as_rvalue(arg: x); |
102 | BOOST_CHECK_EQUAL(any_cast<const int*>(&z), &i); |
103 | any<dst_concept, const _a&> w = as_const(arg: x); |
104 | BOOST_CHECK_EQUAL(any_cast<const int*>(&w), &i); |
105 | } |
106 | |
107 | BOOST_AUTO_TEST_CASE(test_rebind_and_convert_with_binding) |
108 | { |
109 | typedef ::boost::mpl::vector<common<>, incrementable<> > src_concept; |
110 | typedef ::boost::mpl::vector<common<_a> > dst_concept; |
111 | typedef ::boost::mpl::map<boost::mpl::pair<_a, _self> > map; |
112 | typedef ::boost::mpl::map<boost::mpl::pair<_a, int> > types; |
113 | |
114 | binding<dst_concept> table(make_binding<types>()); |
115 | |
116 | int i = 4; |
117 | any<src_concept, const _self&> x(i); |
118 | BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i); |
119 | any<dst_concept, const _a&> y(x, make_binding<map>()); |
120 | BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i); |
121 | any<dst_concept, const _a&> z(x, table); |
122 | BOOST_CHECK_EQUAL(any_cast<const int*>(&z), &i); |
123 | |
124 | any<dst_concept, const _a&> cy(as_const(arg: x), make_binding<map>()); |
125 | BOOST_CHECK_EQUAL(any_cast<const int*>(&cy), &i); |
126 | any<dst_concept, const _a&> cz(as_const(arg: x), table); |
127 | BOOST_CHECK_EQUAL(any_cast<const int*>(&cz), &i); |
128 | } |
129 | |
130 | BOOST_AUTO_TEST_CASE(test_copy_from_ref) |
131 | { |
132 | typedef ::boost::mpl::vector<typeid_<> > test_concept; |
133 | int i = 4; |
134 | any<test_concept, _self&> x(i); |
135 | BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i); |
136 | any<test_concept, const _self&> y(x); |
137 | BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i); |
138 | any<test_concept, const _self&> z = as_rvalue(arg: x); |
139 | BOOST_CHECK_EQUAL(any_cast<const int*>(&z), &i); |
140 | any<test_concept, const _self&> w = as_const(arg: x); |
141 | BOOST_CHECK_EQUAL(any_cast<const int*>(&w), &i); |
142 | } |
143 | |
144 | BOOST_AUTO_TEST_CASE(test_convert_from_ref) |
145 | { |
146 | typedef ::boost::mpl::vector<common<>, typeid_<> > src_concept; |
147 | typedef ::boost::mpl::vector<typeid_<> > dst_concept; |
148 | int i = 4; |
149 | any<src_concept, _self&> x(i); |
150 | BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i); |
151 | any<dst_concept, const _self&> y(x); |
152 | BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i); |
153 | any<dst_concept, const _self&> z = as_rvalue(arg: x); |
154 | BOOST_CHECK_EQUAL(any_cast<const int*>(&z), &i); |
155 | any<dst_concept, const _self&> w = as_const(arg: x); |
156 | BOOST_CHECK_EQUAL(any_cast<const int*>(&w), &i); |
157 | } |
158 | |
159 | BOOST_AUTO_TEST_CASE(test_rebind_from_ref) |
160 | { |
161 | typedef ::boost::mpl::vector<typeid_<> > src_concept; |
162 | typedef ::boost::mpl::vector<typeid_<_a> > dst_concept; |
163 | int i = 4; |
164 | any<src_concept, _self&> x(i); |
165 | BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i); |
166 | any<dst_concept, const _a&> y(x); |
167 | BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i); |
168 | any<dst_concept, const _a&> z = as_rvalue(arg: x); |
169 | BOOST_CHECK_EQUAL(any_cast<const int*>(&z), &i); |
170 | any<dst_concept, const _a&> w = as_const(arg: x); |
171 | BOOST_CHECK_EQUAL(any_cast<const int*>(&w), &i); |
172 | } |
173 | |
174 | BOOST_AUTO_TEST_CASE(test_rebind_and_convert_from_ref) |
175 | { |
176 | typedef ::boost::mpl::vector<common<>, typeid_<> > src_concept; |
177 | typedef ::boost::mpl::vector<typeid_<_a> > dst_concept; |
178 | int i = 4; |
179 | any<src_concept, _self&> x(i); |
180 | BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i); |
181 | any<dst_concept, const _a&> y(x); |
182 | BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i); |
183 | any<dst_concept, const _a&> z = as_rvalue(arg: x); |
184 | BOOST_CHECK_EQUAL(any_cast<const int*>(&z), &i); |
185 | any<dst_concept, const _a&> w = as_const(arg: x); |
186 | BOOST_CHECK_EQUAL(any_cast<const int*>(&w), &i); |
187 | } |
188 | |
189 | BOOST_AUTO_TEST_CASE(test_rebind_and_convert_with_binding_from_ref) |
190 | { |
191 | typedef ::boost::mpl::vector<common<>, incrementable<> > src_concept; |
192 | typedef ::boost::mpl::vector<common<_a> > dst_concept; |
193 | typedef ::boost::mpl::map<boost::mpl::pair<_a, _self> > map; |
194 | typedef ::boost::mpl::map<boost::mpl::pair<_a, int> > types; |
195 | |
196 | binding<dst_concept> table(make_binding<types>()); |
197 | |
198 | int i = 4; |
199 | any<src_concept, _self&> x(i); |
200 | BOOST_CHECK_EQUAL(any_cast<const int*>(&x), &i); |
201 | any<dst_concept, const _a&> y(x, make_binding<map>()); |
202 | BOOST_CHECK_EQUAL(any_cast<const int*>(&y), &i); |
203 | any<dst_concept, const _a&> z(x, table); |
204 | BOOST_CHECK_EQUAL(any_cast<const int*>(&z), &i); |
205 | |
206 | any<dst_concept, const _a&> cy(as_const(arg: x), make_binding<map>()); |
207 | BOOST_CHECK_EQUAL(any_cast<const int*>(&cy), &i); |
208 | any<dst_concept, const _a&> cz(as_const(arg: x), table); |
209 | BOOST_CHECK_EQUAL(any_cast<const int*>(&cz), &i); |
210 | } |
211 | |
212 | BOOST_AUTO_TEST_CASE(test_copy_from_value) |
213 | { |
214 | typedef ::boost::mpl::vector<copy_constructible<>, typeid_<> > test_concept; |
215 | any<test_concept> x(4); |
216 | const int* ip = any_cast<const int*>(arg: &x); |
217 | any<test_concept, const _self&> y(x); |
218 | BOOST_CHECK_EQUAL(any_cast<const int*>(&y), ip); |
219 | BOOST_CHECK_EQUAL(any_cast<int>(any<test_concept, const _self&>(as_rvalue(x))), 4); |
220 | any<test_concept, const _self&> w = as_const(arg: x); |
221 | BOOST_CHECK_EQUAL(any_cast<const int*>(&w), ip); |
222 | } |
223 | |
224 | BOOST_AUTO_TEST_CASE(test_convert_from_value) |
225 | { |
226 | typedef ::boost::mpl::vector<common<>, typeid_<> > src_concept; |
227 | typedef ::boost::mpl::vector<typeid_<> > dst_concept; |
228 | any<src_concept> x(4); |
229 | const int* ip = any_cast<const int*>(arg: &x); |
230 | any<dst_concept, const _self&> y(x); |
231 | BOOST_CHECK_EQUAL(any_cast<const int*>(&y), ip); |
232 | BOOST_CHECK_EQUAL(any_cast<int>(any<dst_concept, const _self&>(as_rvalue(x))), 4); |
233 | any<dst_concept, const _self&> w = as_const(arg: x); |
234 | BOOST_CHECK_EQUAL(any_cast<const int*>(&w), ip); |
235 | } |
236 | |
237 | BOOST_AUTO_TEST_CASE(test_rebind_from_value) |
238 | { |
239 | typedef ::boost::mpl::vector<copy_constructible<>, typeid_<> > src_concept; |
240 | typedef ::boost::mpl::vector<copy_constructible<_a>, typeid_<_a> > dst_concept; |
241 | any<src_concept> x(4); |
242 | const int* ip = any_cast<const int*>(arg: &x); |
243 | any<dst_concept, const _a&> y(x); |
244 | BOOST_CHECK_EQUAL(any_cast<const int*>(&y), ip); |
245 | BOOST_CHECK_EQUAL(any_cast<int>(any<dst_concept, const _a&>(as_rvalue(x))), 4); |
246 | any<dst_concept, const _a&> w = as_const(arg: x); |
247 | BOOST_CHECK_EQUAL(any_cast<const int*>(&w), ip); |
248 | } |
249 | |
250 | BOOST_AUTO_TEST_CASE(test_rebind_and_convert_from_value) |
251 | { |
252 | typedef ::boost::mpl::vector<common<>, typeid_<> > src_concept; |
253 | typedef ::boost::mpl::vector<typeid_<_a> > dst_concept; |
254 | any<src_concept> x(4); |
255 | const int* ip = any_cast<const int*>(arg: &x); |
256 | any<dst_concept, const _a&> y(x); |
257 | BOOST_CHECK_EQUAL(any_cast<const int*>(&y), ip); |
258 | BOOST_CHECK_EQUAL(any_cast<int>(any<dst_concept, const _a&>(as_rvalue(x))), 4); |
259 | any<dst_concept, const _a&> w = as_const(arg: x); |
260 | BOOST_CHECK_EQUAL(any_cast<const int*>(&w), ip); |
261 | } |
262 | |
263 | BOOST_AUTO_TEST_CASE(test_rebind_and_convert_with_binding_from_value) |
264 | { |
265 | typedef ::boost::mpl::vector<common<>, incrementable<> > src_concept; |
266 | typedef ::boost::mpl::vector<common<_a> > dst_concept; |
267 | typedef ::boost::mpl::map<boost::mpl::pair<_a, _self> > map; |
268 | typedef ::boost::mpl::map<boost::mpl::pair<_a, int> > types; |
269 | |
270 | binding<dst_concept> table(make_binding<types>()); |
271 | |
272 | any<src_concept> x(4); |
273 | const int* ip = any_cast<const int*>(arg: &x); |
274 | any<dst_concept, const _a&> y(x, make_binding<map>()); |
275 | BOOST_CHECK_EQUAL(any_cast<const int*>(&y), ip); |
276 | any<dst_concept, const _a&> z(x, table); |
277 | BOOST_CHECK_EQUAL(any_cast<const int*>(&z), ip); |
278 | |
279 | any<dst_concept, const _a&> cy(as_const(arg: x), make_binding<map>()); |
280 | BOOST_CHECK_EQUAL(any_cast<const int*>(&cy), ip); |
281 | any<dst_concept, const _a&> cz(as_const(arg: x), table); |
282 | BOOST_CHECK_EQUAL(any_cast<const int*>(&cz), ip); |
283 | } |
284 | |