forked from boostorg/range
Boost.RangeEx merged into Boost.Range
[SVN r60897]
This commit is contained in:
@@ -0,0 +1,405 @@
|
||||
// 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 check(
|
||||
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 check(
|
||||
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 check(
|
||||
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 check(
|
||||
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 check(
|
||||
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 check(
|
||||
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 check(
|
||||
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 check(
|
||||
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 check(
|
||||
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 check(
|
||||
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 check(
|
||||
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>::check(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);
|
||||
|
||||
range_return_t range_result = test_range_t()(policy, test_cont);
|
||||
iterator_t reference_it = policy.reference(reference);
|
||||
|
||||
check_results<result_type>::check(test_cont, reference,
|
||||
range_result, reference_it);
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // include guard
|
||||
Reference in New Issue
Block a user