1 /*=============================================================================
2 Copyright (c) 2001-2011 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 <string>
8 #include <boost/static_assert.hpp>
9 #include <boost/detail/lightweight_test.hpp>
10 #include <boost/fusion/support/category_of.hpp>
11 #include <boost/fusion/iterator/deref.hpp>
12 #include <boost/fusion/iterator/next.hpp>
13 #include <boost/fusion/iterator/prior.hpp>
14 #include <boost/fusion/iterator/equal_to.hpp>
15 #include <boost/fusion/iterator/distance.hpp>
16 #include <boost/fusion/iterator/advance.hpp>
17 #include <boost/fusion/iterator/value_of.hpp>
18 #include <boost/fusion/sequence/intrinsic/begin.hpp>
19 #include <boost/fusion/sequence/intrinsic/end.hpp>
20 #include <boost/fusion/sequence/intrinsic/at.hpp>
21 #include <boost/fusion/sequence/intrinsic/value_at.hpp>
22
test()23 void test()
24 {
25 using boost::fusion::next;
26 using namespace boost::fusion;
27 using namespace boost;
28
29 { // Testing deref, next, prior, begin, end
30
31 char const* s = "Hello";
32 typedef FUSION_SEQUENCE<int, char, double, char const*> seq_type;
33 seq_type v(1, 'x', 3.3, s);
34 boost::fusion::result_of::begin<seq_type>::type i(v);
35
36 BOOST_TEST(*i == 1);
37 BOOST_TEST(*next(i) == 'x');
38 BOOST_TEST(*next(next(i)) == 3.3);
39 BOOST_TEST(*next(next(next(i))) == s);
40 next(next(next(next(i)))); // end
41
42 #if !defined(FUSION_NO_PRIOR)
43 BOOST_TEST(*prior(next(next(next(i)))) == 3.3);
44 BOOST_TEST(*prior(prior(next(next(next(i))))) == 'x');
45 BOOST_TEST(*prior(prior(prior(next(next(next(i)))))) == 1);
46 #endif
47 BOOST_TEST(*begin(v) == 1);
48 #if !defined(FUSION_NO_PRIOR)
49 BOOST_TEST(*prior(end(v)) == s);
50 #endif
51
52 *i = 3;
53 BOOST_TEST(*i == 3);
54 BOOST_TEST(&*i == &at_c<0>(v));
55
56 // prove that it is mutable
57 *i = 987;
58 BOOST_TEST(*i == 987);
59 }
60
61 { // Testing const sequence and const iterator
62
63 char const* s = "Hello";
64 typedef FUSION_SEQUENCE<int, char, double, char const*> const seq_type;
65 seq_type t(1, 'x', 3.3, s);
66 boost::fusion::result_of::begin<seq_type>::type i(t);
67
68 BOOST_TEST(*i == 1);
69 BOOST_TEST(*next(i) == 'x');
70 BOOST_TEST(*begin(t) == 1);
71 #if !defined(FUSION_NO_PRIOR)
72 BOOST_TEST(*prior(end(t)) == s);
73 #endif
74
75 #ifdef FUSION_TEST_FAIL
76 *i = 3; // must not compile
77 #endif
78 }
79
80 { // Testing iterator equality
81
82 typedef FUSION_SEQUENCE<int, char, double, char const*> seq_type;
83 typedef FUSION_SEQUENCE<int, char, double, char const*> const cseq_type;
84 typedef boost::fusion::result_of::begin<seq_type>::type vi1;
85 typedef boost::fusion::result_of::begin<cseq_type>::type vi2;
86 BOOST_STATIC_ASSERT((boost::fusion::result_of::equal_to<vi1 const, vi1>::value));
87 BOOST_STATIC_ASSERT((boost::fusion::result_of::equal_to<vi1, vi1 const>::value));
88 BOOST_STATIC_ASSERT((boost::fusion::result_of::equal_to<vi1, vi2>::value));
89 BOOST_STATIC_ASSERT((boost::fusion::result_of::equal_to<vi1 const, vi2>::value));
90 BOOST_STATIC_ASSERT((boost::fusion::result_of::equal_to<vi1, vi2 const>::value));
91 BOOST_STATIC_ASSERT((boost::fusion::result_of::equal_to<vi1 const, vi2 const>::value));
92 }
93
94 {
95 typedef FUSION_SEQUENCE<int, int> seq_type;
96 typedef boost::fusion::result_of::begin<seq_type>::type begin_type;
97 typedef boost::fusion::result_of::end<seq_type>::type end_type;
98 typedef boost::fusion::result_of::next<begin_type>::type i1;
99 typedef boost::fusion::result_of::next<i1>::type i2;
100
101 BOOST_STATIC_ASSERT((is_same<end_type, i2>::value));
102 }
103
104 { // testing deref, next, prior, begin, end
105
106 char const* s = "Hello";
107 typedef FUSION_SEQUENCE<int, char, double, char const*> seq_type;
108 seq_type t(1, 'x', 3.3, s);
109 boost::fusion::result_of::begin<seq_type>::type i(t);
110
111 BOOST_TEST(*i == 1);
112 BOOST_TEST(*next(i) == 'x');
113 BOOST_TEST(*next(next(i)) == 3.3);
114 BOOST_TEST(*next(next(next(i))) == s);
115
116 next(next(next(next(i)))); // end
117
118 #ifdef FUSION_TEST_FAIL
119 next(next(next(next(next(i))))); // past the end: must not compile
120 #endif
121
122 #if !defined(FUSION_NO_PRIOR)
123 BOOST_TEST(*prior(next(next(next(i)))) == 3.3);
124 BOOST_TEST(*prior(prior(next(next(next(i))))) == 'x');
125 BOOST_TEST(*prior(prior(prior(next(next(next(i)))))) == 1);
126 #endif
127 BOOST_TEST(*begin(t) == 1);
128 #if !defined(FUSION_NO_PRIOR)
129 BOOST_TEST(*prior(end(t)) == s);
130 #endif
131
132 *i = 3;
133 BOOST_TEST(*i == 3);
134 BOOST_TEST(*i == at_c<0>(t));
135 }
136
137 { // Testing distance
138
139 typedef FUSION_SEQUENCE<int, char, double, char const*> seq_type;
140 seq_type t(1, 'x', 3.3, "Hello");
141
142 BOOST_STATIC_ASSERT((boost::fusion::result_of::distance<
143 boost::fusion::result_of::begin<seq_type>::type
144 , boost::fusion::result_of::end<seq_type>::type >::value == 4));
145
146 BOOST_TEST(distance(begin(t), end(t)).value == 4);
147 }
148
149 { // Testing tuple iterator boost::fusion::result_of::value_of, boost::fusion::result_of::deref, boost::fusion::result_of::value_at
150
151 typedef FUSION_SEQUENCE<int, char&> seq_type;
152 typedef boost::fusion::result_of::begin<seq_type>::type i0;
153 typedef boost::fusion::result_of::next<i0>::type i1;
154 typedef boost::fusion::result_of::next<boost::fusion::result_of::begin<const seq_type>::type>::type i2;
155
156 BOOST_STATIC_ASSERT((
157 is_same<boost::fusion::result_of::value_at_c<seq_type, 0>::type, int>::value));
158
159 BOOST_STATIC_ASSERT((
160 is_same<boost::fusion::result_of::value_at_c<seq_type, 1>::type, char&>::value));
161
162 BOOST_STATIC_ASSERT((
163 is_same<traits::category_of<i0>::type, FUSION_TRAVERSAL_TAG>::value));
164
165 BOOST_STATIC_ASSERT((is_same<boost::fusion::result_of::deref<i0>::type, int&>::value));
166 BOOST_STATIC_ASSERT((is_same<boost::fusion::result_of::deref<i1>::type, char&>::value));
167 BOOST_STATIC_ASSERT((is_same<boost::fusion::result_of::deref<i2>::type, char&>::value));
168
169 BOOST_STATIC_ASSERT((is_same<boost::fusion::result_of::value_of<i0>::type, int>::value));
170 BOOST_STATIC_ASSERT((is_same<boost::fusion::result_of::value_of<i1>::type, char&>::value));
171 BOOST_STATIC_ASSERT((is_same<boost::fusion::result_of::value_of<i2>::type, char&>::value));
172 }
173
174 { // Testing advance
175
176 typedef FUSION_SEQUENCE<int, char, double, char const*> seq_type;
177 seq_type t(1, 'x', 3.3, "Hello");
178
179 BOOST_TEST(*advance_c<0>(begin(t)) == at_c<0>(t));
180 BOOST_TEST(*advance_c<1>(begin(t)) == at_c<1>(t));
181 BOOST_TEST(*advance_c<2>(begin(t)) == at_c<2>(t));
182 BOOST_TEST(*advance_c<3>(begin(t)) == at_c<3>(t));
183
184 #if !defined(FUSION_NO_PRIOR)
185 BOOST_TEST(*advance_c<-1>(end(t)) == at_c<3>(t));
186 BOOST_TEST(*advance_c<-2>(end(t)) == at_c<2>(t));
187 BOOST_TEST(*advance_c<-3>(end(t)) == at_c<1>(t));
188 BOOST_TEST(*advance_c<-4>(end(t)) == at_c<0>(t));
189 #endif
190
191 BOOST_TEST(&*advance_c<0>(begin(t)) == &at_c<0>(t));
192 BOOST_TEST(&*advance_c<1>(begin(t)) == &at_c<1>(t));
193 BOOST_TEST(&*advance_c<2>(begin(t)) == &at_c<2>(t));
194 BOOST_TEST(&*advance_c<3>(begin(t)) == &at_c<3>(t));
195 }
196 }
197
198
199
200
201