• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost.Range library
2 //
3 //  Copyright Thorsten Ottosen 2003-2004. Use, modification and
4 //  distribution is subject to the Boost Software License, Version
5 //  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 //  http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // For more information, see http://www.boost.org/libs/range/
9 //
10 
11 
12 #include <boost/detail/workaround.hpp>
13 
14 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
15 #  pragma warn -8091 // suppress warning in Boost.Test
16 #  pragma warn -8057 // unused argument argc/argv in Boost.Test
17 #endif
18 
19 #include <boost/range/sub_range.hpp>
20 #include <boost/range/as_literal.hpp>
21 #include <boost/test/unit_test.hpp>
22 #include <boost/test/test_tools.hpp>
23 #include <iostream>
24 #include <string>
25 #include <vector>
26 
27 namespace boost_range_test
28 {
29     namespace
30     {
31 
check_sub_range()32 void check_sub_range()
33 {
34 
35     typedef std::string::iterator                 iterator;
36     typedef std::string::const_iterator           const_iterator;
37     typedef boost::iterator_range<iterator>       irange;
38     typedef boost::iterator_range<const_iterator> cirange;
39     std::string       str  = "hello world";
40     const std::string cstr = "const world";
41     irange r    = boost::make_iterator_range( str );
42     r           = boost::make_iterator_range( str.begin(), str.end() );
43     cirange r2  = boost::make_iterator_range( cstr );
44     r2          = boost::make_iterator_range( cstr.begin(), cstr.end() );
45     r2          = boost::make_iterator_range( str );
46 
47     typedef boost::sub_range<std::string>       srange;
48     typedef boost::sub_range<const std::string> csrange;
49     srange s     = r;
50     BOOST_CHECK( r == r );
51     BOOST_CHECK( s == r );
52     s            = boost::make_iterator_range( str );
53     csrange s2   = r;
54     s2           = r2;
55     s2           = boost::make_iterator_range( cstr );
56     BOOST_CHECK( r2 == r2 );
57     BOOST_CHECK( s2 != r2 );
58     s2           = boost::make_iterator_range( str );
59     BOOST_CHECK( !(s != s) );
60 
61     BOOST_CHECK( r.begin() == s.begin() );
62     BOOST_CHECK( r2.begin()== s2.begin() );
63     BOOST_CHECK( r.end()   == s.end() );
64     BOOST_CHECK( r2.end()  == s2.end() );
65     BOOST_CHECK_EQUAL( r.size(), s.size() );
66     BOOST_CHECK_EQUAL( r2.size(), s2.size() );
67 
68 //#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
69 //    if( !(bool)r )
70 //        BOOST_CHECK( false );
71 //    if( !(bool)r2 )
72 //        BOOST_CHECK( false );
73 //    if( !(bool)s )
74 //        BOOST_CHECK( false );
75 //    if( !(bool)s2 )
76 //        BOOST_CHECK( false );
77 //#else
78     if( !r )
79         BOOST_CHECK( false );
80     if( !r2 )
81         BOOST_CHECK( false );
82     if( !s )
83         BOOST_CHECK( false );
84     if( !s2 )
85         BOOST_CHECK( false );
86 //#endif
87 
88     std::cout << r << r2 << s << s2;
89 
90     std::string res  = boost::copy_range<std::string>( r );
91     BOOST_CHECK_EQUAL_COLLECTIONS( res.begin(), res.end(), r.begin(), r.end() );
92 
93     r.empty();
94     s.empty();
95     r.size();
96     s.size();
97 
98     //
99     // As of range v2 not legal anymore.
100     //
101     //irange singular_irange;
102     //BOOST_CHECK( singular_irange.empty() );
103     //BOOST_CHECK( singular_irange.size() == 0 );
104     //
105     //srange singular_srange;
106     //BOOST_CHECK( singular_srange.empty() );
107     //BOOST_CHECK( singular_srange.size() == 0 );
108     //
109     //BOOST_CHECK( empty( singular_irange ) );
110     //BOOST_CHECK( empty( singular_srange ) );
111     //
112 
113     srange rr = boost::make_iterator_range( str );
114     BOOST_CHECK( rr.equal( r ) );
115 
116     rr  = boost::make_iterator_range( str.begin(), str.begin() + 5 );
117     BOOST_CHECK( rr == boost::as_literal("hello") );
118     BOOST_CHECK( rr != boost::as_literal("hell") );
119     BOOST_CHECK( rr < boost::as_literal("hello dude") );
120     BOOST_CHECK( boost::as_literal("hello") == rr );
121     BOOST_CHECK( boost::as_literal("hell")  != rr );
122     BOOST_CHECK( ! (boost::as_literal("hello dude") < rr ) );
123 
124     irange rrr = rr;
125     BOOST_CHECK( rrr == rr );
126     BOOST_CHECK( !( rrr != rr ) );
127     BOOST_CHECK( !( rrr < rr ) );
128 
129     const irange cr = boost::make_iterator_range( str );
130     BOOST_CHECK_EQUAL( cr.front(), 'h' );
131     BOOST_CHECK_EQUAL( cr.back(), 'd' );
132     BOOST_CHECK_EQUAL( cr[1], 'e' );
133     BOOST_CHECK_EQUAL( cr(1), 'e' );
134 
135     rrr = boost::make_iterator_range( str, 1, -1 );
136     BOOST_CHECK( rrr == boost::as_literal("ello worl") );
137     rrr = boost::make_iterator_range( rrr, -1, 1 );
138     BOOST_CHECK( rrr == str );
139     rrr.front() = 'H';
140     rrr.back()  = 'D';
141     rrr[1]      = 'E';
142     BOOST_CHECK( rrr == boost::as_literal("HEllo worlD") );
143 }
144 
145 template<class T>
check_mutable_type(T &)146 void check_mutable_type(T&)
147 {
148     BOOST_STATIC_ASSERT(!boost::is_const<T>::value);
149 }
150 
151 template<class T>
check_constant_type(T &)152 void check_constant_type(T&)
153 {
154     BOOST_STATIC_ASSERT(boost::is_const<T>::value);
155 }
156 
157 template<class Range, class Iterator>
check_is_const_iterator(Iterator it)158 void check_is_const_iterator(Iterator it)
159 {
160     BOOST_STATIC_ASSERT((
161         boost::is_same<
162             BOOST_DEDUCED_TYPENAME boost::range_iterator<
163                 BOOST_DEDUCED_TYPENAME boost::add_const<Range>::type
164             >::type,
165             Iterator
166         >::value));
167 }
168 
169 template<class Range, class Iterator>
check_is_iterator(Iterator it)170 void check_is_iterator(Iterator it)
171 {
172     BOOST_STATIC_ASSERT((
173         boost::is_same<
174             BOOST_DEDUCED_TYPENAME boost::range_iterator<
175                 BOOST_DEDUCED_TYPENAME boost::remove_const<Range>::type
176             >::type,
177             Iterator
178         >::value));
179 }
180 
const_propagation_mutable_collection(void)181 void const_propagation_mutable_collection(void)
182 {
183     typedef std::vector<int> coll_t;
184     typedef boost::sub_range<coll_t> sub_range_t;
185 
186     coll_t c;
187     c.push_back(0);
188 
189     sub_range_t rng(c);
190     const sub_range_t crng(c);
191 
192     check_is_iterator<sub_range_t>(rng.begin());
193     check_is_iterator<sub_range_t>(rng.end());
194 
195     check_is_const_iterator<sub_range_t>(crng.begin());
196     check_is_const_iterator<sub_range_t>(crng.end());
197 
198     check_mutable_type(rng[0]);
199     check_mutable_type(rng.front());
200     check_mutable_type(rng.back());
201     check_constant_type(crng[0]);
202     check_constant_type(crng.front());
203     check_constant_type(crng.back());
204 }
205 
const_propagation_const_collection(void)206 void const_propagation_const_collection(void)
207 {
208     typedef std::vector<int> coll_t;
209     typedef boost::sub_range<const coll_t> sub_range_t;
210 
211     coll_t c;
212     c.push_back(0);
213 
214     sub_range_t rng(c);
215     const sub_range_t crng(c);
216 
217     check_is_const_iterator<sub_range_t>(rng.begin());
218     check_is_const_iterator<sub_range_t>(rng.end());
219 
220     check_is_const_iterator<sub_range_t>(crng.begin());
221     check_is_const_iterator<sub_range_t>(crng.end());
222 
223     check_constant_type(rng[0]);
224     check_constant_type(rng.front());
225     check_constant_type(rng.back());
226     check_constant_type(crng[0]);
227     check_constant_type(crng.front());
228     check_constant_type(crng.back());
229 }
230 
test_advance()231 inline void test_advance()
232 {
233     std::vector<int> l;
234     l.push_back(1);
235     l.push_back(2);
236     typedef boost::sub_range<std::vector<int> > rng_t;
237     rng_t r1(l.begin(), l.end());
238     BOOST_CHECK(r1.advance_begin(1).advance_end(-1).empty());
239 
240     rng_t r2(l.begin(), l.end());
241     BOOST_CHECK_EQUAL(r2.advance_begin(1).size(), 1u);
242 
243     rng_t r3(l.begin(), l.end());
244     BOOST_CHECK_EQUAL(r3.advance_end(-1).size(), 1u);
245 }
246 
ticket_10514()247 void ticket_10514()
248 {
249     typedef std::vector<int> vec_t;
250     typedef boost::sub_range<vec_t> range_t;
251     vec_t v(10);
252     range_t r(v.begin(), v.end());
253     const range_t& cr = r;
254     range_t copy_r = cr;
255 
256     BOOST_CHECK(r.begin() == copy_r.begin());
257     BOOST_CHECK(r.end() == copy_r.end());
258 
259     BOOST_CHECK(cr.begin() == copy_r.begin());
260     BOOST_CHECK(cr.end() == copy_r.end());
261 }
262 
263     } // anonymous namespace
264 } // namespace boost_range_test
265 
init_unit_test_suite(int,char * [])266 boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
267 {
268     boost::unit_test::test_suite* test =
269             BOOST_TEST_SUITE( "Boost.Range sub_range test suite" );
270 
271     test->add(BOOST_TEST_CASE(&boost_range_test::check_sub_range));
272 
273     test->add(BOOST_TEST_CASE(
274                   &boost_range_test::const_propagation_const_collection));
275 
276     test->add(BOOST_TEST_CASE(
277                   &boost_range_test::const_propagation_mutable_collection));
278 
279     test->add(BOOST_TEST_CASE(&boost_range_test::test_advance));
280 
281     test->add(BOOST_TEST_CASE(&boost_range_test::ticket_10514));
282 
283     return test;
284 }
285 
286 
287 
288 
289 
290