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