• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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