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
35namespace 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
152class empty_adt{};
153BOOST_FUSION_ADAPT_ADT(empty_adt,)
154
155int
156main()
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

source code of boost/libs/fusion/test/sequence/adapt_adt.cpp