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
27namespace boost_range_test
28{
29 namespace
30 {
31
32void 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( r&: str );
42 r = boost::make_iterator_range( Begin: str.begin(), End: str.end() );
43 cirange r2 = boost::make_iterator_range( r: cstr );
44 r2 = boost::make_iterator_range( Begin: cstr.begin(), End: cstr.end() );
45 r2 = boost::make_iterator_range( r&: 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( r&: str );
53 csrange s2 = r;
54 s2 = r2;
55 s2 = boost::make_iterator_range( r: cstr );
56 BOOST_CHECK( r2 == r2 );
57 BOOST_CHECK( s2 != r2 );
58 s2 = boost::make_iterator_range( r&: 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( r&: str );
114 BOOST_CHECK( rr.equal( r ) );
115
116 rr = boost::make_iterator_range( Begin: str.begin(), End: 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( r&: 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( r&: str, advance_begin: 1, advance_end: -1 );
136 BOOST_CHECK( rrr == boost::as_literal("ello worl") );
137 rrr = boost::make_iterator_range( r&: rrr, advance_begin: -1, advance_end: 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
145template<class T>
146void check_mutable_type(T&)
147{
148 BOOST_STATIC_ASSERT(!boost::is_const<T>::value);
149}
150
151template<class T>
152void check_constant_type(T&)
153{
154 BOOST_STATIC_ASSERT(boost::is_const<T>::value);
155}
156
157template<class Range, class Iterator>
158void 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
169template<class Range, class Iterator>
170void 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
181void 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(x: 0);
188
189 sub_range_t rng(c);
190 const sub_range_t crng(c);
191
192 check_is_iterator<sub_range_t>(it: rng.begin());
193 check_is_iterator<sub_range_t>(it: rng.end());
194
195 check_is_const_iterator<sub_range_t>(it: crng.begin());
196 check_is_const_iterator<sub_range_t>(it: 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
206void 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(x: 0);
213
214 sub_range_t rng(c);
215 const sub_range_t crng(c);
216
217 check_is_const_iterator<sub_range_t>(it: rng.begin());
218 check_is_const_iterator<sub_range_t>(it: rng.end());
219
220 check_is_const_iterator<sub_range_t>(it: crng.begin());
221 check_is_const_iterator<sub_range_t>(it: 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
231inline void test_advance()
232{
233 std::vector<int> l;
234 l.push_back(x: 1);
235 l.push_back(x: 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
247void 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
266boost::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

source code of boost/libs/range/test/sub_range.cpp