trac 7376 - join iterator reference type.

This commit is contained in:
Neil Groves
2014-03-03 15:43:05 +00:00
parent ea6ca22e3f
commit c9b96f2c88
2 changed files with 109 additions and 0 deletions

View File

@ -9,6 +9,9 @@
// aschoedl contributed an improvement to the determination // aschoedl contributed an improvement to the determination
// of the Reference type parameter. // 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/ // For more information, see http://www.boost.org/libs/range/
// //
#ifndef BOOST_RANGE_DETAIL_JOIN_ITERATOR_HPP_INCLUDED #ifndef BOOST_RANGE_DETAIL_JOIN_ITERATOR_HPP_INCLUDED

View File

@ -8,7 +8,12 @@
// //
// For more information, see http://www.boost.org/libs/range/ // 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 <boost/range/join.hpp> #include <boost/range/join.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/test/test_tools.hpp> #include <boost/test/test_tools.hpp>
@ -274,6 +279,106 @@ namespace boost
boost::push_back(joined, join(v1, v2)); 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<derived_type1>::iterator,
std::vector<derived_type2>::iterator,
const base_type&,
const base_type&
> join_iterator_t;
std::vector<boost::int32_t> reference_output;
std::vector<derived_type1> x;
for (boost::int32_t i = 0; i < 10; ++i)
{
x.push_back(derived_type1(i));
reference_output.push_back(i * 2);
}
std::vector<derived_type2> 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<boost::int32_t> 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::join_test ) );
test->add( BOOST_TEST_CASE( &boost::test_join_iterator_reference_type_constness_ticket8483 ) ); 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; return test;
} }