• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (C) 1999-2003 Jaakko Jarvi
3     Copyright (c) 2001-2011 Joel de Guzman
4 
5     Distributed under the Boost Software License, Version 1.0. (See accompanying
6     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 ==============================================================================*/
8 #include <boost/detail/lightweight_test.hpp>
9 #include <boost/fusion/sequence/intrinsic.hpp>
10 #include <boost/fusion/support/is_sequence.hpp>
11 #include <boost/fusion/mpl.hpp>
12 #include <boost/mpl/find.hpp>
13 #include <boost/mpl/equal.hpp>
14 #include <boost/mpl/int.hpp>
15 #include <boost/mpl/integral_c.hpp>
16 #include <boost/mpl/is_sequence.hpp>
17 #include <boost/type_traits/is_same.hpp>
18 #include <string>
19 
20 #if !defined(FUSION_AT)
21 #define FUSION_AT at_c
22 #endif
23 
24 #if !defined(FUSION_SIZE)
25 #define FUSION_SIZE boost::fusion::result_of::size
26 #endif
27 
28 template <typename S1, typename S2>
29 struct is_same
30 {
31 };
32 
33 struct test_intrinsics1
34 {
35     // test at, begin, end, next, prior, advance, size, deref, etc.
36 
37     typedef boost::fusion::FUSION_SEQUENCE<int, float, bool, char> sequence;
38     typedef boost::mpl::begin<sequence>::type first;
39     typedef boost::mpl::next<first>::type second;
40     typedef boost::mpl::next<second>::type third;
41     typedef boost::mpl::next<third>::type fourth;
42     typedef boost::mpl::end<sequence>::type last;
43 
44     BOOST_STATIC_ASSERT((boost::is_same<
45         boost::mpl::deref<first>::type, int>::value));
46 
47     BOOST_STATIC_ASSERT((boost::is_same<
48         boost::mpl::deref<second>::type, float>::value));
49 
50     BOOST_STATIC_ASSERT((boost::is_same<
51         boost::mpl::deref<third>::type, bool>::value));
52 
53     BOOST_STATIC_ASSERT((boost::is_same<
54         boost::mpl::deref<fourth>::type, char>::value));
55 
56     BOOST_STATIC_ASSERT((boost::is_same<
57         boost::mpl::at_c<sequence, 2>::type, bool>::value));
58 
59     BOOST_STATIC_ASSERT((boost::is_same<
60         boost::mpl::front<sequence>::type, int>::value));
61 
62     BOOST_STATIC_ASSERT((boost::is_same<
63         boost::mpl::deref<
64             boost::mpl::advance_c<second, 2>::type>::type, char>::value));
65 
66     BOOST_STATIC_ASSERT((boost::mpl::size<sequence>::value == 4));
67     BOOST_STATIC_ASSERT(!(boost::mpl::empty<sequence>::value));
68     BOOST_STATIC_ASSERT((boost::mpl::distance<second, fourth>::value == 2));
69 
70 #if !defined(FUSION_FORWARD_ONLY) // list has no back/prev
71 
72     typedef boost::mpl::prior<last>::type fourth_;
73     typedef boost::mpl::prior<fourth_>::type third_;
74     typedef boost::mpl::prior<third_>::type second_;
75     typedef boost::mpl::prior<second_>::type first_;
76 
77     BOOST_STATIC_ASSERT((boost::is_same<
78         boost::mpl::deref<first_>::type, int>::value));
79 
80     BOOST_STATIC_ASSERT((boost::is_same<
81         boost::mpl::deref<second_>::type, float>::value));
82 
83     BOOST_STATIC_ASSERT((boost::is_same<
84         boost::mpl::deref<third_>::type, bool>::value));
85 
86     BOOST_STATIC_ASSERT((boost::is_same<
87         boost::mpl::deref<fourth_>::type, char>::value));
88 
89     BOOST_STATIC_ASSERT((boost::is_same<
90         boost::mpl::back<sequence>::type, char>::value));
91 
92 #endif
93 };
94 
95 struct test_intrinsics2
96 {
97     typedef boost::fusion::FUSION_SEQUENCE<> seq0;
98 
99 #if !defined(BOOST_FUSION_SEQUENCE_CONVERSION_IS_NOT_SEQUENCE__TYPE_PRESERVING)
100 #if !defined(FUSION_FORWARD_ONLY) // list has no back/prev
101 
102     typedef boost::fusion::FUSION_SEQUENCE<int> target1;
103     typedef boost::mpl::push_back<seq0, int>::type seq1;
104     BOOST_STATIC_ASSERT((boost::mpl::equal<seq1, target1>::value));
105 
106     typedef boost::fusion::FUSION_SEQUENCE<int, double> target2;
107     typedef boost::mpl::push_back<seq1, double>::type seq2;
108     BOOST_STATIC_ASSERT((boost::mpl::equal<seq2, target2>::value));
109 
110 #endif
111 
112     typedef boost::fusion::FUSION_SEQUENCE<int> target3;
113     typedef boost::mpl::push_front<seq0, int>::type seq3;
114     BOOST_STATIC_ASSERT((boost::mpl::equal<seq3, target3>::value));
115 
116     typedef boost::fusion::FUSION_SEQUENCE<double, int> target4;
117     typedef boost::mpl::push_front<seq3, double>::type seq4;
118     BOOST_STATIC_ASSERT((boost::mpl::equal<seq4, target4>::value));
119 
120 #endif
121 };
122 
123 void
test()124 test()
125 {
126     using namespace boost::fusion;
127 
128     {   // testing const sequences
129 
130         const FUSION_SEQUENCE<int, float> t1(5, 3.3f);
131         BOOST_TEST(FUSION_AT<0>(t1) == 5);
132         BOOST_TEST(FUSION_AT<1>(t1) == 3.3f);
133     }
134 
135     {   // testing at<N> works with MPL integral constants
136         const FUSION_SEQUENCE<int, char> t1(101, 'z');
137         BOOST_TEST(boost::fusion::at<boost::mpl::int_<0> >(t1) == 101);
138         BOOST_TEST(boost::fusion::at<boost::mpl::int_<1> >(t1) == 'z');
139         // explicitly try something other than mpl::int_
140         BOOST_TEST((boost::fusion::at<boost::mpl::integral_c<long, 0> >(t1) == 101));
141         BOOST_TEST((boost::fusion::at<boost::mpl::integral_c<long, 1> >(t1) == 'z'));
142     }
143 
144     {   // testing size & empty
145 
146         typedef FUSION_SEQUENCE<int, float, double> t1;
147         typedef FUSION_SEQUENCE<> t2;
148 
149         BOOST_STATIC_ASSERT(FUSION_SIZE<t1>::value == 3);
150         BOOST_STATIC_ASSERT(FUSION_SIZE<t2>::value == 0);
151         BOOST_STATIC_ASSERT(!boost::fusion::result_of::empty<t1>::value);
152         BOOST_STATIC_ASSERT(boost::fusion::result_of::empty<t2>::value);
153     }
154 
155     {   // testing front & back
156 
157         typedef FUSION_SEQUENCE<int, float, std::string> tup;
158         tup t(1, 2.2f, "Kimpo");
159 
160         BOOST_TEST(front(t) == 1);
161 #if !defined(FUSION_FORWARD_ONLY) // list has no back
162         BOOST_TEST(back(t) == "Kimpo");
163 #endif
164     }
165 
166     {   // testing is_sequence
167 
168         typedef FUSION_SEQUENCE<int, float, double> t1;
169         typedef FUSION_SEQUENCE<> t2;
170         typedef FUSION_SEQUENCE<char> t3;
171 
172         BOOST_STATIC_ASSERT(traits::is_sequence<t1>::value);
173         BOOST_STATIC_ASSERT(traits::is_sequence<t2>::value);
174         BOOST_STATIC_ASSERT(traits::is_sequence<t3>::value);
175         BOOST_STATIC_ASSERT(!traits::is_sequence<int>::value);
176         BOOST_STATIC_ASSERT(!traits::is_sequence<char>::value);
177     }
178 
179     {   // testing mpl::is_sequence
180 
181         typedef FUSION_SEQUENCE<int, float, double> t1;
182         typedef FUSION_SEQUENCE<> t2;
183         typedef FUSION_SEQUENCE<char> t3;
184 
185         BOOST_STATIC_ASSERT(boost::mpl::is_sequence<t1>::value);
186         BOOST_STATIC_ASSERT(boost::mpl::is_sequence<t2>::value);
187         BOOST_STATIC_ASSERT(boost::mpl::is_sequence<t3>::value);
188     }
189 
190     {   // testing mpl compatibility
191 
192         // test begin, end, next, prior, advance, size, deref, etc.
193         //~ typedef FUSION_SEQUENCE<int, float, bool, char> tuple_type;
194         //~ test_intrinsics1<tuple_type> test1;
195         //~ (void)test1; // prevent unused variable warning
196 
197         // test an algorithm
198         typedef FUSION_SEQUENCE<int, float, double> t1;
199         typedef boost::mpl::find<t1, float>::type iter;
200         typedef boost::mpl::deref<iter>::type type;
201         BOOST_STATIC_ASSERT((boost::is_same<type, float>::value));
202 
203     }
204 }
205