1 | /*============================================================================= |
2 | Copyright (c) 2001-2009 Joel de Guzman |
3 | |
4 | Distributed under the Boost Software License, Version 1.0. (See accompanying |
5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6 | ==============================================================================*/ |
7 | #include <boost/detail/lightweight_test.hpp> |
8 | #include <boost/fusion/adapted/adt/adapt_adt.hpp> |
9 | #include <boost/fusion/sequence/intrinsic/at.hpp> |
10 | #include <boost/fusion/sequence/intrinsic/size.hpp> |
11 | #include <boost/fusion/sequence/intrinsic/empty.hpp> |
12 | #include <boost/fusion/sequence/intrinsic/front.hpp> |
13 | #include <boost/fusion/sequence/intrinsic/back.hpp> |
14 | #include <boost/fusion/sequence/intrinsic/value_at.hpp> |
15 | #include <boost/fusion/sequence/io/out.hpp> |
16 | #include <boost/fusion/container/vector/vector.hpp> |
17 | #include <boost/fusion/container/list/list.hpp> |
18 | #include <boost/fusion/container/generation/make_vector.hpp> |
19 | #include <boost/fusion/container/vector/convert.hpp> |
20 | #include <boost/fusion/sequence/comparison/equal_to.hpp> |
21 | #include <boost/fusion/sequence/comparison/not_equal_to.hpp> |
22 | #include <boost/fusion/sequence/comparison/less.hpp> |
23 | #include <boost/fusion/sequence/comparison/less_equal.hpp> |
24 | #include <boost/fusion/sequence/comparison/greater.hpp> |
25 | #include <boost/fusion/sequence/comparison/greater_equal.hpp> |
26 | #include <boost/fusion/mpl.hpp> |
27 | #include <boost/fusion/support/is_view.hpp> |
28 | #include <boost/mpl/front.hpp> |
29 | #include <boost/mpl/is_sequence.hpp> |
30 | #include <boost/mpl/assert.hpp> |
31 | #include <boost/type_traits/is_same.hpp> |
32 | #include <iostream> |
33 | #include <string> |
34 | |
35 | namespace ns |
36 | { |
37 | class point |
38 | { |
39 | public: |
40 | |
41 | point() : x(0), y(0), z(0) {} |
42 | point(int in_x, int in_y, int in_z) : x(in_x), y(in_y), z(in_z) {} |
43 | |
44 | int get_x() const { return x; } |
45 | int get_y() const { return y; } |
46 | int get_z() const { return z; } |
47 | void set_x(int x_) { x = x_; } |
48 | void set_y(int y_) { y = y_; } |
49 | void set_z(int z_) { z = z_; } |
50 | |
51 | private: |
52 | |
53 | int x; |
54 | int y; |
55 | int z; |
56 | }; |
57 | |
58 | #if !BOOST_WORKAROUND(__GNUC__,<4) |
59 | class point_with_private_members |
60 | { |
61 | friend struct boost::fusion::extension::access; |
62 | |
63 | public: |
64 | point_with_private_members() : x(0), y(0), z(0) {} |
65 | point_with_private_members(int in_x, int in_y, int in_z) |
66 | : x(in_x), y(in_y), z(in_z) {} |
67 | |
68 | int get_x() const { return x; } |
69 | int get_y() const { return y; } |
70 | int get_z() const { return z; } |
71 | void set_x(int x_) { x = x_; } |
72 | void set_y(int y_) { y = y_; } |
73 | void set_z(int z_) { z = z_; } |
74 | |
75 | private: |
76 | |
77 | int x; |
78 | int y; |
79 | int z; |
80 | }; |
81 | #endif |
82 | |
83 | // A sequence that has data members defined in an unrelated namespace |
84 | // (std, in this case). This allows testing ADL issues. |
85 | class name |
86 | { |
87 | public: |
88 | name() {} |
89 | name(const std::string& last, const std::string& first) |
90 | : last(last), first(first) {} |
91 | |
92 | const std::string& get_last() const { return last; } |
93 | const std::string& get_first() const { return first; } |
94 | void set_last(const std::string& last_) { last = last_; } |
95 | void set_first(const std::string& first_) { first = first_; } |
96 | private: |
97 | std::string last; |
98 | std::string first; |
99 | }; |
100 | } |
101 | |
102 | #if BOOST_PP_VARIADICS |
103 | BOOST_FUSION_ADAPT_ADT( |
104 | ns::point, |
105 | (int, int, obj.get_x(), obj.set_x(val)) |
106 | (BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_y(), obj.set_y(val)) |
107 | (obj.get_z(), obj.set_z(val)) |
108 | ) |
109 | |
110 | # if !BOOST_WORKAROUND(__GNUC__,<4) |
111 | BOOST_FUSION_ADAPT_ADT( |
112 | ns::point_with_private_members, |
113 | (obj.get_x(), obj.set_x(val)) |
114 | (obj.get_y(), obj.set_y(val)) |
115 | (obj.get_z(), obj.set_z(val)) |
116 | ) |
117 | # endif |
118 | |
119 | |
120 | BOOST_FUSION_ADAPT_ADT( |
121 | ns::name, |
122 | (obj.get_last(), obj.set_last(val)) |
123 | (obj.get_first(), obj.set_first(val)) |
124 | ) |
125 | |
126 | |
127 | #else // BOOST_PP_VARIADICS |
128 | BOOST_FUSION_ADAPT_ADT( |
129 | ns::point, |
130 | (int, int, obj.get_x(), obj.set_x(val)) |
131 | (BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_y(), obj.set_y(val)) |
132 | (BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_z(), obj.set_z(val)) |
133 | ) |
134 | |
135 | # if !BOOST_WORKAROUND(__GNUC__,<4) |
136 | BOOST_FUSION_ADAPT_ADT( |
137 | ns::point_with_private_members, |
138 | (BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_x(), obj.set_x(val)) |
139 | (BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_y(), obj.set_y(val)) |
140 | (BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_z(), obj.set_z(val)) |
141 | ) |
142 | # endif |
143 | |
144 | BOOST_FUSION_ADAPT_ADT( |
145 | ns::name, |
146 | (const std::string&, const std::string&, obj.get_last(), obj.set_last(val)) |
147 | (BOOST_FUSION_ADAPT_AUTO, BOOST_FUSION_ADAPT_AUTO, obj.get_first(), obj.set_first(val)) |
148 | ) |
149 | |
150 | #endif |
151 | |
152 | class empty_adt{}; |
153 | BOOST_FUSION_ADAPT_ADT(empty_adt,) |
154 | |
155 | int |
156 | main() |
157 | { |
158 | using namespace boost::fusion; |
159 | using namespace boost; |
160 | |
161 | std::cout << tuple_open(c: '['); |
162 | std::cout << tuple_close(c: ']'); |
163 | std::cout << tuple_delimiter(s: ", " ); |
164 | |
165 | { |
166 | BOOST_MPL_ASSERT_NOT((traits::is_view<ns::point>)); |
167 | ns::point p(123, 456, 789); |
168 | |
169 | std::cout << at_c<0>(seq&: p) << std::endl; |
170 | std::cout << at_c<1>(seq&: p) << std::endl; |
171 | std::cout << at_c<2>(seq&: p) << std::endl; |
172 | std::cout << p << std::endl; |
173 | BOOST_TEST(p == make_vector(123, 456, 789)); |
174 | |
175 | at_c<0>(seq&: p) = 6; |
176 | at_c<1>(seq&: p) = 9; |
177 | at_c<2>(seq&: p) = 12; |
178 | BOOST_TEST(p == make_vector(6, 9, 12)); |
179 | |
180 | BOOST_STATIC_ASSERT(boost::fusion::result_of::size<ns::point>::value == 3); |
181 | BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<ns::point>::value); |
182 | |
183 | BOOST_TEST(front(p) == 6); |
184 | BOOST_TEST(back(p) == 12); |
185 | } |
186 | |
187 | { |
188 | fusion::vector<int, float, int> v1(4, 2, 2); |
189 | ns::point v2(5, 3, 3); |
190 | fusion::vector<long, double, int> v3(5, 4, 4); |
191 | BOOST_TEST(v1 < v2); |
192 | BOOST_TEST(v1 <= v2); |
193 | BOOST_TEST(v2 > v1); |
194 | BOOST_TEST(v2 >= v1); |
195 | BOOST_TEST(v2 < v3); |
196 | BOOST_TEST(v2 <= v3); |
197 | BOOST_TEST(v3 > v2); |
198 | BOOST_TEST(v3 >= v2); |
199 | } |
200 | |
201 | { |
202 | fusion::vector<std::string, std::string> v1("Lincoln" , "Abraham" ); |
203 | ns::name v2("Roosevelt" , "Franklin" ); |
204 | ns::name v3("Roosevelt" , "Theodore" ); |
205 | BOOST_TEST(v1 < v2); |
206 | BOOST_TEST(v1 <= v2); |
207 | BOOST_TEST(v2 > v1); |
208 | BOOST_TEST(v2 >= v1); |
209 | BOOST_TEST(v2 < v3); |
210 | BOOST_TEST(v2 <= v3); |
211 | BOOST_TEST(v3 > v2); |
212 | BOOST_TEST(v3 >= v2); |
213 | } |
214 | |
215 | { |
216 | // conversion from ns::point to vector |
217 | ns::point p(5, 3, 3); |
218 | fusion::vector<int, long, int> v(p); |
219 | v = p; |
220 | } |
221 | |
222 | { |
223 | // conversion from ns::point to list |
224 | ns::point p(5, 3, 3); |
225 | fusion::list<int, long, int> l(p); |
226 | l = p; |
227 | } |
228 | |
229 | { |
230 | BOOST_MPL_ASSERT((mpl::is_sequence<ns::point>)); |
231 | BOOST_MPL_ASSERT((boost::is_same< |
232 | boost::fusion::result_of::value_at_c<ns::point,0>::type |
233 | , mpl::front<ns::point>::type>)); |
234 | } |
235 | |
236 | #if !BOOST_WORKAROUND(__GNUC__,<4) |
237 | { |
238 | BOOST_MPL_ASSERT_NOT((traits::is_view<ns::point_with_private_members>)); |
239 | ns::point_with_private_members p(123, 456, 789); |
240 | |
241 | std::cout << at_c<0>(seq&: p) << std::endl; |
242 | std::cout << at_c<1>(seq&: p) << std::endl; |
243 | std::cout << at_c<2>(seq&: p) << std::endl; |
244 | std::cout << p << std::endl; |
245 | BOOST_TEST(p == make_vector(123, 456, 789)); |
246 | |
247 | at_c<0>(seq&: p) = 6; |
248 | at_c<1>(seq&: p) = 9; |
249 | at_c<2>(seq&: p) = 12; |
250 | BOOST_TEST(p == make_vector(6, 9, 12)); |
251 | |
252 | BOOST_STATIC_ASSERT(boost::fusion::result_of::size<ns::point_with_private_members>::value == 3); |
253 | BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<ns::point_with_private_members>::value); |
254 | |
255 | BOOST_TEST(front(p) == 6); |
256 | BOOST_TEST(back(p) == 12); |
257 | } |
258 | #endif |
259 | |
260 | { |
261 | // Check types provided in case it's provided |
262 | BOOST_MPL_ASSERT(( |
263 | boost::is_same< |
264 | boost::fusion::result_of::front<ns::point>::type, |
265 | boost::fusion::extension::adt_attribute_proxy<ns::point,0,false> |
266 | >)); |
267 | BOOST_MPL_ASSERT(( |
268 | boost::is_same< |
269 | boost::fusion::result_of::front<ns::point>::type::type, |
270 | int |
271 | >)); |
272 | BOOST_MPL_ASSERT(( |
273 | boost::is_same< |
274 | boost::fusion::result_of::front<ns::point const>::type, |
275 | boost::fusion::extension::adt_attribute_proxy<ns::point,0,true> |
276 | >)); |
277 | BOOST_MPL_ASSERT(( |
278 | boost::is_same< |
279 | boost::fusion::result_of::front<ns::point const>::type::type, |
280 | int |
281 | >)); |
282 | |
283 | // Check types provided in case it's deduced |
284 | BOOST_MPL_ASSERT(( |
285 | boost::is_same< |
286 | boost::fusion::result_of::back<ns::point>::type, |
287 | boost::fusion::extension::adt_attribute_proxy<ns::point,2,false> |
288 | >)); |
289 | BOOST_MPL_ASSERT(( |
290 | boost::is_same< |
291 | boost::fusion::result_of::back<ns::point>::type::type, |
292 | int |
293 | >)); |
294 | BOOST_MPL_ASSERT(( |
295 | boost::is_same< |
296 | boost::fusion::result_of::back<ns::point const>::type, |
297 | boost::fusion::extension::adt_attribute_proxy<ns::point,2,true> |
298 | >)); |
299 | BOOST_MPL_ASSERT(( |
300 | boost::is_same< |
301 | boost::fusion::result_of::back<ns::point const>::type::type, |
302 | const int |
303 | >)); |
304 | } |
305 | |
306 | return boost::report_errors(); |
307 | } |
308 | |
309 | |