mirror of
https://github.com/boostorg/range.git
synced 2025-07-30 12:57:28 +02:00
Merge branch 'hotfix/type_erased_test_split' into develop
This commit is contained in:
@ -50,6 +50,14 @@ test-suite range :
|
|||||||
[ range-test adaptor_test/tokenized ]
|
[ range-test adaptor_test/tokenized ]
|
||||||
[ range-test adaptor_test/transformed ]
|
[ range-test adaptor_test/transformed ]
|
||||||
[ range-test adaptor_test/type_erased ]
|
[ 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/uniqued ]
|
||||||
[ range-test adaptor_test/adjacent_filtered_example ]
|
[ range-test adaptor_test/adjacent_filtered_example ]
|
||||||
[ range-test adaptor_test/copied_example ]
|
[ range-test adaptor_test/copied_example ]
|
||||||
|
@ -6,547 +6,39 @@
|
|||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
#include <boost/range/adaptor/type_erased.hpp>
|
#include <boost/range/adaptor/type_erased.hpp>
|
||||||
|
#include "type_erased_test.hpp"
|
||||||
|
|
||||||
#include <boost/test/test_tools.hpp>
|
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
#include <boost/range/algorithm_ext.hpp>
|
|
||||||
#include <boost/range/algorithm/fill.hpp>
|
|
||||||
#include <boost/range/value_type.hpp>
|
|
||||||
#include <boost/assign.hpp>
|
|
||||||
#include <boost/array.hpp>
|
|
||||||
#include <boost/cstdint.hpp>
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <set>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace boost_range_adaptor_type_erased_test
|
namespace boost_range_adaptor_type_erased_test
|
||||||
{
|
{
|
||||||
class MockType
|
namespace
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
MockType()
|
|
||||||
: m_x(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
MockType(boost::int32_t x)
|
void test_type_erased()
|
||||||
: m_x(x)
|
{
|
||||||
{
|
test_driver< std::list<int> >();
|
||||||
}
|
test_driver< std::vector<int> >();
|
||||||
|
|
||||||
boost::int32_t get() const { return m_x; }
|
test_driver< std::list<MockType> >();
|
||||||
|
test_driver< std::vector<MockType> >();
|
||||||
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<class Container>
|
|
||||||
void test_type_erased_impl(Container& c)
|
|
||||||
{
|
|
||||||
using namespace boost::adaptors;
|
|
||||||
typedef typename boost::range_value<Container>::type value_type;
|
|
||||||
typedef typename boost::adaptors::type_erased<> type_erased_t;
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<value_type> 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<class Container>
|
|
||||||
void test_const_and_mutable(Container& c)
|
|
||||||
{
|
|
||||||
test_type_erased_impl(c);
|
|
||||||
|
|
||||||
const Container& const_c = c;
|
|
||||||
test_type_erased_impl(const_c);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Container>
|
|
||||||
void test_driver()
|
|
||||||
{
|
|
||||||
using namespace boost::assign;
|
|
||||||
|
|
||||||
typedef typename boost::range_value<Container>::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<int> >();
|
|
||||||
test_driver< std::vector<int> >();
|
|
||||||
|
|
||||||
test_driver< std::list<MockType> >();
|
|
||||||
test_driver< std::vector<MockType> >();
|
|
||||||
}
|
|
||||||
|
|
||||||
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<Container>::type value_type;
|
|
||||||
typedef typename boost::range_difference<Container>::type difference_type;
|
|
||||||
typedef typename boost::range_reference<Container>::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<value_type> output_test;
|
|
||||||
boost::fill(r, value_type(1));
|
|
||||||
BOOST_CHECK_EQUAL( boost::distance(r), boost::distance(source) );
|
|
||||||
std::vector<value_type> 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<Container>::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<Traversal>(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<int>, boost::single_pass_traversal_tag >();
|
|
||||||
test_type_erased_exercise_buffer_types< std::deque<int>, boost::single_pass_traversal_tag >();
|
|
||||||
test_type_erased_exercise_buffer_types< std::vector<int>, boost::single_pass_traversal_tag >();
|
|
||||||
|
|
||||||
test_type_erased_exercise_buffer_types< std::list<MockType>, boost::single_pass_traversal_tag >();
|
|
||||||
test_type_erased_exercise_buffer_types< std::deque<MockType>, boost::single_pass_traversal_tag >();
|
|
||||||
test_type_erased_exercise_buffer_types< std::vector<MockType>, boost::single_pass_traversal_tag >();
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_type_erased_forward()
|
|
||||||
{
|
|
||||||
test_type_erased_exercise_buffer_types< std::list<int>, boost::forward_traversal_tag >();
|
|
||||||
test_type_erased_exercise_buffer_types< std::deque<int>, boost::forward_traversal_tag >();
|
|
||||||
test_type_erased_exercise_buffer_types< std::vector<int>, boost::forward_traversal_tag >();
|
|
||||||
|
|
||||||
test_type_erased_exercise_buffer_types< std::list<MockType>, boost::forward_traversal_tag >();
|
|
||||||
test_type_erased_exercise_buffer_types< std::deque<MockType>, boost::forward_traversal_tag >();
|
|
||||||
test_type_erased_exercise_buffer_types< std::vector<MockType>, boost::forward_traversal_tag >();
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_type_erased_bidirectional()
|
|
||||||
{
|
|
||||||
test_type_erased_exercise_buffer_types< std::list<int>, boost::bidirectional_traversal_tag >();
|
|
||||||
test_type_erased_exercise_buffer_types< std::deque<int>, boost::bidirectional_traversal_tag >();
|
|
||||||
test_type_erased_exercise_buffer_types< std::vector<int>, boost::bidirectional_traversal_tag >();
|
|
||||||
|
|
||||||
test_type_erased_exercise_buffer_types< std::list<MockType>, boost::bidirectional_traversal_tag >();
|
|
||||||
test_type_erased_exercise_buffer_types< std::deque<MockType>, boost::bidirectional_traversal_tag >();
|
|
||||||
test_type_erased_exercise_buffer_types< std::vector<MockType>, boost::bidirectional_traversal_tag >();
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_type_erased_random_access()
|
|
||||||
{
|
|
||||||
test_type_erased_exercise_buffer_types< std::deque<int>, boost::random_access_traversal_tag >();
|
|
||||||
test_type_erased_exercise_buffer_types< std::vector<int>, boost::random_access_traversal_tag >();
|
|
||||||
|
|
||||||
test_type_erased_exercise_buffer_types< std::deque<MockType>, boost::random_access_traversal_tag >();
|
|
||||||
test_type_erased_exercise_buffer_types< std::vector<MockType>, 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<class Traversal>
|
|
||||||
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<int> c;
|
|
||||||
for (int i = 0; i < 10; ++i)
|
|
||||||
c.push_back(i);
|
|
||||||
|
|
||||||
typedef boost::any_range_type_generator<
|
|
||||||
std::vector<int> >::type any_range_type;
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((
|
|
||||||
boost::is_same<
|
|
||||||
int,
|
|
||||||
boost::range_value<any_range_type>::type
|
|
||||||
>::value
|
|
||||||
));
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((
|
|
||||||
boost::is_same<
|
|
||||||
boost::random_access_traversal_tag,
|
|
||||||
boost::iterator_traversal<
|
|
||||||
boost::range_iterator<any_range_type>::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<dummy_impl> 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*
|
boost::unit_test::test_suite*
|
||||||
init_unit_test_suite(int argc, char* argv[])
|
init_unit_test_suite(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
boost::unit_test::test_suite* test
|
boost::unit_test::test_suite* test =
|
||||||
= BOOST_TEST_SUITE( "RangeTestSuite.adaptor.type_erased" );
|
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(
|
||||||
test->add( BOOST_TEST_CASE( &boost_range_adaptor_type_erased_test::test_type_erased_single_pass ) );
|
&boost_range_adaptor_type_erased_test::test_type_erased));
|
||||||
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 ) );
|
|
||||||
|
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
88
test/adaptor_test/type_erased_abstract.cpp
Normal file
88
test/adaptor_test/type_erased_abstract.cpp
Normal file
@ -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 <boost/range/adaptor/type_erased.hpp>
|
||||||
|
#include "type_erased_test.hpp"
|
||||||
|
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
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<dummy_impl> 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;
|
||||||
|
}
|
57
test/adaptor_test/type_erased_bidirectional.cpp
Normal file
57
test/adaptor_test/type_erased_bidirectional.cpp
Normal file
@ -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 <boost/range/adaptor/type_erased.hpp>
|
||||||
|
#include "type_erased_test.hpp"
|
||||||
|
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <deque>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace boost_range_adaptor_type_erased_test
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
void test_bidirectional()
|
||||||
|
{
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::list<int>, boost::bidirectional_traversal_tag >();
|
||||||
|
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::deque<int>, boost::bidirectional_traversal_tag >();
|
||||||
|
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::vector<int>, boost::bidirectional_traversal_tag >();
|
||||||
|
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::list<MockType>, boost::bidirectional_traversal_tag >();
|
||||||
|
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::deque<MockType>, boost::bidirectional_traversal_tag >();
|
||||||
|
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::vector<MockType>, 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;
|
||||||
|
}
|
||||||
|
|
70
test/adaptor_test/type_erased_brackets.cpp
Normal file
70
test/adaptor_test/type_erased_brackets.cpp
Normal file
@ -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 <boost/range/adaptor/type_erased.hpp>
|
||||||
|
#include "type_erased_test.hpp"
|
||||||
|
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace boost_range_adaptor_type_erased_test
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
void test_operator_brackets()
|
||||||
|
{
|
||||||
|
typedef boost::adaptors::type_erased<> type_erased_t;
|
||||||
|
|
||||||
|
std::vector<int> c;
|
||||||
|
for (int i = 0; i < 10; ++i)
|
||||||
|
c.push_back(i);
|
||||||
|
|
||||||
|
typedef boost::any_range_type_generator<
|
||||||
|
std::vector<int> >::type any_range_type;
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
boost::is_same<
|
||||||
|
int,
|
||||||
|
boost::range_value<any_range_type>::type
|
||||||
|
>::value
|
||||||
|
));
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
boost::is_same<
|
||||||
|
boost::random_access_traversal_tag,
|
||||||
|
boost::iterator_traversal<
|
||||||
|
boost::range_iterator<any_range_type>::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;
|
||||||
|
}
|
||||||
|
|
57
test/adaptor_test/type_erased_forward.cpp
Normal file
57
test/adaptor_test/type_erased_forward.cpp
Normal file
@ -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 <boost/range/adaptor/type_erased.hpp>
|
||||||
|
#include "type_erased_test.hpp"
|
||||||
|
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace boost_range_adaptor_type_erased_test
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
void test_forward()
|
||||||
|
{
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::list<int>, boost::forward_traversal_tag >();
|
||||||
|
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::deque<int>, boost::forward_traversal_tag >();
|
||||||
|
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::vector<int>, boost::forward_traversal_tag >();
|
||||||
|
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::list<MockType>, boost::forward_traversal_tag >();
|
||||||
|
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::deque<MockType>, boost::forward_traversal_tag >();
|
||||||
|
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::vector<MockType>, 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;
|
||||||
|
}
|
||||||
|
|
94
test/adaptor_test/type_erased_mix_values.cpp
Normal file
94
test/adaptor_test/type_erased_mix_values.cpp
Normal file
@ -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 <boost/range/adaptor/type_erased.hpp>
|
||||||
|
#include "type_erased_test.hpp"
|
||||||
|
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
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<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<class Traversal>
|
||||||
|
void mix_values_driver()
|
||||||
|
{
|
||||||
|
mix_values_impl<
|
||||||
|
Traversal,
|
||||||
|
MockType,
|
||||||
|
MockType2, const MockType&,
|
||||||
|
MockType, const MockType&
|
||||||
|
>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mix_values()
|
||||||
|
{
|
||||||
|
mix_values_driver<boost::single_pass_traversal_tag >();
|
||||||
|
mix_values_driver<boost::forward_traversal_tag >();
|
||||||
|
mix_values_driver<boost::bidirectional_traversal_tag >();
|
||||||
|
mix_values_driver<boost::random_access_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_mix_values");
|
||||||
|
|
||||||
|
test->add(BOOST_TEST_CASE(
|
||||||
|
&boost_range_adaptor_type_erased_test::mix_values));
|
||||||
|
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
50
test/adaptor_test/type_erased_random_access.cpp
Normal file
50
test/adaptor_test/type_erased_random_access.cpp
Normal file
@ -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 <boost/range/adaptor/type_erased.hpp>
|
||||||
|
#include "type_erased_test.hpp"
|
||||||
|
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace boost_range_adaptor_type_erased_test
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
void test_random_access()
|
||||||
|
{
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::deque<int>, boost::random_access_traversal_tag >();
|
||||||
|
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::vector<int>, boost::random_access_traversal_tag >();
|
||||||
|
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::deque<MockType>, boost::random_access_traversal_tag >();
|
||||||
|
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::vector<MockType>, 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;
|
||||||
|
}
|
||||||
|
|
57
test/adaptor_test/type_erased_single_pass.cpp
Normal file
57
test/adaptor_test/type_erased_single_pass.cpp
Normal file
@ -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 <boost/range/adaptor/type_erased.hpp>
|
||||||
|
#include "type_erased_test.hpp"
|
||||||
|
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace boost_range_adaptor_type_erased_test
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
void test_single_pass()
|
||||||
|
{
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::list<int>, boost::single_pass_traversal_tag>();
|
||||||
|
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::deque<int>, boost::single_pass_traversal_tag>();
|
||||||
|
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::vector<int>, boost::single_pass_traversal_tag>();
|
||||||
|
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::list<MockType>, boost::single_pass_traversal_tag>();
|
||||||
|
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::deque<MockType>, boost::single_pass_traversal_tag>();
|
||||||
|
|
||||||
|
test_type_erased_exercise_buffer_types<
|
||||||
|
std::vector<MockType>, 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;
|
||||||
|
}
|
||||||
|
|
289
test/adaptor_test/type_erased_test.hpp
Normal file
289
test/adaptor_test/type_erased_test.hpp
Normal file
@ -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 <boost/range/algorithm/fill.hpp>
|
||||||
|
#include <boost/range/algorithm_ext/push_back.hpp>
|
||||||
|
#include <boost/assign.hpp>
|
||||||
|
#include <boost/test/test_tools.hpp>
|
||||||
|
|
||||||
|
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<class Container>
|
||||||
|
void test_type_erased_impl(Container& c)
|
||||||
|
{
|
||||||
|
using namespace boost::adaptors;
|
||||||
|
typedef typename boost::range_value<Container>::type value_type;
|
||||||
|
typedef typename boost::adaptors::type_erased<> type_erased_t;
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<value_type> 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<class Container>
|
||||||
|
void test_const_and_mutable(Container& c)
|
||||||
|
{
|
||||||
|
test_type_erased_impl(c);
|
||||||
|
|
||||||
|
const Container& const_c = c;
|
||||||
|
test_type_erased_impl(const_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Container>
|
||||||
|
void test_driver()
|
||||||
|
{
|
||||||
|
using namespace boost::assign;
|
||||||
|
|
||||||
|
typedef typename boost::range_value<Container>::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<Container>::type value_type;
|
||||||
|
typedef typename boost::range_difference<Container>::type difference_type;
|
||||||
|
typedef typename boost::range_reference<Container>::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<value_type> output_test;
|
||||||
|
boost::fill(r, value_type(1));
|
||||||
|
BOOST_CHECK_EQUAL( boost::distance(r), boost::distance(source) );
|
||||||
|
std::vector<value_type> 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<Container>::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<Traversal>(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
|
74
test/adaptor_test/type_erased_tparam_conv.cpp
Normal file
74
test/adaptor_test/type_erased_tparam_conv.cpp
Normal file
@ -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 <boost/range/adaptor/type_erased.hpp>
|
||||||
|
#include "type_erased_test.hpp"
|
||||||
|
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user