// Boost.Range library // // Copyright Neil Groves 2014. 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/ // #include #include #include #include #include #include #include #include #include #include #include "../test_utils.hpp" namespace boost_range_test { namespace { template void check_result( const Container& reference_range, const AdaptedRange& adapted_range, std::ptrdiff_t start_index ) { typedef typename boost::range_iterator::type reference_iterator; typedef typename boost::range_iterator::type adapted_iterator; BOOST_REQUIRE_EQUAL(boost::size(reference_range), boost::size(adapted_range)); reference_iterator reference_it = boost::begin(reference_range); adapted_iterator adapted_it = boost::begin(adapted_range); for (std::ptrdiff_t i = start_index; reference_it != boost::end(reference_range); ++reference_it, ++adapted_it, ++i) { BOOST_CHECK_EQUAL(i, adapted_it->index()); BOOST_CHECK_EQUAL(*reference_it, adapted_it->value()); } } template void indexed_test_impl(Container& c, std::ptrdiff_t start_index) { // This is my preferred syntax using the | operator. check_result(c, c | boost::adaptors::indexed(), 0); check_result(c, c | boost::adaptors::indexed(start_index), start_index); // This is the function syntax check_result(c, boost::adaptors::index(c), 0); check_result(c, boost::adaptors::index(c, start_index), start_index); } template void indexed_test_impl(Container& c) { indexed_test_impl(c, 0); indexed_test_impl(c, -1); indexed_test_impl(c, 4); } template void indexed_test_impl() { using namespace boost::assign; Container c; // test empty container indexed_test_impl(c); // test one element c += 1; indexed_test_impl(c); // test many elements c += 1,2,2,2,3,4,4,4,4,5,6,7,8,9,9; indexed_test_impl(c); } template void check_traversal(const Range& rng) { BOOST_STATIC_ASSERT( boost::is_convertible< typename boost::range_traversal::type, Traversal >::value); } template void check_not_traversal(const Range& rng) { BOOST_STATIC_ASSERT( !boost::is_convertible< typename boost::range_traversal::type, Traversal >::value); } void indexed_test() { indexed_test_impl< std::vector< int > >(); indexed_test_impl< std::list< int > >(); std::vector vi; check_traversal( vi | boost::adaptors::indexed()); std::list li; check_traversal( li | boost::adaptors::indexed()); check_not_traversal( li | boost::adaptors::indexed()); check_not_traversal( li | boost::adaptors::indexed()); } } // anonymous namesapce } // namespace boost_range_test boost::unit_test::test_suite* init_unit_test_suite(int, char*[]) { boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Boost.Range indexed adaptor test suite" ); test->add(BOOST_TEST_CASE(&boost_range_test::indexed_test)); return test; }