• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2001-2007 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/struct/adapt_struct.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/static_assert.hpp>
32 #include <iostream>
33 #include <string>
34 
35 namespace namespaced_type {
36   typedef int integer;
37 }
38 
39 namespace ns
40 {
41     struct point
42     {
43         int x;
44         int y;
45         namespaced_type::integer z;
46     };
47 
48 #if !BOOST_WORKAROUND(__GNUC__,<4)
49     struct point_with_private_attributes
50     {
51         friend struct boost::fusion::extension::access;
52 
53     private:
54         int x;
55         int y;
56         int z;
57 
58     public:
point_with_private_attributesns::point_with_private_attributes59         point_with_private_attributes(int x, int y, int z):x(x),y(y),z(z)
60         {}
61     };
62 #endif
63 
64     struct foo
65     {
66         int x;
67     };
68 
69     struct bar
70     {
71         foo foo_;
72         int y;
73     };
74 
75 
76     // Testing non-constexpr compatible types
77     struct employee {
78       std::string name;
79       std::string nickname;
80 
employeens::employee81       employee(std::string name, std::string nickname)
82         : name(name), nickname(nickname)
83       {}
84     };
85 }
86 
87 #if BOOST_PP_VARIADICS
88 
89     BOOST_FUSION_ADAPT_STRUCT(
90         ns::point,
91         x,
92         y,
93         z
94     )
95 
96 #   if !BOOST_WORKAROUND(__GNUC__,<4)
97     BOOST_FUSION_ADAPT_STRUCT(
98         ns::point_with_private_attributes,
99         x,
100         y,
101         z
102     )
103 #   endif
104 
105     struct s { int m; };
106     BOOST_FUSION_ADAPT_STRUCT(s, m)
107 
108     BOOST_FUSION_ADAPT_STRUCT(
109         ns::bar,
110         foo_.x, // test that adapted members can actually be expressions
111         (auto , y)
112     )
113 
114     BOOST_FUSION_ADAPT_STRUCT(
115         ns::employee,
116         name,
117         nickname
118     )
119 
120 
121 #else // BOOST_PP_VARIADICS
122 
123     BOOST_FUSION_ADAPT_STRUCT(
124         ns::point,
125         (int, x)
126         (auto, y)
127         (namespaced_type::integer, z)
128     )
129 
130 #   if !BOOST_WORKAROUND(__GNUC__,<4)
131     BOOST_FUSION_ADAPT_STRUCT(
132         ns::point_with_private_attributes,
133         (int, x)
134         (int, y)
135         (auto, z)
136     )
137 #   endif
138 
139     struct s { int m; };
140     BOOST_FUSION_ADAPT_STRUCT(s, (auto, m))
141 
142     BOOST_FUSION_ADAPT_STRUCT(
143         ns::bar,
144         (auto, foo_.x) // test that adapted members can actually be expressions
145         (BOOST_FUSION_ADAPT_AUTO, y) // Mixing auto & BOOST_FUSION_ADAPT_AUTO
146                                      // to test backward compatibility
147     )
148 
149     BOOST_FUSION_ADAPT_STRUCT(
150         ns::employee,
151         (std::string, name)
152         (BOOST_FUSION_ADAPT_AUTO, nickname)
153     )
154 
155 #endif
156 
157 struct empty_struct {};
158 BOOST_FUSION_ADAPT_STRUCT(empty_struct,)
159 
160 int
main()161 main()
162 {
163     using namespace boost::fusion;
164     using namespace boost;
165     using ns::point;
166 
167     std::cout << tuple_open('[');
168     std::cout << tuple_close(']');
169     std::cout << tuple_delimiter(", ");
170 
171     {
172         BOOST_MPL_ASSERT_NOT((traits::is_view<point>));
173         BOOST_STATIC_ASSERT(!traits::is_view<point>::value);
174         point p = {123, 456, 789};
175 
176         std::cout << at_c<0>(p) << std::endl;
177         std::cout << at_c<1>(p) << std::endl;
178         std::cout << at_c<2>(p) << std::endl;
179         std::cout << p << std::endl;
180         BOOST_TEST(p == make_vector(123, 456, 789));
181 
182         at_c<0>(p) = 6;
183         at_c<1>(p) = 9;
184         at_c<2>(p) = 12;
185         BOOST_TEST(p == make_vector(6, 9, 12));
186 
187         BOOST_STATIC_ASSERT(boost::fusion::result_of::size<point>::value == 3);
188         BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<point>::value);
189 
190         BOOST_TEST(front(p) == 6);
191         BOOST_TEST(back(p) == 12);
192     }
193 
194     {
195         vector<int, float, int> v1(4, 2.f, 2);
196         point v2 = {5, 3, 3};
197         vector<long, double, int> v3(5, 4., 4);
198         BOOST_TEST(v1 < v2);
199         BOOST_TEST(v1 <= v2);
200         BOOST_TEST(v2 > v1);
201         BOOST_TEST(v2 >= v1);
202         BOOST_TEST(v2 < v3);
203         BOOST_TEST(v2 <= v3);
204         BOOST_TEST(v3 > v2);
205         BOOST_TEST(v3 >= v2);
206     }
207 
208     {
209         // conversion from point to vector
210         point p = {5, 3, 3};
211         vector<int, long, int> v(p);
212         v = p;
213     }
214 
215     {
216         // conversion from point to list
217         point p = {5, 3, 3};
218         list<int, long, int> l(p);
219         l = p;
220     }
221 
222     { // begin/end
223         using namespace boost::fusion;
224         using boost::is_same;
225 
226         typedef boost::fusion::result_of::begin<s>::type b;
227         typedef boost::fusion::result_of::end<s>::type e;
228         // this fails
229         BOOST_MPL_ASSERT((is_same<boost::fusion::result_of::next<b>::type, e>));
230     }
231 
232     {
233         BOOST_MPL_ASSERT((mpl::is_sequence<ns::point>));
234         BOOST_MPL_ASSERT((boost::is_same<
235             boost::fusion::result_of::value_at_c<ns::point,0>::type
236           , mpl::front<ns::point>::type>));
237     }
238 
239 #if !BOOST_WORKAROUND(__GNUC__,<4)
240     {
241         ns::point_with_private_attributes p(123, 456, 789);
242 
243         std::cout << at_c<0>(p) << std::endl;
244         std::cout << at_c<1>(p) << std::endl;
245         std::cout << at_c<2>(p) << std::endl;
246         std::cout << p << std::endl;
247         BOOST_TEST(p == make_vector(123, 456, 789));
248     }
249 #endif
250 
251     {
252         fusion::vector<int, float> v1(4, 2.f);
253         ns::bar v2 = {{5}, 3};
254         BOOST_TEST(v1 < v2);
255         BOOST_TEST(v1 <= v2);
256         BOOST_TEST(v2 > v1);
257         BOOST_TEST(v2 >= v1);
258     }
259 
260     {
261         ns::employee emp("John Doe", "jdoe");
262         std::cout << at_c<0>(emp) << std::endl;
263         std::cout << at_c<1>(emp) << std::endl;
264 
265         fusion::vector<std::string, std::string> v1("John Doe", "jdoe");
266         BOOST_TEST(emp == v1);
267     }
268 
269     return boost::report_errors();
270 }
271 
272