forked from boostorg/range
trac 5816 - fix any_range requiring copyable elements.
This commit is contained in:
@ -27,25 +27,40 @@ namespace boost
|
|||||||
{
|
{
|
||||||
typedef typename mpl::if_<
|
typedef typename mpl::if_<
|
||||||
typename is_reference<T>::type,
|
typename is_reference<T>::type,
|
||||||
typename add_reference<
|
|
||||||
typename add_const<
|
typename add_const<
|
||||||
typename remove_reference<T>::type
|
typename remove_reference<T>::type
|
||||||
>::type
|
>::type&,
|
||||||
>::type,
|
|
||||||
T
|
T
|
||||||
>::type type;
|
>::type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct mutable_reference_type_generator
|
||||||
|
{
|
||||||
|
typedef typename mpl::if_<
|
||||||
|
typename mpl::and_<
|
||||||
|
typename is_const<T>::type,
|
||||||
|
typename mpl::not_<typename is_reference<T>::type>::type
|
||||||
|
>::type,
|
||||||
|
T,
|
||||||
|
typename add_reference<T>::type
|
||||||
|
>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
template<
|
template<
|
||||||
class Reference
|
class Reference
|
||||||
, class Buffer
|
, class Buffer
|
||||||
>
|
>
|
||||||
struct any_incrementable_iterator_interface
|
struct any_incrementable_iterator_interface
|
||||||
{
|
{
|
||||||
typedef Reference reference;
|
typedef typename mutable_reference_type_generator<
|
||||||
|
Reference
|
||||||
|
>::type reference;
|
||||||
|
|
||||||
typedef typename const_reference_type_generator<
|
typedef typename const_reference_type_generator<
|
||||||
Reference
|
Reference
|
||||||
>::type const_reference;
|
>::type const_reference;
|
||||||
|
|
||||||
typedef typename remove_const<
|
typedef typename remove_const<
|
||||||
typename remove_reference<Reference>::type
|
typename remove_reference<Reference>::type
|
||||||
>::type reference_as_value_type;
|
>::type reference_as_value_type;
|
||||||
@ -87,7 +102,7 @@ namespace boost
|
|||||||
virtual any_single_pass_iterator_interface<reference_as_value_type, Buffer>*
|
virtual any_single_pass_iterator_interface<reference_as_value_type, Buffer>*
|
||||||
clone_reference_as_value(buffer_type& buffer) const = 0;
|
clone_reference_as_value(buffer_type& buffer) const = 0;
|
||||||
|
|
||||||
virtual Reference dereference() const = 0;
|
virtual reference dereference() const = 0;
|
||||||
|
|
||||||
virtual bool equal(const any_single_pass_iterator_interface& other) const = 0;
|
virtual bool equal(const any_single_pass_iterator_interface& other) const = 0;
|
||||||
};
|
};
|
||||||
|
@ -19,6 +19,17 @@ namespace boost
|
|||||||
{
|
{
|
||||||
namespace range_detail
|
namespace range_detail
|
||||||
{
|
{
|
||||||
|
template<class Reference, class T>
|
||||||
|
Reference dereference_cast(T& x)
|
||||||
|
{
|
||||||
|
return static_cast<Reference>(x);
|
||||||
|
}
|
||||||
|
template<class Reference, class T>
|
||||||
|
Reference dereference_cast(const T& x)
|
||||||
|
{
|
||||||
|
return static_cast<Reference>(const_cast<T&>(x));
|
||||||
|
}
|
||||||
|
|
||||||
template<
|
template<
|
||||||
class WrappedIterator
|
class WrappedIterator
|
||||||
, class Reference
|
, class Reference
|
||||||
@ -114,7 +125,13 @@ namespace boost
|
|||||||
{
|
{
|
||||||
struct disabler {};
|
struct disabler {};
|
||||||
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassIteratorConcept<WrappedIterator> ));
|
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassIteratorConcept<WrappedIterator> ));
|
||||||
|
typedef any_single_pass_iterator_interface<
|
||||||
|
Reference,
|
||||||
|
Buffer
|
||||||
|
> base_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
typedef typename base_type::reference reference;
|
||||||
|
|
||||||
any_single_pass_iterator_wrapper()
|
any_single_pass_iterator_wrapper()
|
||||||
: m_it()
|
: m_it()
|
||||||
@ -178,9 +195,9 @@ namespace boost
|
|||||||
return m_it == boost::polymorphic_downcast<const any_single_pass_iterator_wrapper*>(&other)->m_it;
|
return m_it == boost::polymorphic_downcast<const any_single_pass_iterator_wrapper*>(&other)->m_it;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Reference dereference() const
|
virtual reference dereference() const
|
||||||
{
|
{
|
||||||
return *m_it;
|
return dereference_cast<reference>(*m_it);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -199,7 +216,14 @@ namespace boost
|
|||||||
>
|
>
|
||||||
{
|
{
|
||||||
BOOST_RANGE_CONCEPT_ASSERT(( ForwardIteratorConcept<WrappedIterator> ));
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardIteratorConcept<WrappedIterator> ));
|
||||||
|
typedef any_forward_iterator_interface<
|
||||||
|
Reference,
|
||||||
|
Buffer
|
||||||
|
> base_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
typedef typename base_type::reference reference;
|
||||||
|
|
||||||
any_forward_iterator_wrapper()
|
any_forward_iterator_wrapper()
|
||||||
: m_it()
|
: m_it()
|
||||||
{}
|
{}
|
||||||
@ -263,9 +287,9 @@ namespace boost
|
|||||||
return m_it == boost::polymorphic_downcast<const any_forward_iterator_wrapper*>(&other)->m_it;
|
return m_it == boost::polymorphic_downcast<const any_forward_iterator_wrapper*>(&other)->m_it;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Reference dereference() const
|
virtual reference dereference() const
|
||||||
{
|
{
|
||||||
return *m_it;
|
return dereference_cast<reference>(*m_it);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
WrappedIterator m_it;
|
WrappedIterator m_it;
|
||||||
@ -283,7 +307,14 @@ namespace boost
|
|||||||
>
|
>
|
||||||
{
|
{
|
||||||
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalIteratorConcept<WrappedIterator> ));
|
BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalIteratorConcept<WrappedIterator> ));
|
||||||
|
typedef any_bidirectional_iterator_interface<
|
||||||
|
Reference,
|
||||||
|
Buffer
|
||||||
|
> base_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
typedef typename base_type::reference reference;
|
||||||
|
|
||||||
any_bidirectional_iterator_wrapper()
|
any_bidirectional_iterator_wrapper()
|
||||||
: m_it()
|
: m_it()
|
||||||
{
|
{
|
||||||
@ -353,9 +384,9 @@ namespace boost
|
|||||||
return m_it == boost::polymorphic_downcast<const any_bidirectional_iterator_wrapper*>(&other)->m_it;
|
return m_it == boost::polymorphic_downcast<const any_bidirectional_iterator_wrapper*>(&other)->m_it;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Reference dereference() const
|
virtual reference dereference() const
|
||||||
{
|
{
|
||||||
return *m_it;
|
return dereference_cast<reference>(*m_it);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -376,7 +407,14 @@ namespace boost
|
|||||||
>
|
>
|
||||||
{
|
{
|
||||||
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessIteratorConcept<WrappedIterator> ));
|
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessIteratorConcept<WrappedIterator> ));
|
||||||
|
typedef any_random_access_iterator_interface<
|
||||||
|
Reference,
|
||||||
|
Difference,
|
||||||
|
Buffer
|
||||||
|
> base_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
typedef typename base_type::reference reference;
|
||||||
typedef Difference difference_type;
|
typedef Difference difference_type;
|
||||||
|
|
||||||
any_random_access_iterator_wrapper()
|
any_random_access_iterator_wrapper()
|
||||||
@ -457,9 +495,9 @@ namespace boost
|
|||||||
m_it += offset;
|
m_it += offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Reference dereference() const
|
virtual reference dereference() const
|
||||||
{
|
{
|
||||||
return *m_it;
|
return dereference_cast<reference>(*m_it);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Difference distance_to(const any_random_access_iterator_interface<Reference, Difference, Buffer>& other) const
|
virtual Difference distance_to(const any_random_access_iterator_interface<Reference, Difference, Buffer>& other) const
|
||||||
|
@ -476,6 +476,60 @@ namespace boost_range_adaptor_type_erased_test
|
|||||||
BOOST_CHECK_EQUAL( rng[i], 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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::unit_test::test_suite*
|
boost::unit_test::test_suite*
|
||||||
@ -492,6 +546,7 @@ init_unit_test_suite(int argc, char* argv[])
|
|||||||
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_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_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_operator_brackets ) );
|
||||||
|
test->add( BOOST_TEST_CASE( &boost_range_adaptor_type_erased_test::test_type_erased_abstract ) );
|
||||||
|
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user