diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 09a29d5..a7b479a 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -50,6 +50,14 @@ test-suite range : [ range-test adaptor_test/tokenized ] [ range-test adaptor_test/transformed ] [ range-test adaptor_test/type_erased ] + [ range-test adaptor_test/type_erased_abstract ] + [ range-test adaptor_test/type_erased_brackets ] + [ range-test adaptor_test/type_erased_mix_values ] + [ range-test adaptor_test/type_erased_tparam_conv ] + [ range-test adaptor_test/type_erased_single_pass ] + [ range-test adaptor_test/type_erased_forward ] + [ range-test adaptor_test/type_erased_bidirectional ] + [ range-test adaptor_test/type_erased_random_access ] [ range-test adaptor_test/uniqued ] [ range-test adaptor_test/adjacent_filtered_example ] [ range-test adaptor_test/copied_example ] diff --git a/test/adaptor_test/type_erased.cpp b/test/adaptor_test/type_erased.cpp index ad5d600..edea1c4 100644 --- a/test/adaptor_test/type_erased.cpp +++ b/test/adaptor_test/type_erased.cpp @@ -6,547 +6,39 @@ // http://www.boost.org/LICENSE_1_0.txt) // #include +#include "type_erased_test.hpp" -#include #include -#include -#include -#include -#include -#include -#include - -#include #include -#include #include namespace boost_range_adaptor_type_erased_test { - class MockType + namespace { - public: - MockType() - : m_x(0) - { - } - MockType(boost::int32_t x) - : m_x(x) - { - } +void test_type_erased() +{ + test_driver< std::list >(); + test_driver< std::vector >(); - boost::int32_t get() const { return m_x; } - - inline bool operator==(const MockType& other) const - { - return m_x == other.m_x; - } - - inline bool operator!=(const MockType& other) const - { - return m_x != other.m_x; - } - - private: - boost::int32_t m_x; - }; - - class MockType2 : public MockType - { - public: - MockType2() {} - MockType2(boost::int32_t x) : MockType(x) { } - MockType2(const MockType& other) : MockType(other) { } - }; - - inline std::ostream& operator<<(std::ostream& out, const MockType& obj) - { - out << obj.get(); - return out; - } - - template - void test_type_erased_impl(Container& c) - { - using namespace boost::adaptors; - typedef typename boost::range_value::type value_type; - typedef typename boost::adaptors::type_erased<> type_erased_t; - - - std::vector output; - - boost::push_back(output, boost::adaptors::type_erase(c, type_erased_t())); - - BOOST_CHECK_EQUAL_COLLECTIONS( output.begin(), output.end(), - c.begin(), c.end() ); - - output.clear(); - boost::push_back(output, c | type_erased_t()); - - BOOST_CHECK_EQUAL_COLLECTIONS( output.begin(), output.end(), - c.begin(), c.end() ); - } - - template - void test_const_and_mutable(Container& c) - { - test_type_erased_impl(c); - - const Container& const_c = c; - test_type_erased_impl(const_c); - } - - template - void test_driver() - { - using namespace boost::assign; - - typedef typename boost::range_value::type value_type; - - Container c; - test_const_and_mutable(c); - - c += value_type(1); - test_const_and_mutable(c); - - c += value_type(2); - test_const_and_mutable(c); - } - - void test_type_erased() - { - test_driver< std::list >(); - test_driver< std::vector >(); - - test_driver< std::list >(); - test_driver< std::vector >(); - } - - template< - class Traversal - , class Container - > - void test_writeable(Container&, boost::single_pass_traversal_tag) - {} - - template< - class Traversal - , class Container - > - void test_writeable(Container& source, boost::forward_traversal_tag) - { - using namespace boost::adaptors; - - typedef typename boost::range_value::type value_type; - typedef typename boost::range_difference::type difference_type; - typedef typename boost::range_reference::type mutable_reference_type; - typedef boost::any_range< - value_type - , Traversal - , mutable_reference_type - , difference_type - > mutable_any_range; - - mutable_any_range r = source | boost::adaptors::type_erased<>(); - std::vector output_test; - boost::fill(r, value_type(1)); - BOOST_CHECK_EQUAL( boost::distance(r), boost::distance(source) ); - std::vector reference_output(source.size(), value_type(1)); - BOOST_CHECK_EQUAL_COLLECTIONS( reference_output.begin(), reference_output.end(), - r.begin(), r.end() ); - - } - - template< - class Container - , class Traversal - , class Buffer - > - void test_type_erased_impl() - { - using namespace boost::adaptors; - - typedef typename boost::range_value::type value_type; - - typedef typename boost::any_range_type_generator< - Container - , boost::use_default - , Traversal - , boost::use_default - , boost::use_default - , Buffer - >::type mutable_any_range; - - typedef typename boost::any_range_type_generator< - const Container - , boost::use_default - , Traversal - , boost::use_default - , boost::use_default - , Buffer - >::type const_any_range; - - typedef boost::adaptors::type_erased< - boost::use_default - , Traversal - , boost::use_default - , boost::use_default - , Buffer - > type_erased_t; - - Container source; - for (int i = 0; i < 10; ++i) - source.push_back(value_type(i)); - - mutable_any_range r(source); - BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(), - r.begin(), r.end() ); - - r = mutable_any_range(); - BOOST_CHECK_EQUAL( r.empty(), true ); - - r = source | type_erased_t(); - BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(), - r.begin(), r.end() ); - r = mutable_any_range(); - - r = boost::adaptors::type_erase(source, type_erased_t()); - BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(), - r.begin(), r.end() ); - r = mutable_any_range(); - - test_writeable(source, Traversal()); - - // convert and construct a const any_range from a mutable source - // range - const_any_range cr(source); - BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(), - cr.begin(), cr.end() ); - // assign an empty range and ensure that this correctly results - // in an empty range. This is important for the validity of - // the rest of the tests. - cr = const_any_range(); - BOOST_CHECK_EQUAL( cr.empty(), true ); - - // Test the pipe type_erased adaptor from a constant source - // range to a constant any_range - const Container& const_source = source; - cr = const_any_range(); - cr = const_source | type_erased_t(); - BOOST_CHECK_EQUAL_COLLECTIONS( const_source.begin(), const_source.end(), - cr.begin(), cr.end() ); - - // Test the pipe type erased adaptor from a mutable source - // range to a constant any_range - cr = const_any_range(); - cr = source | type_erased_t(); - BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(), - cr.begin(), cr.end() ); - - // Use the function form of the type_erase adaptor from a constant - // source range - cr = const_any_range(); - cr = boost::adaptors::type_erase(const_source, type_erased_t()); - BOOST_CHECK_EQUAL_COLLECTIONS( const_source.begin(), const_source.end(), - cr.begin(), cr.end() ); - - // Assignment from mutable to const... - cr = const_any_range(); - cr = r; - BOOST_CHECK_EQUAL_COLLECTIONS( cr.begin(), cr.end(), - r.begin(), r.end() ); - - // Converting copy from mutable to const... - cr = const_any_range(); - cr = const_any_range(r); - BOOST_CHECK_EQUAL_COLLECTIONS( cr.begin(), cr.end(), - r.begin(), r.end() ); - } - - template< - class Container - , class Traversal - , class Buffer - > - class test_type_erased_impl_fn - { - public: - typedef void result_type; - void operator()() - { - test_type_erased_impl< Container, Traversal, Buffer >(); - } - }; - - template< - class Container - , class Traversal - > - void test_type_erased_exercise_buffer_types() - { - using boost::any_iterator_default_buffer; - using boost::any_iterator_buffer; - using boost::any_iterator_heap_only_buffer; - using boost::any_iterator_stack_only_buffer; - - test_type_erased_impl_fn< Container, Traversal, any_iterator_default_buffer >()(); - test_type_erased_impl_fn< Container, Traversal, any_iterator_heap_only_buffer >()(); - test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<1> >()(); - test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<2> >()(); - test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<32> >()(); - test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<64> >()(); - test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<128> >()(); - test_type_erased_impl_fn< Container, Traversal, any_iterator_stack_only_buffer<128> >()(); - } - - void test_type_erased_single_pass() - { - test_type_erased_exercise_buffer_types< std::list, boost::single_pass_traversal_tag >(); - test_type_erased_exercise_buffer_types< std::deque, boost::single_pass_traversal_tag >(); - test_type_erased_exercise_buffer_types< std::vector, boost::single_pass_traversal_tag >(); - - test_type_erased_exercise_buffer_types< std::list, boost::single_pass_traversal_tag >(); - test_type_erased_exercise_buffer_types< std::deque, boost::single_pass_traversal_tag >(); - test_type_erased_exercise_buffer_types< std::vector, boost::single_pass_traversal_tag >(); - } - - void test_type_erased_forward() - { - test_type_erased_exercise_buffer_types< std::list, boost::forward_traversal_tag >(); - test_type_erased_exercise_buffer_types< std::deque, boost::forward_traversal_tag >(); - test_type_erased_exercise_buffer_types< std::vector, boost::forward_traversal_tag >(); - - test_type_erased_exercise_buffer_types< std::list, boost::forward_traversal_tag >(); - test_type_erased_exercise_buffer_types< std::deque, boost::forward_traversal_tag >(); - test_type_erased_exercise_buffer_types< std::vector, boost::forward_traversal_tag >(); - } - - void test_type_erased_bidirectional() - { - test_type_erased_exercise_buffer_types< std::list, boost::bidirectional_traversal_tag >(); - test_type_erased_exercise_buffer_types< std::deque, boost::bidirectional_traversal_tag >(); - test_type_erased_exercise_buffer_types< std::vector, boost::bidirectional_traversal_tag >(); - - test_type_erased_exercise_buffer_types< std::list, boost::bidirectional_traversal_tag >(); - test_type_erased_exercise_buffer_types< std::deque, boost::bidirectional_traversal_tag >(); - test_type_erased_exercise_buffer_types< std::vector, boost::bidirectional_traversal_tag >(); - } - - void test_type_erased_random_access() - { - test_type_erased_exercise_buffer_types< std::deque, boost::random_access_traversal_tag >(); - test_type_erased_exercise_buffer_types< std::vector, boost::random_access_traversal_tag >(); - - test_type_erased_exercise_buffer_types< std::deque, boost::random_access_traversal_tag >(); - test_type_erased_exercise_buffer_types< std::vector, boost::random_access_traversal_tag >(); - } - - void test_type_erased_multiple_different_template_parameter_conversion() - { - typedef boost::any_range< - int - , boost::random_access_traversal_tag - , int& - , std::ptrdiff_t - > source_range_type; - - typedef boost::any_range< - int - , boost::single_pass_traversal_tag - , const int& - , std::ptrdiff_t - > target_range_type; - - source_range_type source; - - // Converting via construction - target_range_type t1(source); - - // Converting via assignment - target_range_type t2; - t2 = source; - - // Converting via construction to a type with a reference type - // that is a value - typedef boost::any_range< - int - , boost::single_pass_traversal_tag - , int - , std::ptrdiff_t - > target_range2_type; - - target_range2_type t3(source); - target_range2_type t4; - t4 = source; - } - - template< - class Traversal - , class ValueType - , class SourceValueType - , class SourceReference - , class TargetValueType - , class TargetReference - > - void test_type_erased_mix_values_impl() - { - typedef std::vector< ValueType > Container; - - typedef typename boost::any_range_type_generator< - Container - , SourceValueType - , Traversal - , SourceReference - >::type source_type; - - typedef typename boost::any_range_type_generator< - Container - , TargetValueType - , Traversal - , TargetReference - >::type target_type; - - Container test_data; - for (int i = 0; i < 10; ++i) - test_data.push_back(i); - - const source_type source_data(test_data); - target_type t1(source_data); - BOOST_CHECK_EQUAL_COLLECTIONS( source_data.begin(), source_data.end(), - t1.begin(), t1.end() ); - - target_type t2; - t2 = source_data; - BOOST_CHECK_EQUAL_COLLECTIONS( source_data.begin(), source_data.end(), - t2.begin(), t2.end() ); - } - - template - void test_type_erased_mix_values_driver() - { - test_type_erased_mix_values_impl< - Traversal, - MockType, - MockType2, const MockType&, - MockType, const MockType& - >(); - } - - void test_type_erased_mix_values() - { - test_type_erased_mix_values_driver< boost::single_pass_traversal_tag >(); - test_type_erased_mix_values_driver< boost::forward_traversal_tag >(); - test_type_erased_mix_values_driver< boost::bidirectional_traversal_tag >(); - test_type_erased_mix_values_driver< boost::random_access_traversal_tag >(); - } - - void test_type_erased_operator_brackets() - { - typedef boost::adaptors::type_erased<> type_erased_t; - - std::vector c; - for (int i = 0; i < 10; ++i) - c.push_back(i); - - typedef boost::any_range_type_generator< - std::vector >::type any_range_type; - - BOOST_STATIC_ASSERT(( - boost::is_same< - int, - boost::range_value::type - >::value - )); - - BOOST_STATIC_ASSERT(( - boost::is_same< - boost::random_access_traversal_tag, - boost::iterator_traversal< - boost::range_iterator::type - >::type - >::value - )); - - any_range_type rng = c | type_erased_t(); - - for (int i = 0; i < 10; ++i) - { - BOOST_CHECK_EQUAL( rng[i], i ); - } - } - - class dummy_interface - { - public: - virtual ~dummy_interface() { } - virtual void test() = 0; - protected: - dummy_interface() { } - private: - dummy_interface(const dummy_interface&); - void operator=(const dummy_interface&); - }; - - class dummy_impl - : public dummy_interface - { - public: - dummy_impl() { } - dummy_impl(const dummy_impl&) { } - dummy_impl& operator=(const dummy_impl&) { return *this; } - virtual void test() { } - }; - - typedef boost::any_range< - dummy_interface, - boost::random_access_traversal_tag, - dummy_interface&, - std::ptrdiff_t - > any_interface_range; - - struct foo_dummy_interface_fn - { - void operator()(dummy_interface& iface) - { - iface.test(); - } - }; - - void foo_test_dummy_interface_range(any_interface_range rng) - { - std::for_each(boost::begin(rng), boost::end(rng), - foo_dummy_interface_fn()); - } - - void test_type_erased_abstract() - { - std::vector v(10); - - any_interface_range r(v); - - foo_test_dummy_interface_range(r); - - foo_test_dummy_interface_range(any_interface_range(v)); - } + test_driver< std::list >(); + test_driver< std::vector >(); } + } // anonymous namespace +} // namespace boost_range_adaptor_type_erased_test + boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) { - boost::unit_test::test_suite* test - = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.type_erased" ); + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased"); - test->add( BOOST_TEST_CASE( &boost_range_adaptor_type_erased_test::test_type_erased ) ); - test->add( BOOST_TEST_CASE( &boost_range_adaptor_type_erased_test::test_type_erased_single_pass ) ); - test->add( BOOST_TEST_CASE( &boost_range_adaptor_type_erased_test::test_type_erased_forward ) ); - test->add( BOOST_TEST_CASE( &boost_range_adaptor_type_erased_test::test_type_erased_bidirectional ) ); - test->add( BOOST_TEST_CASE( &boost_range_adaptor_type_erased_test::test_type_erased_random_access ) ); - test->add( BOOST_TEST_CASE( &boost_range_adaptor_type_erased_test::test_type_erased_multiple_different_template_parameter_conversion ) ); - test->add( BOOST_TEST_CASE( &boost_range_adaptor_type_erased_test::test_type_erased_mix_values ) ); - test->add( BOOST_TEST_CASE( &boost_range_adaptor_type_erased_test::test_type_erased_operator_brackets ) ); - test->add( BOOST_TEST_CASE( &boost_range_adaptor_type_erased_test::test_type_erased_abstract ) ); + test->add(BOOST_TEST_CASE( + &boost_range_adaptor_type_erased_test::test_type_erased)); return test; } + diff --git a/test/adaptor_test/type_erased_abstract.cpp b/test/adaptor_test/type_erased_abstract.cpp new file mode 100644 index 0000000..dd54890 --- /dev/null +++ b/test/adaptor_test/type_erased_abstract.cpp @@ -0,0 +1,88 @@ +// 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) +// +#include +#include "type_erased_test.hpp" + +#include + +#include + +namespace boost_range_adaptor_type_erased_test +{ + namespace + { + +class dummy_interface +{ +public: + virtual ~dummy_interface() { } + virtual void test() = 0; +protected: + dummy_interface() { } +private: + dummy_interface(const dummy_interface&); + void operator=(const dummy_interface&); +}; + +class dummy_impl + : public dummy_interface +{ +public: + dummy_impl() { } + dummy_impl(const dummy_impl&) { } + dummy_impl& operator=(const dummy_impl&) { return *this; } + virtual void test() { } +}; + +typedef boost::any_range< + dummy_interface, + boost::random_access_traversal_tag, + dummy_interface&, + std::ptrdiff_t +> any_interface_range; + +struct foo_dummy_interface_fn +{ + void operator()(dummy_interface& iface) + { + iface.test(); + } +}; + +void foo_test_dummy_interface_range(any_interface_range rng) +{ + std::for_each(boost::begin(rng), boost::end(rng), + foo_dummy_interface_fn()); +} + +void test_type_erased_abstract() +{ + std::vector v(10); + + any_interface_range r(v); + + foo_test_dummy_interface_range(r); + + foo_test_dummy_interface_range(any_interface_range(v)); +} + + } // anonymous namespace +} // namespace boost_range_adaptor_type_erased_test + +boost::unit_test::test_suite* +init_unit_test_suite(int, char*[]) +{ + boost::unit_test::test_suite* test + = BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_abstract"); + + test->add( + BOOST_TEST_CASE( + &boost_range_adaptor_type_erased_test::test_type_erased_abstract)); + + return test; +} diff --git a/test/adaptor_test/type_erased_bidirectional.cpp b/test/adaptor_test/type_erased_bidirectional.cpp new file mode 100644 index 0000000..3dc86fe --- /dev/null +++ b/test/adaptor_test/type_erased_bidirectional.cpp @@ -0,0 +1,57 @@ +// 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) +// +#include +#include "type_erased_test.hpp" + +#include + +#include +#include +#include + +namespace boost_range_adaptor_type_erased_test +{ + namespace + { + +void test_bidirectional() +{ + test_type_erased_exercise_buffer_types< + std::list, boost::bidirectional_traversal_tag >(); + + test_type_erased_exercise_buffer_types< + std::deque, boost::bidirectional_traversal_tag >(); + + test_type_erased_exercise_buffer_types< + std::vector, boost::bidirectional_traversal_tag >(); + + test_type_erased_exercise_buffer_types< + std::list, boost::bidirectional_traversal_tag >(); + + test_type_erased_exercise_buffer_types< + std::deque, boost::bidirectional_traversal_tag >(); + + test_type_erased_exercise_buffer_types< + std::vector, boost::bidirectional_traversal_tag >(); +} + + } // anonymous namespace +} // namespace boost_range_adaptor_type_erased_test + +boost::unit_test::test_suite* +init_unit_test_suite(int, char*[]) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_bidirectional"); + + test->add(BOOST_TEST_CASE( + &boost_range_adaptor_type_erased_test::test_bidirectional)); + + return test; +} + diff --git a/test/adaptor_test/type_erased_brackets.cpp b/test/adaptor_test/type_erased_brackets.cpp new file mode 100644 index 0000000..9d5c7dd --- /dev/null +++ b/test/adaptor_test/type_erased_brackets.cpp @@ -0,0 +1,70 @@ +// 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) +// +#include +#include "type_erased_test.hpp" + +#include + +#include + +namespace boost_range_adaptor_type_erased_test +{ + namespace + { + +void test_operator_brackets() +{ + typedef boost::adaptors::type_erased<> type_erased_t; + + std::vector c; + for (int i = 0; i < 10; ++i) + c.push_back(i); + + typedef boost::any_range_type_generator< + std::vector >::type any_range_type; + + BOOST_STATIC_ASSERT(( + boost::is_same< + int, + boost::range_value::type + >::value + )); + + BOOST_STATIC_ASSERT(( + boost::is_same< + boost::random_access_traversal_tag, + boost::iterator_traversal< + boost::range_iterator::type + >::type + >::value + )); + + any_range_type rng = c | type_erased_t(); + + for (int i = 0; i < 10; ++i) + { + BOOST_CHECK_EQUAL(rng[i], i); + } +} + + } // anonymous namespace +} // namespace boost_range_adaptor_type_erased_test + +boost::unit_test::test_suite* +init_unit_test_suite(int, char*[]) +{ + boost::unit_test::test_suite* test + = BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_brackets"); + + test->add( + BOOST_TEST_CASE( + &boost_range_adaptor_type_erased_test::test_operator_brackets)); + + return test; +} + diff --git a/test/adaptor_test/type_erased_forward.cpp b/test/adaptor_test/type_erased_forward.cpp new file mode 100644 index 0000000..7f6540f --- /dev/null +++ b/test/adaptor_test/type_erased_forward.cpp @@ -0,0 +1,57 @@ +// 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) +// +#include +#include "type_erased_test.hpp" + +#include + +#include +#include +#include + +namespace boost_range_adaptor_type_erased_test +{ + namespace + { + +void test_forward() +{ + test_type_erased_exercise_buffer_types< + std::list, boost::forward_traversal_tag >(); + + test_type_erased_exercise_buffer_types< + std::deque, boost::forward_traversal_tag >(); + + test_type_erased_exercise_buffer_types< + std::vector, boost::forward_traversal_tag >(); + + test_type_erased_exercise_buffer_types< + std::list, boost::forward_traversal_tag >(); + + test_type_erased_exercise_buffer_types< + std::deque, boost::forward_traversal_tag >(); + + test_type_erased_exercise_buffer_types< + std::vector, boost::forward_traversal_tag >(); +} + + } // anonymous namespace +} // namespace boost_range_adaptor_type_erased_test + +boost::unit_test::test_suite* +init_unit_test_suite(int, char*[]) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE( "RangeTestSuite.adaptor.type_erased_forward" ); + + test->add(BOOST_TEST_CASE( + &boost_range_adaptor_type_erased_test::test_forward)); + + return test; +} + diff --git a/test/adaptor_test/type_erased_mix_values.cpp b/test/adaptor_test/type_erased_mix_values.cpp new file mode 100644 index 0000000..e91644c --- /dev/null +++ b/test/adaptor_test/type_erased_mix_values.cpp @@ -0,0 +1,94 @@ +// 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) +// +#include +#include "type_erased_test.hpp" + +#include + +#include + +namespace boost_range_adaptor_type_erased_test +{ + namespace + { + +template< + class Traversal + , class ValueType + , class SourceValueType + , class SourceReference + , class TargetValueType + , class TargetReference +> +void mix_values_impl() +{ + typedef std::vector Container; + + typedef typename boost::any_range_type_generator< + Container + , SourceValueType + , Traversal + , SourceReference + >::type source_type; + + typedef typename boost::any_range_type_generator< + Container + , TargetValueType + , Traversal + , TargetReference + >::type target_type; + + Container test_data; + for (int i = 0; i < 10; ++i) + test_data.push_back(i); + + const source_type source_data(test_data); + target_type t1(source_data); + BOOST_CHECK_EQUAL_COLLECTIONS(source_data.begin(), source_data.end(), + t1.begin(), t1.end()); + + target_type t2; + t2 = source_data; + BOOST_CHECK_EQUAL_COLLECTIONS(source_data.begin(), source_data.end(), + t2.begin(), t2.end()); +} + +template +void mix_values_driver() +{ + mix_values_impl< + Traversal, + MockType, + MockType2, const MockType&, + MockType, const MockType& + >(); +} + +void mix_values() +{ + mix_values_driver(); + mix_values_driver(); + mix_values_driver(); + mix_values_driver(); +} + + } // anonymous namespace +} // namespace boost_range_adaptor_type_erased_test + +boost::unit_test::test_suite* +init_unit_test_suite(int, char*[]) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_mix_values"); + + test->add(BOOST_TEST_CASE( + &boost_range_adaptor_type_erased_test::mix_values)); + + return test; +} + diff --git a/test/adaptor_test/type_erased_random_access.cpp b/test/adaptor_test/type_erased_random_access.cpp new file mode 100644 index 0000000..39cf1c6 --- /dev/null +++ b/test/adaptor_test/type_erased_random_access.cpp @@ -0,0 +1,50 @@ +// 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) +// +#include +#include "type_erased_test.hpp" + +#include + +#include +#include + +namespace boost_range_adaptor_type_erased_test +{ + namespace + { + +void test_random_access() +{ + test_type_erased_exercise_buffer_types< + std::deque, boost::random_access_traversal_tag >(); + + test_type_erased_exercise_buffer_types< + std::vector, boost::random_access_traversal_tag >(); + + test_type_erased_exercise_buffer_types< + std::deque, boost::random_access_traversal_tag >(); + + test_type_erased_exercise_buffer_types< + std::vector, boost::random_access_traversal_tag >(); +} + + } // anonymous namespace +} // namespace boost_range_adaptor_type_erased_test + +boost::unit_test::test_suite* +init_unit_test_suite(int argc, char* argv[]) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_random_access"); + + test->add(BOOST_TEST_CASE( + &boost_range_adaptor_type_erased_test::test_random_access)); + + return test; +} + diff --git a/test/adaptor_test/type_erased_single_pass.cpp b/test/adaptor_test/type_erased_single_pass.cpp new file mode 100644 index 0000000..ad0c4ae --- /dev/null +++ b/test/adaptor_test/type_erased_single_pass.cpp @@ -0,0 +1,57 @@ +// Boost.Range library +// +// Copyright Neil Groves 2010. 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) +// +#include +#include "type_erased_test.hpp" + +#include + +#include +#include +#include + +namespace boost_range_adaptor_type_erased_test +{ + namespace + { + +void test_single_pass() +{ + test_type_erased_exercise_buffer_types< + std::list, boost::single_pass_traversal_tag>(); + + test_type_erased_exercise_buffer_types< + std::deque, boost::single_pass_traversal_tag>(); + + test_type_erased_exercise_buffer_types< + std::vector, boost::single_pass_traversal_tag>(); + + test_type_erased_exercise_buffer_types< + std::list, boost::single_pass_traversal_tag>(); + + test_type_erased_exercise_buffer_types< + std::deque, boost::single_pass_traversal_tag>(); + + test_type_erased_exercise_buffer_types< + std::vector, boost::single_pass_traversal_tag>(); +} + + } // anonymous namespace +} // namespace boost_range_adaptor_type_erased_test + +boost::unit_test::test_suite* +init_unit_test_suite(int argc, char* argv[]) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_single_pass"); + + test->add(BOOST_TEST_CASE( + &boost_range_adaptor_type_erased_test::test_single_pass)); + + return test; +} + diff --git a/test/adaptor_test/type_erased_test.hpp b/test/adaptor_test/type_erased_test.hpp new file mode 100644 index 0000000..9a42e81 --- /dev/null +++ b/test/adaptor_test/type_erased_test.hpp @@ -0,0 +1,289 @@ +// Boost.Range library +// +// Copyright Neil Groves 2010. 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) +// +#ifndef BOOST_RANGE_ADAPTOR_TEST_TYPE_ERASED_TEST_HPP +#define BOOST_RANGE_ADAPTOR_TEST_TYPE_ERASED_TEST_HPP + +#include +#include +#include +#include + +namespace boost_range_adaptor_type_erased_test +{ + +class MockType +{ +public: + MockType() + : m_x(0) + { + } + + MockType(boost::int32_t x) + : m_x(x) + { + } + + boost::int32_t get() const { return m_x; } + + inline bool operator==(const MockType& other) const + { + return m_x == other.m_x; + } + + inline bool operator!=(const MockType& other) const + { + return m_x != other.m_x; + } + +private: + boost::int32_t m_x; +}; + +class MockType2 : public MockType +{ +public: + MockType2() {} + MockType2(boost::int32_t x) : MockType(x) { } + MockType2(const MockType& other) : MockType(other) { } +}; + +inline std::ostream& operator<<(std::ostream& out, const MockType& obj) +{ + out << obj.get(); + return out; +} + +template +void test_type_erased_impl(Container& c) +{ + using namespace boost::adaptors; + typedef typename boost::range_value::type value_type; + typedef typename boost::adaptors::type_erased<> type_erased_t; + + + std::vector output; + + boost::push_back(output, boost::adaptors::type_erase(c, type_erased_t())); + + BOOST_CHECK_EQUAL_COLLECTIONS( output.begin(), output.end(), + c.begin(), c.end() ); + + output.clear(); + boost::push_back(output, c | type_erased_t()); + + BOOST_CHECK_EQUAL_COLLECTIONS( output.begin(), output.end(), + c.begin(), c.end() ); +} + +template +void test_const_and_mutable(Container& c) +{ + test_type_erased_impl(c); + + const Container& const_c = c; + test_type_erased_impl(const_c); +} + +template +void test_driver() +{ + using namespace boost::assign; + + typedef typename boost::range_value::type value_type; + + Container c; + test_const_and_mutable(c); + + c += value_type(1); + test_const_and_mutable(c); + + c += value_type(2); + test_const_and_mutable(c); +} + +template< + class Traversal + , class Container +> +void test_writeable(Container&, boost::single_pass_traversal_tag) +{} + +template< + class Traversal + , class Container +> +void test_writeable(Container& source, boost::forward_traversal_tag) +{ + using namespace boost::adaptors; + + typedef typename boost::range_value::type value_type; + typedef typename boost::range_difference::type difference_type; + typedef typename boost::range_reference::type mutable_reference_type; + typedef boost::any_range< + value_type + , Traversal + , mutable_reference_type + , difference_type + > mutable_any_range; + + mutable_any_range r = source | boost::adaptors::type_erased<>(); + std::vector output_test; + boost::fill(r, value_type(1)); + BOOST_CHECK_EQUAL( boost::distance(r), boost::distance(source) ); + std::vector reference_output(source.size(), value_type(1)); + BOOST_CHECK_EQUAL_COLLECTIONS( reference_output.begin(), reference_output.end(), + r.begin(), r.end() ); + +} + +template< + class Container + , class Traversal + , class Buffer +> +void test_type_erased_impl() +{ + using namespace boost::adaptors; + + typedef typename boost::range_value::type value_type; + + typedef typename boost::any_range_type_generator< + Container + , boost::use_default + , Traversal + , boost::use_default + , boost::use_default + , Buffer + >::type mutable_any_range; + + typedef typename boost::any_range_type_generator< + const Container + , boost::use_default + , Traversal + , boost::use_default + , boost::use_default + , Buffer + >::type const_any_range; + + typedef boost::adaptors::type_erased< + boost::use_default + , Traversal + , boost::use_default + , boost::use_default + , Buffer + > type_erased_t; + + Container source; + for (int i = 0; i < 10; ++i) + source.push_back(value_type(i)); + + mutable_any_range r(source); + BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(), + r.begin(), r.end() ); + + r = mutable_any_range(); + BOOST_CHECK_EQUAL( r.empty(), true ); + + r = source | type_erased_t(); + BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(), + r.begin(), r.end() ); + r = mutable_any_range(); + + r = boost::adaptors::type_erase(source, type_erased_t()); + BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(), + r.begin(), r.end() ); + r = mutable_any_range(); + + test_writeable(source, Traversal()); + + // convert and construct a const any_range from a mutable source + // range + const_any_range cr(source); + BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(), + cr.begin(), cr.end() ); + // assign an empty range and ensure that this correctly results + // in an empty range. This is important for the validity of + // the rest of the tests. + cr = const_any_range(); + BOOST_CHECK_EQUAL( cr.empty(), true ); + + // Test the pipe type_erased adaptor from a constant source + // range to a constant any_range + const Container& const_source = source; + cr = const_any_range(); + cr = const_source | type_erased_t(); + BOOST_CHECK_EQUAL_COLLECTIONS( const_source.begin(), const_source.end(), + cr.begin(), cr.end() ); + + // Test the pipe type erased adaptor from a mutable source + // range to a constant any_range + cr = const_any_range(); + cr = source | type_erased_t(); + BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(), + cr.begin(), cr.end() ); + + // Use the function form of the type_erase adaptor from a constant + // source range + cr = const_any_range(); + cr = boost::adaptors::type_erase(const_source, type_erased_t()); + BOOST_CHECK_EQUAL_COLLECTIONS( const_source.begin(), const_source.end(), + cr.begin(), cr.end() ); + + // Assignment from mutable to const... + cr = const_any_range(); + cr = r; + BOOST_CHECK_EQUAL_COLLECTIONS( cr.begin(), cr.end(), + r.begin(), r.end() ); + + // Converting copy from mutable to const... + cr = const_any_range(); + cr = const_any_range(r); + BOOST_CHECK_EQUAL_COLLECTIONS( cr.begin(), cr.end(), + r.begin(), r.end() ); +} + +template< + class Container + , class Traversal + , class Buffer +> +class test_type_erased_impl_fn +{ +public: + typedef void result_type; + void operator()() + { + test_type_erased_impl< Container, Traversal, Buffer >(); + } +}; + +template< + class Container + , class Traversal +> +void test_type_erased_exercise_buffer_types() +{ + using boost::any_iterator_default_buffer; + using boost::any_iterator_buffer; + using boost::any_iterator_heap_only_buffer; + using boost::any_iterator_stack_only_buffer; + + test_type_erased_impl_fn< Container, Traversal, any_iterator_default_buffer >()(); + test_type_erased_impl_fn< Container, Traversal, any_iterator_heap_only_buffer >()(); + test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<1> >()(); + test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<2> >()(); + test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<32> >()(); + test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<64> >()(); + test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<128> >()(); + test_type_erased_impl_fn< Container, Traversal, any_iterator_stack_only_buffer<128> >()(); +} + +} // namespace boost_range_adaptor_type_erased_test + +#endif // include guard diff --git a/test/adaptor_test/type_erased_tparam_conv.cpp b/test/adaptor_test/type_erased_tparam_conv.cpp new file mode 100644 index 0000000..e235ab3 --- /dev/null +++ b/test/adaptor_test/type_erased_tparam_conv.cpp @@ -0,0 +1,74 @@ +// 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) +// +#include +#include "type_erased_test.hpp" + +#include + +#include +#include + +namespace boost_range_adaptor_type_erased_test +{ + namespace + { + +void template_parameter_conversion() +{ + typedef boost::any_range< + int + , boost::random_access_traversal_tag + , int& + , std::ptrdiff_t + > source_range_type; + + typedef boost::any_range< + int + , boost::single_pass_traversal_tag + , const int& + , std::ptrdiff_t + > target_range_type; + + source_range_type source; + + // Converting via construction + target_range_type t1(source); + + // Converting via assignment + target_range_type t2; + t2 = source; + + // Converting via construction to a type with a reference type + // that is a value + typedef boost::any_range< + int + , boost::single_pass_traversal_tag + , int + , std::ptrdiff_t + > target_range2_type; + + target_range2_type t3(source); + target_range2_type t4; + t4 = source; +} + + } // anonymous namespace +} // namespace boost_range_adaptor_type_erased_test + +boost::unit_test::test_suite* +init_unit_test_suite(int argc, char* argv[]) +{ + boost::unit_test::test_suite* test = + BOOST_TEST_SUITE("RangeTestSuite.adaptor.type_erased_tparam_conv"); + + test->add(BOOST_TEST_CASE( + &boost_range_adaptor_type_erased_test::template_parameter_conversion)); + + return test; +} +