From c9b96f2c882cee26f0b327e52888b8c9edc9a090 Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Mon, 3 Mar 2014 15:43:05 +0000 Subject: [PATCH] trac 7376 - join iterator reference type. --- include/boost/range/detail/join_iterator.hpp | 3 + test/join.cpp | 106 +++++++++++++++++++ 2 files changed, 109 insertions(+) diff --git a/include/boost/range/detail/join_iterator.hpp b/include/boost/range/detail/join_iterator.hpp index ea0dd20..1020ebf 100644 --- a/include/boost/range/detail/join_iterator.hpp +++ b/include/boost/range/detail/join_iterator.hpp @@ -9,6 +9,9 @@ // aschoedl contributed an improvement to the determination // of the Reference type parameter. // +// Leonid Gershanovich reported Trac ticket 7376 about the dereference operator +// requiring identical reference types due to using the ternary if. +// // For more information, see http://www.boost.org/libs/range/ // #ifndef BOOST_RANGE_DETAIL_JOIN_ITERATOR_HPP_INCLUDED diff --git a/test/join.cpp b/test/join.cpp index cff3f35..586f05c 100644 --- a/test/join.cpp +++ b/test/join.cpp @@ -8,7 +8,12 @@ // // For more information, see http://www.boost.org/libs/range/ // +// Credits: +// Trac 7376 - was raised by Leonid Gershanovich and his sample was used to +// make the test case to cover this condition. +// #include +#include #include #include @@ -274,6 +279,106 @@ namespace boost boost::push_back(joined, join(v1, v2)); } + namespace trac7376 + { + struct base_type + { + explicit base_type(boost::int32_t value) + : value(value) + { + } + + virtual boost::int32_t get() const = 0; + + boost::int32_t value; + }; + + struct derived_type1 + : base_type + { + derived_type1(boost::int32_t value) + : base_type(value) + { + } + + virtual boost::int32_t get() const + { + return value * 2; + } + }; + + struct derived_type2 + : base_type + { + derived_type2(boost::int32_t value) + : base_type(value) + { + } + + virtual boost::int32_t get() const + { + return value * 4; + } + }; + + struct apply_get + { + typedef boost::int32_t result_type; + result_type operator()(const base_type& arg) const + { + return arg.get(); + } + }; + + void test_reference_types() + { + using namespace boost::adaptors; + + typedef boost::range_detail::join_iterator< + std::vector::iterator, + std::vector::iterator, + const base_type&, + const base_type& + > join_iterator_t; + + std::vector reference_output; + + std::vector x; + for (boost::int32_t i = 0; i < 10; ++i) + { + x.push_back(derived_type1(i)); + reference_output.push_back(i * 2); + } + + std::vector y; + for (boost::int32_t i = 0; i < 10; ++i) + { + y.push_back(derived_type2(i)); + reference_output.push_back(i * 4); + } + + join_iterator_t it( + x, + y, + boost::range_detail::join_iterator_begin_tag()); + + std::vector output; + boost::push_back( + output, + boost::make_iterator_range( + join_iterator_t( + x, y, + boost::range_detail::join_iterator_begin_tag()), + join_iterator_t( + x, y, + boost::range_detail::join_iterator_end_tag())) + | transformed(apply_get())); + + BOOST_CHECK_EQUAL_COLLECTIONS( + output.begin(), output.end(), + reference_output.begin(), reference_output.end()); + } + } // namespace trac7376 } } @@ -285,6 +390,7 @@ init_unit_test_suite(int argc, char* argv[]) test->add( BOOST_TEST_CASE( &boost::join_test ) ); test->add( BOOST_TEST_CASE( &boost::test_join_iterator_reference_type_constness_ticket8483 ) ); + test->add( BOOST_TEST_CASE( &boost::trac7376::test_reference_types ) ); return test; }