1
// Copyright Neil Groves 2009. Use, modification and
2
// distribution is subject to the Boost Software License, Version
3
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
4
// http://www.boost.org/LICENSE_1_0.txt)
7
// For more information, see http://www.boost.org/libs/range/
9
#ifndef BOOST_RANGE_TEST_TEST_DRIVER_RANGE_RETURN_TEST_DRIVER_HPP_INCLUDED
10
#define BOOST_RANGE_TEST_TEST_DRIVER_RANGE_RETURN_TEST_DRIVER_HPP_INCLUDED
12
#include <boost/assert.hpp>
13
#include <boost/test/test_tools.hpp>
14
#include <boost/test/unit_test.hpp>
20
// check the results of an algorithm that returns
23
// This version is the general version. It should never be called.
24
// All calls should invoke specialized implementations.
25
template< range_return_value return_type >
28
template< class Container, class Iterator >
36
BOOST_ASSERT( false );
40
// check the results of an algorithm that returns
43
struct check_results<return_found>
45
template< class Container, class Iterator >
53
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
54
test.begin(), test.end() );
56
BOOST_CHECK_EQUAL( std::distance(test.begin(), test_it),
57
std::distance(reference.begin(), reference_it) );
61
// check the results of an algorithm that returns
62
// a 'next(found)' iterator
64
struct check_results<return_next>
66
template< class Container, class Iterator >
74
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
75
test.begin(), test.end() );
77
if (reference_it == reference.end())
79
BOOST_CHECK( test_it == test.end() );
84
std::distance(test.begin(), test_it),
85
std::distance(reference.begin(), reference_it) + 1);
90
// check the results of an algorithm that returns
91
// a 'prior(found)' iterator
93
struct check_results<return_prior>
95
template< class Container, class Iterator >
100
Iterator reference_it
103
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
104
test.begin(), test.end() );
106
if (reference_it == reference.begin())
108
BOOST_CHECK( test_it == test.begin() );
113
std::distance(test.begin(), test_it) + 1,
114
std::distance(reference.begin(), reference_it));
119
// check the results of an algorithm that returns
120
// a '[begin, found)' range
122
struct check_results<return_begin_found>
124
template< class Container, class Iterator >
127
Container& reference,
128
iterator_range<Iterator> test_rng,
129
Iterator reference_it
132
BOOST_CHECK_EQUAL_COLLECTIONS(
133
reference.begin(), reference.end(),
134
test.begin(), test.end()
137
BOOST_CHECK( test_rng.begin() == test.begin() );
139
BOOST_CHECK_EQUAL_COLLECTIONS(
140
reference.begin(), reference_it,
141
boost::begin(test_rng), boost::end(test_rng)
146
// check the results of an algorithm that returns
147
// a '[begin, next(found))' range
149
struct check_results<return_begin_next>
151
template< class Container, class Iterator >
154
Container& reference,
155
iterator_range<Iterator> test_rng,
156
Iterator reference_it
159
BOOST_CHECK_EQUAL_COLLECTIONS(
160
reference.begin(), reference.end(),
161
test.begin(), test.end()
164
BOOST_CHECK( test_rng.begin() == test.begin() );
166
if (reference_it == reference.end())
168
BOOST_CHECK( test_rng.end() == test.end() );
172
BOOST_CHECK_EQUAL_COLLECTIONS(
173
reference.begin(), boost::next(reference_it),
174
test_rng.begin(), test_rng.end());
179
// check the results of an algorithm that returns
180
// a '[begin, prior(found))' range
182
struct check_results<return_begin_prior>
184
template< class Container, class Iterator >
187
Container& reference,
188
iterator_range<Iterator> test_rng,
189
Iterator reference_it
192
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
193
test.begin(), test.end() );
195
BOOST_CHECK( test_rng.begin() == test.begin() );
197
if (reference_it == reference.begin())
199
BOOST_CHECK( boost::end(test_rng) == test.begin() );
203
BOOST_CHECK_EQUAL( std::distance(boost::begin(test_rng), boost::end(test_rng)) + 1,
204
std::distance(reference.begin(), reference_it) );
209
// check the results of an algorithm that returns
210
// a '[found, end)' range
212
struct check_results<return_found_end>
214
template< class Container, class Iterator >
217
Container& reference,
218
iterator_range<Iterator> test_rng,
219
Iterator reference_it
222
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
223
test.begin(), test.end() );
226
std::distance(test.begin(), boost::begin(test_rng)),
227
std::distance(reference.begin(), reference_it));
229
BOOST_CHECK( boost::end(test_rng) == test.end() );
233
// check the results of an algorithm that returns
234
// a '[next(found), end)' range
236
struct check_results<return_next_end>
238
template< class Container, class Iterator >
241
Container& reference,
242
iterator_range<Iterator> test_rng,
243
Iterator reference_it
246
BOOST_CHECK_EQUAL_COLLECTIONS(
247
reference.begin(), reference.end(),
248
test.begin(), test.end()
251
BOOST_CHECK( test_rng.end() == test.end() );
253
if (reference_it == reference.end())
255
BOOST_CHECK( test_rng.begin() == test.end() );
259
BOOST_CHECK_EQUAL_COLLECTIONS(
260
boost::next(reference_it), reference.end(),
261
test_rng.begin(), test_rng.end()
267
// check the results of an algorithm that returns
268
// a 'prior(found), end)' range
270
struct check_results<return_prior_end>
272
template< class Container, class Iterator >
275
Container& reference,
276
iterator_range<Iterator> test_rng,
277
Iterator reference_it
280
BOOST_CHECK_EQUAL_COLLECTIONS(
281
reference.begin(), reference.end(),
282
test.begin(), test.end()
285
BOOST_CHECK( test_rng.end() == test.end() );
287
if (reference_it == reference.begin())
289
BOOST_CHECK( test_rng.begin() == test.begin() );
293
BOOST_CHECK_EQUAL_COLLECTIONS(
294
boost::prior(reference_it), reference.end(),
295
test_rng.begin(), test_rng.end()
301
// check the results of an algorithm that returns
302
// a '[begin, end)' range
304
struct check_results<return_begin_end>
306
template< class Container, class Iterator >
309
Container& reference,
310
iterator_range<Iterator> test_rng,
311
Iterator reference_it
314
BOOST_CHECK_EQUAL_COLLECTIONS(
315
reference.begin(), reference.end(),
316
test.begin(), test.end()
319
BOOST_CHECK( test_rng.begin() == test.begin() );
320
BOOST_CHECK( test_rng.end() == test.end() );
324
// A test driver to exercise a test through all of the range_return
327
// The test driver also contains the code required to check the
328
// return value correctness.
330
// The TestPolicy needs to implement two functions:
332
// - perform the boost range version of the algorithm that returns
333
// a range_return<Container,return_type>::type
334
// template<range_return_value return_type, class Container>
335
// BOOST_DEDUCED_TYPENAME range_return<Container,return_type>::type
336
// test(Container& cont);
338
// - perform the reference std version of the algorithm that
339
// returns the standard iterator result
340
// template<class Container>
341
// BOOST_DEDUCED_TYPENAME range_iterator<Container>::type
342
// reference(Container& cont);
343
class range_return_test_driver
346
template< class Container,
348
void operator()(Container& cont, TestPolicy policy)
350
test_range_iter (cont, policy);
351
test_range<return_found,Container,TestPolicy> ()(cont, policy);
352
test_range<return_next,Container,TestPolicy> ()(cont, policy);
353
test_range<return_prior,Container,TestPolicy> ()(cont, policy);
354
test_range<return_begin_found,Container,TestPolicy>()(cont, policy);
355
test_range<return_begin_next,Container,TestPolicy> ()(cont, policy);
356
test_range<return_begin_prior,Container,TestPolicy>()(cont, policy);
357
test_range<return_found_end,Container,TestPolicy> ()(cont, policy);
358
test_range<return_next_end,Container,TestPolicy> ()(cont, policy);
359
test_range<return_prior_end,Container,TestPolicy> ()(cont, policy);
360
test_range<return_begin_end,Container,TestPolicy> ()(cont, policy);
364
template< class Container, class TestPolicy >
365
void test_range_iter(
370
typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
372
Container reference(cont);
373
Container test(cont);
375
iterator_t range_result = policy.test_iter(test);
376
iterator_t reference_it = policy.reference(reference);
378
check_results<return_found>::test(test, reference,
379
range_result, reference_it);
382
template< range_return_value result_type, class Container, class TestPolicy >
385
void operator()(Container& cont, TestPolicy policy)
387
typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
388
typedef BOOST_DEDUCED_TYPENAME range_return<Container, result_type>::type range_return_t;
389
typedef BOOST_DEDUCED_TYPENAME TestPolicy::template test_range<result_type> test_range_t;
391
Container reference(cont);
392
Container test_cont(cont);
394
test_range_t test_range_fn;
395
range_return_t range_result = test_range_fn(policy, test_cont);
396
iterator_t reference_it = policy.reference(reference);
398
check_results<result_type>::test(test_cont, reference,
399
range_result, reference_it);
406
#endif // include guard