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<>, _self&> x = i; |
37 | BOOST_CHECK_EQUAL(any_cast<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, _self&> x(i, make_binding<boost::mpl::map<boost::mpl::pair<_self, int> > >()); |
45 | BOOST_CHECK_EQUAL(any_cast<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, _self&> x(i); |
53 | BOOST_CHECK_EQUAL(any_cast<int*>(&x), &i); |
54 | any<test_concept, _self&> y(x); |
55 | BOOST_CHECK_EQUAL(any_cast<int*>(&y), &i); |
56 | any<test_concept, _self&> z = as_rvalue(arg: x); |
57 | BOOST_CHECK_EQUAL(any_cast<int*>(&z), &i); |
58 | any<test_concept, _self&> w = as_const(arg: x); |
59 | BOOST_CHECK_EQUAL(any_cast<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, _self&> x(i); |
68 | BOOST_CHECK_EQUAL(any_cast<int*>(&x), &i); |
69 | any<dst_concept, _self&> y(x); |
70 | BOOST_CHECK_EQUAL(any_cast<int*>(&y), &i); |
71 | any<dst_concept, _self&> z = as_rvalue(arg: x); |
72 | BOOST_CHECK_EQUAL(any_cast<int*>(&z), &i); |
73 | any<dst_concept, _self&> w = as_const(arg: x); |
74 | BOOST_CHECK_EQUAL(any_cast<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, _self&> x(i); |
83 | BOOST_CHECK_EQUAL(any_cast<int*>(&x), &i); |
84 | any<dst_concept, _a&> y(x); |
85 | BOOST_CHECK_EQUAL(any_cast<int*>(&y), &i); |
86 | any<dst_concept, _a&> z = as_rvalue(arg: x); |
87 | BOOST_CHECK_EQUAL(any_cast<int*>(&z), &i); |
88 | any<dst_concept, _a&> w = as_const(arg: x); |
89 | BOOST_CHECK_EQUAL(any_cast<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, _self&> x(i); |
98 | BOOST_CHECK_EQUAL(any_cast<int*>(&x), &i); |
99 | any<dst_concept, _a&> y(x); |
100 | BOOST_CHECK_EQUAL(any_cast<int*>(&y), &i); |
101 | any<dst_concept, _a&> z = as_rvalue(arg: x); |
102 | BOOST_CHECK_EQUAL(any_cast<int*>(&z), &i); |
103 | any<dst_concept, _a&> w = as_const(arg: x); |
104 | BOOST_CHECK_EQUAL(any_cast<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, _self&> x(i); |
118 | BOOST_CHECK_EQUAL(any_cast<int*>(&x), &i); |
119 | any<dst_concept, _a&> y(x, make_binding<map>()); |
120 | BOOST_CHECK_EQUAL(any_cast<int*>(&y), &i); |
121 | any<dst_concept, _a&> z(x, table); |
122 | BOOST_CHECK_EQUAL(any_cast<int*>(&z), &i); |
123 | |
124 | any<dst_concept, _a&> cy(as_const(arg: x), make_binding<map>()); |
125 | BOOST_CHECK_EQUAL(any_cast<int*>(&cy), &i); |
126 | any<dst_concept, _a&> cz(as_const(arg: x), table); |
127 | BOOST_CHECK_EQUAL(any_cast<int*>(&cz), &i); |
128 | } |
129 | |
130 | BOOST_AUTO_TEST_CASE(test_copy_from_value) |
131 | { |
132 | typedef ::boost::mpl::vector<destructible<>, typeid_<> > test_concept; |
133 | any<test_concept> x(4); |
134 | int* ip = any_cast<int*>(arg: &x); |
135 | any<test_concept, _self&> y(x); |
136 | BOOST_CHECK_EQUAL(any_cast<int*>(&y), ip); |
137 | } |
138 | |
139 | BOOST_AUTO_TEST_CASE(test_convert_from_value) |
140 | { |
141 | typedef ::boost::mpl::vector<common<>, typeid_<> > src_concept; |
142 | typedef ::boost::mpl::vector<typeid_<> > dst_concept; |
143 | any<src_concept> x(4); |
144 | int* ip = any_cast<int*>(arg: &x); |
145 | any<dst_concept, _self&> y(x); |
146 | BOOST_CHECK_EQUAL(any_cast<int*>(&y), ip); |
147 | } |
148 | |
149 | BOOST_AUTO_TEST_CASE(test_rebind_from_value) |
150 | { |
151 | typedef ::boost::mpl::vector<destructible<>, typeid_<> > src_concept; |
152 | typedef ::boost::mpl::vector<destructible<_a>, typeid_<_a> > dst_concept; |
153 | any<src_concept> x(4); |
154 | int* ip = any_cast<int*>(arg: &x); |
155 | any<dst_concept, _a&> y(x); |
156 | BOOST_CHECK_EQUAL(any_cast<int*>(&y), ip); |
157 | } |
158 | |
159 | BOOST_AUTO_TEST_CASE(test_rebind_and_convert_from_value) |
160 | { |
161 | typedef ::boost::mpl::vector<common<>, typeid_<> > src_concept; |
162 | typedef ::boost::mpl::vector<typeid_<_a> > dst_concept; |
163 | any<src_concept> x(4); |
164 | int* ip = any_cast<int*>(arg: &x); |
165 | any<dst_concept, _a&> y(x); |
166 | BOOST_CHECK_EQUAL(any_cast<int*>(&y), ip); |
167 | } |
168 | |
169 | BOOST_AUTO_TEST_CASE(test_rebind_and_convert_with_binding_from_value) |
170 | { |
171 | typedef ::boost::mpl::vector<common<>, incrementable<> > src_concept; |
172 | typedef ::boost::mpl::vector<common<_a> > dst_concept; |
173 | typedef ::boost::mpl::map<boost::mpl::pair<_a, _self> > map; |
174 | typedef ::boost::mpl::map<boost::mpl::pair<_a, int> > types; |
175 | |
176 | binding<dst_concept> table(make_binding<types>()); |
177 | |
178 | any<src_concept> x(4); |
179 | int* ip = any_cast<int*>(arg: &x); |
180 | any<dst_concept, _a&> y(x, make_binding<map>()); |
181 | BOOST_CHECK_EQUAL(any_cast<int*>(&y), ip); |
182 | any<dst_concept, _a&> z(x, table); |
183 | BOOST_CHECK_EQUAL(any_cast<int*>(&z), ip); |
184 | } |
185 | |