1 /*=============================================================================
2     Copyright (c) 2010 Christopher Schmidt
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/sequence.hpp>
9 #include <boost/fusion/support.hpp>
10 #include <boost/fusion/container/list.hpp>
11 #include <boost/fusion/container/vector.hpp>
12 #include <boost/fusion/container/generation/make_vector.hpp>
13 #include <boost/fusion/adapted/adt/adapt_assoc_adt.hpp>
14 #include <boost/mpl/assert.hpp>
15 #include <boost/mpl/not.hpp>
16 #include <boost/mpl/front.hpp>
17 #include <boost/mpl/is_sequence.hpp>
18 #include <boost/type_traits/is_same.hpp>
19 #include <boost/static_assert.hpp>
20 #include <iostream>
21 #include <string>
22 
23 namespace ns
24 {
25     struct x_member;
26     struct y_member;
27     struct z_member;
28 
29     struct non_member;
30 
31     class point
32     {
33     public:
34 
point()35         point() : x(0), y(0), z(0) {}
point(int in_x,int in_y,int in_z)36         point(int in_x, int in_y, int in_z) : x(in_x), y(in_y), z(in_z) {}
37 
get_x() const38         int get_x() const { return x; }
get_y() const39         int get_y() const { return y; }
get_z() const40         int get_z() const { return z; }
set_x(int x_)41         void set_x(int x_) { x = x_; }
set_y(int y_)42         void set_y(int y_) { y = y_; }
set_z(int z_)43         void set_z(int z_) { z = z_; }
44 
45     private:
46 
47         int x;
48         int y;
49         int z;
50     };
51 }
52 
53 #if BOOST_PP_VARIADICS
54 
55 BOOST_FUSION_ADAPT_ASSOC_ADT(
56     ns::point,
57     (int, int, obj.get_x(), obj.set_x(val), ns::x_member)
58     (int, int, obj.get_y(), obj.set_y(val), ns::y_member)
59     (obj.get_z(), obj.set_z(val), ns::z_member)
60 )
61 
62 #else // BOOST_PP_VARIADICS
63 
64 BOOST_FUSION_ADAPT_ASSOC_ADT(
65     ns::point,
66     (int, int, obj.get_x(), obj.set_x(val), ns::x_member)
67     (int, int, obj.get_y(), obj.set_y(val), ns::y_member)
68     (auto, auto, obj.get_z(), obj.set_z(val), ns::z_member)
69 )
70 
71 #endif
72 
73 class empty_adt{};
74 BOOST_FUSION_ADAPT_ASSOC_ADT(empty_adt,)
75 
76 int
main()77 main()
78 {
79     using namespace boost::fusion;
80 
81     std::cout << tuple_open('[');
82     std::cout << tuple_close(']');
83     std::cout << tuple_delimiter(", ");
84 
85     {
86         BOOST_MPL_ASSERT_NOT((traits::is_view<ns::point>));
87         BOOST_STATIC_ASSERT(!traits::is_view<ns::point>::value);
88         ns::point p(123, 456, 789);
89 
90         std::cout << at_c<0>(p) << std::endl;
91         std::cout << at_c<1>(p) << std::endl;
92         std::cout << at_c<2>(p) << std::endl;
93         std::cout << p << std::endl;
94         BOOST_TEST(p == make_vector(123, 456, 789));
95 
96         at_c<0>(p) = 6;
97         at_c<1>(p) = 9;
98         at_c<2>(p) = 12;
99         BOOST_TEST(p == make_vector(6, 9, 12));
100 
101         BOOST_STATIC_ASSERT(boost::fusion::result_of::size<ns::point>::value == 3);
102         BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<ns::point>::value);
103 
104         BOOST_TEST(front(p) == 6);
105         BOOST_TEST(back(p) == 12);
106     }
107 
108     {
109         boost::fusion::vector<int, float, int> v1(4, 2.f, 2);
110         ns::point v2(5, 3, 3);
111         boost::fusion::vector<long, double, int> v3(5, 4., 4);
112         BOOST_TEST(v1 < v2);
113         BOOST_TEST(v1 <= v2);
114         BOOST_TEST(v2 > v1);
115         BOOST_TEST(v2 >= v1);
116         BOOST_TEST(v2 < v3);
117         BOOST_TEST(v2 <= v3);
118         BOOST_TEST(v3 > v2);
119         BOOST_TEST(v3 >= v2);
120     }
121 
122     {
123         // conversion from ns::point to vector
124         ns::point p(5, 3, 3);
125         boost::fusion::vector<int, long, int> v(p);
126         v = p;
127     }
128 
129     {
130         // conversion from ns::point to list
131         ns::point p(5, 3, 3);
132         boost::fusion::list<int, long, int> l(p);
133         l = p;
134     }
135 
136     {
137         BOOST_MPL_ASSERT((boost::mpl::is_sequence<ns::point>));
138         BOOST_MPL_ASSERT((boost::is_same<
139             boost::fusion::result_of::value_at_c<ns::point,0>::type
140           , boost::mpl::front<ns::point>::type>));
141     }
142 
143     {
144         // assoc stuff
145         BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<ns::point, ns::x_member>));
146         BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<ns::point, ns::y_member>));
147         BOOST_MPL_ASSERT((boost::fusion::result_of::has_key<ns::point, ns::z_member>));
148         BOOST_MPL_ASSERT((boost::mpl::not_<boost::fusion::result_of::has_key<ns::point, ns::non_member> >));
149 
150 
151         BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<ns::point, ns::x_member>::type, int>));
152         BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<ns::point, ns::y_member>::type, int>));
153         BOOST_MPL_ASSERT((boost::is_same<boost::fusion::result_of::value_at_key<ns::point, ns::z_member>::type, int>));
154 
155         ns::point p(5, 3, 1);
156 
157         BOOST_TEST(at_key<ns::x_member>(p) == 5);
158         BOOST_TEST(at_key<ns::y_member>(p) == 3);
159         BOOST_TEST(at_key<ns::z_member>(p) == 1);
160     }
161 
162     return boost::report_errors();
163 }
164 
165