123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406 |
- // Copyright Neil Groves 2009. Use, modification and
- // distribution is subject to the Boost Software License, Version
- // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- //
- //
- // For more information, see http://www.boost.org/libs/range/
- //
- #ifndef BOOST_RANGE_TEST_TEST_DRIVER_RANGE_RETURN_TEST_DRIVER_HPP_INCLUDED
- #define BOOST_RANGE_TEST_TEST_DRIVER_RANGE_RETURN_TEST_DRIVER_HPP_INCLUDED
- #include <boost/assert.hpp>
- #include <boost/test/test_tools.hpp>
- #include <boost/test/unit_test.hpp>
- namespace boost
- {
- namespace range_test
- {
- // check the results of an algorithm that returns
- // a range_return.
- //
- // This version is the general version. It should never be called.
- // All calls should invoke specialized implementations.
- template< range_return_value return_type >
- struct check_results
- {
- template< class Container, class Iterator >
- static void test(
- Container& test,
- Container& reference,
- Iterator test_it,
- Iterator reference_it
- )
- {
- BOOST_ASSERT( false );
- }
- };
- // check the results of an algorithm that returns
- // a 'found' iterator
- template< >
- struct check_results<return_found>
- {
- template< class Container, class Iterator >
- static void test(
- Container& test,
- Container& reference,
- Iterator test_it,
- Iterator reference_it
- )
- {
- BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
- test.begin(), test.end() );
- BOOST_CHECK_EQUAL( std::distance(test.begin(), test_it),
- std::distance(reference.begin(), reference_it) );
- }
- };
- // check the results of an algorithm that returns
- // a 'next(found)' iterator
- template< >
- struct check_results<return_next>
- {
- template< class Container, class Iterator >
- static void test(
- Container& test,
- Container& reference,
- Iterator test_it,
- Iterator reference_it
- )
- {
- BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
- test.begin(), test.end() );
- if (reference_it == reference.end())
- {
- BOOST_CHECK( test_it == test.end() );
- }
- else
- {
- BOOST_CHECK_EQUAL(
- std::distance(test.begin(), test_it),
- std::distance(reference.begin(), reference_it) + 1);
- }
- }
- };
- // check the results of an algorithm that returns
- // a 'prior(found)' iterator
- template< >
- struct check_results<return_prior>
- {
- template< class Container, class Iterator >
- static void test(
- Container& test,
- Container& reference,
- Iterator test_it,
- Iterator reference_it
- )
- {
- BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
- test.begin(), test.end() );
- if (reference_it == reference.begin())
- {
- BOOST_CHECK( test_it == test.begin() );
- }
- else
- {
- BOOST_CHECK_EQUAL(
- std::distance(test.begin(), test_it) + 1,
- std::distance(reference.begin(), reference_it));
- }
- }
- };
- // check the results of an algorithm that returns
- // a '[begin, found)' range
- template< >
- struct check_results<return_begin_found>
- {
- template< class Container, class Iterator >
- static void test(
- Container& test,
- Container& reference,
- iterator_range<Iterator> test_rng,
- Iterator reference_it
- )
- {
- BOOST_CHECK_EQUAL_COLLECTIONS(
- reference.begin(), reference.end(),
- test.begin(), test.end()
- );
- BOOST_CHECK( test_rng.begin() == test.begin() );
- BOOST_CHECK_EQUAL_COLLECTIONS(
- reference.begin(), reference_it,
- boost::begin(test_rng), boost::end(test_rng)
- );
- }
- };
- // check the results of an algorithm that returns
- // a '[begin, next(found))' range
- template< >
- struct check_results<return_begin_next>
- {
- template< class Container, class Iterator >
- static void test(
- Container& test,
- Container& reference,
- iterator_range<Iterator> test_rng,
- Iterator reference_it
- )
- {
- BOOST_CHECK_EQUAL_COLLECTIONS(
- reference.begin(), reference.end(),
- test.begin(), test.end()
- );
- BOOST_CHECK( test_rng.begin() == test.begin() );
- if (reference_it == reference.end())
- {
- BOOST_CHECK( test_rng.end() == test.end() );
- }
- else
- {
- BOOST_CHECK_EQUAL_COLLECTIONS(
- reference.begin(), boost::next(reference_it),
- test_rng.begin(), test_rng.end());
- }
- }
- };
- // check the results of an algorithm that returns
- // a '[begin, prior(found))' range
- template< >
- struct check_results<return_begin_prior>
- {
- template< class Container, class Iterator >
- static void test(
- Container& test,
- Container& reference,
- iterator_range<Iterator> test_rng,
- Iterator reference_it
- )
- {
- BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
- test.begin(), test.end() );
- BOOST_CHECK( test_rng.begin() == test.begin() );
- if (reference_it == reference.begin())
- {
- BOOST_CHECK( boost::end(test_rng) == test.begin() );
- }
- else
- {
- BOOST_CHECK_EQUAL( std::distance(boost::begin(test_rng), boost::end(test_rng)) + 1,
- std::distance(reference.begin(), reference_it) );
- }
- }
- };
- // check the results of an algorithm that returns
- // a '[found, end)' range
- template< >
- struct check_results<return_found_end>
- {
- template< class Container, class Iterator >
- static void test(
- Container& test,
- Container& reference,
- iterator_range<Iterator> test_rng,
- Iterator reference_it
- )
- {
- BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
- test.begin(), test.end() );
- BOOST_CHECK_EQUAL(
- std::distance(test.begin(), boost::begin(test_rng)),
- std::distance(reference.begin(), reference_it));
- BOOST_CHECK( boost::end(test_rng) == test.end() );
- }
- };
- // check the results of an algorithm that returns
- // a '[next(found), end)' range
- template< >
- struct check_results<return_next_end>
- {
- template< class Container, class Iterator >
- static void test(
- Container& test,
- Container& reference,
- iterator_range<Iterator> test_rng,
- Iterator reference_it
- )
- {
- BOOST_CHECK_EQUAL_COLLECTIONS(
- reference.begin(), reference.end(),
- test.begin(), test.end()
- );
- BOOST_CHECK( test_rng.end() == test.end() );
- if (reference_it == reference.end())
- {
- BOOST_CHECK( test_rng.begin() == test.end() );
- }
- else
- {
- BOOST_CHECK_EQUAL_COLLECTIONS(
- boost::next(reference_it), reference.end(),
- test_rng.begin(), test_rng.end()
- );
- }
- }
- };
- // check the results of an algorithm that returns
- // a 'prior(found), end)' range
- template< >
- struct check_results<return_prior_end>
- {
- template< class Container, class Iterator >
- static void test(
- Container& test,
- Container& reference,
- iterator_range<Iterator> test_rng,
- Iterator reference_it
- )
- {
- BOOST_CHECK_EQUAL_COLLECTIONS(
- reference.begin(), reference.end(),
- test.begin(), test.end()
- );
- BOOST_CHECK( test_rng.end() == test.end() );
- if (reference_it == reference.begin())
- {
- BOOST_CHECK( test_rng.begin() == test.begin() );
- }
- else
- {
- BOOST_CHECK_EQUAL_COLLECTIONS(
- boost::prior(reference_it), reference.end(),
- test_rng.begin(), test_rng.end()
- );
- }
- }
- };
- // check the results of an algorithm that returns
- // a '[begin, end)' range
- template< >
- struct check_results<return_begin_end>
- {
- template< class Container, class Iterator >
- static void test(
- Container& test,
- Container& reference,
- iterator_range<Iterator> test_rng,
- Iterator reference_it
- )
- {
- BOOST_CHECK_EQUAL_COLLECTIONS(
- reference.begin(), reference.end(),
- test.begin(), test.end()
- );
- BOOST_CHECK( test_rng.begin() == test.begin() );
- BOOST_CHECK( test_rng.end() == test.end() );
- }
- };
- // A test driver to exercise a test through all of the range_return
- // combinations.
- //
- // The test driver also contains the code required to check the
- // return value correctness.
- //
- // The TestPolicy needs to implement two functions:
- //
- // - perform the boost range version of the algorithm that returns
- // a range_return<Container,return_type>::type
- // template<range_return_value return_type, class Container>
- // BOOST_DEDUCED_TYPENAME range_return<Container,return_type>::type
- // test(Container& cont);
- //
- // - perform the reference std version of the algorithm that
- // returns the standard iterator result
- // template<class Container>
- // BOOST_DEDUCED_TYPENAME range_iterator<Container>::type
- // reference(Container& cont);
- class range_return_test_driver
- {
- public:
- template< class Container,
- class TestPolicy >
- void operator()(Container& cont, TestPolicy policy)
- {
- test_range_iter (cont, policy);
- test_range<return_found,Container,TestPolicy> ()(cont, policy);
- test_range<return_next,Container,TestPolicy> ()(cont, policy);
- test_range<return_prior,Container,TestPolicy> ()(cont, policy);
- test_range<return_begin_found,Container,TestPolicy>()(cont, policy);
- test_range<return_begin_next,Container,TestPolicy> ()(cont, policy);
- test_range<return_begin_prior,Container,TestPolicy>()(cont, policy);
- test_range<return_found_end,Container,TestPolicy> ()(cont, policy);
- test_range<return_next_end,Container,TestPolicy> ()(cont, policy);
- test_range<return_prior_end,Container,TestPolicy> ()(cont, policy);
- test_range<return_begin_end,Container,TestPolicy> ()(cont, policy);
- }
- private:
- template< class Container, class TestPolicy >
- void test_range_iter(
- Container& cont,
- TestPolicy policy
- )
- {
- typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
- Container reference(cont);
- Container test(cont);
- iterator_t range_result = policy.test_iter(test);
- iterator_t reference_it = policy.reference(reference);
- check_results<return_found>::test(test, reference,
- range_result, reference_it);
- }
- template< range_return_value result_type, class Container, class TestPolicy >
- struct test_range
- {
- void operator()(Container& cont, TestPolicy policy)
- {
- typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
- typedef BOOST_DEDUCED_TYPENAME range_return<Container, result_type>::type range_return_t;
- typedef BOOST_DEDUCED_TYPENAME TestPolicy::template test_range<result_type> test_range_t;
- Container reference(cont);
- Container test_cont(cont);
- test_range_t test_range_fn;
- range_return_t range_result = test_range_fn(policy, test_cont);
- iterator_t reference_it = policy.reference(reference);
- check_results<result_type>::test(test_cont, reference,
- range_result, reference_it);
- }
- };
- };
- }
- }
- #endif // include guard
|