forked from boostorg/range
add Enabler template argument to range_iterator, range_const_iterator and range_mutable_iterator extension points.
This commit is contained in:
@ -12,7 +12,7 @@ namespace boost
|
|||||||
// Single Pass Range metafunctions
|
// Single Pass Range metafunctions
|
||||||
//
|
//
|
||||||
|
|
||||||
template< class T >
|
template< class T, class Enabler=void >
|
||||||
struct range_iterator;
|
struct range_iterator;
|
||||||
|
|
||||||
template< class T >
|
template< class T >
|
||||||
|
@ -62,7 +62,7 @@ struct range_const_iterator< T[sz] >
|
|||||||
|
|
||||||
} // namespace range_detail
|
} // namespace range_detail
|
||||||
|
|
||||||
template<typename C>
|
template<typename C, typename Enabler=void>
|
||||||
struct range_const_iterator
|
struct range_const_iterator
|
||||||
: range_detail::range_const_iterator<
|
: range_detail::range_const_iterator<
|
||||||
BOOST_DEDUCED_TYPENAME remove_reference<C>::type
|
BOOST_DEDUCED_TYPENAME remove_reference<C>::type
|
||||||
|
@ -47,7 +47,7 @@ namespace boost
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template< typename C >
|
template< typename C, typename Enabler=void >
|
||||||
struct range_iterator
|
struct range_iterator
|
||||||
{
|
{
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
|
#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
|
||||||
|
@ -31,37 +31,47 @@ namespace boost
|
|||||||
// default
|
// default
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
namespace range_detail {
|
namespace range_detail
|
||||||
BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( iterator )
|
|
||||||
}
|
|
||||||
|
|
||||||
template< typename C >
|
|
||||||
struct range_mutable_iterator
|
|
||||||
: range_detail::extract_iterator<
|
|
||||||
BOOST_DEDUCED_TYPENAME remove_reference<C>::type>
|
|
||||||
{};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// pair
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template< typename Iterator >
|
|
||||||
struct range_mutable_iterator< std::pair<Iterator,Iterator> >
|
|
||||||
{
|
{
|
||||||
typedef Iterator type;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( iterator )
|
||||||
// array
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template< typename T, std::size_t sz >
|
template< typename C >
|
||||||
struct range_mutable_iterator< T[sz] >
|
struct range_mutable_iterator
|
||||||
{
|
: range_detail::extract_iterator<
|
||||||
typedef T* type;
|
BOOST_DEDUCED_TYPENAME remove_reference<C>::type>
|
||||||
};
|
{};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// pair
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template< typename Iterator >
|
||||||
|
struct range_mutable_iterator< std::pair<Iterator,Iterator> >
|
||||||
|
{
|
||||||
|
typedef Iterator type;
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// array
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template< typename T, std::size_t sz >
|
||||||
|
struct range_mutable_iterator< T[sz] >
|
||||||
|
{
|
||||||
|
typedef T* type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace range_detail
|
||||||
|
|
||||||
|
template<typename C, typename Enabler=void>
|
||||||
|
struct range_mutable_iterator
|
||||||
|
: range_detail::range_mutable_iterator<
|
||||||
|
BOOST_DEDUCED_TYPENAME remove_reference<C>::type
|
||||||
|
>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -187,6 +187,7 @@ test-suite range :
|
|||||||
[ range-test irange ]
|
[ range-test irange ]
|
||||||
[ range-test istream_range ]
|
[ range-test istream_range ]
|
||||||
[ range-test iterator ]
|
[ range-test iterator ]
|
||||||
|
[ range-test iterator_ext ]
|
||||||
[ range-test iterator_pair ]
|
[ range-test iterator_pair ]
|
||||||
[ range-test iterator_range ]
|
[ range-test iterator_range ]
|
||||||
[ range-test iterator_range_drop ]
|
[ range-test iterator_range_drop ]
|
||||||
|
153
test/iterator_ext.cpp
Normal file
153
test/iterator_ext.cpp
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
// 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)
|
||||||
|
//
|
||||||
|
// For more information, see http://www.boost.org/libs/range/
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/range/iterator.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
#include <boost/type_traits/is_same.hpp>
|
||||||
|
#include <boost/type_traits/is_base_of.hpp>
|
||||||
|
#include <boost/type_traits/decay.hpp>
|
||||||
|
|
||||||
|
#include <boost/test/test_tools.hpp>
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace boost_range_test
|
||||||
|
{
|
||||||
|
|
||||||
|
struct point
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
};
|
||||||
|
|
||||||
|
class shape
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~shape()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<point>& points() const
|
||||||
|
{
|
||||||
|
return m_points;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<point> m_points;
|
||||||
|
};
|
||||||
|
|
||||||
|
class rectangle : public shape
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
class circle : public shape
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
class container
|
||||||
|
{
|
||||||
|
typedef std::vector<point> impl_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace boost_range_test
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
struct range_mutable_iterator<
|
||||||
|
T,
|
||||||
|
typename boost::enable_if<
|
||||||
|
boost::is_base_of<
|
||||||
|
boost_range_test::shape,
|
||||||
|
typename boost::remove_reference<
|
||||||
|
typename boost::remove_cv<T>::type
|
||||||
|
>::type
|
||||||
|
>
|
||||||
|
>::type
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef std::vector<boost_range_test::point>::iterator type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct range_const_iterator<
|
||||||
|
T,
|
||||||
|
typename boost::enable_if<
|
||||||
|
boost::is_base_of<
|
||||||
|
boost_range_test::shape,
|
||||||
|
typename boost::remove_reference<
|
||||||
|
typename boost::remove_cv<T>::type
|
||||||
|
>::type
|
||||||
|
>
|
||||||
|
>::type
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef std::vector<boost_range_test::point>::const_iterator type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct range_mutable_iterator<boost_range_test::container>
|
||||||
|
{
|
||||||
|
typedef std::vector<boost_range_test::point>::iterator type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct range_const_iterator<boost_range_test::container>
|
||||||
|
{
|
||||||
|
typedef std::vector<boost_range_test::point>::const_iterator type;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace boost_range_test
|
||||||
|
{
|
||||||
|
template<typename Shape>
|
||||||
|
void test_iterator_impl()
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
boost::is_same<
|
||||||
|
std::vector<point>::iterator,
|
||||||
|
typename boost::range_iterator<Shape>::type
|
||||||
|
>::value));
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
boost::is_same<
|
||||||
|
std::vector<point>::const_iterator,
|
||||||
|
typename boost::range_iterator<const Shape>::type
|
||||||
|
>::value));
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
|
BOOST_STATIC_ASSERT((
|
||||||
|
boost::is_same<
|
||||||
|
std::vector<point>::iterator,
|
||||||
|
typename boost::range_iterator<Shape&&>::type
|
||||||
|
>::value));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_iterator()
|
||||||
|
{
|
||||||
|
test_iterator_impl<shape>();
|
||||||
|
test_iterator_impl<rectangle>();
|
||||||
|
test_iterator_impl<circle>();
|
||||||
|
|
||||||
|
test_iterator_impl<container>();
|
||||||
|
}
|
||||||
|
} // namespace boost_range_test
|
||||||
|
|
||||||
|
boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||||
|
{
|
||||||
|
boost::unit_test::test_suite* test =
|
||||||
|
BOOST_TEST_SUITE("Boost.Range range_iterator meta-function");
|
||||||
|
|
||||||
|
test->add(BOOST_TEST_CASE(&boost_range_test::test_iterator));
|
||||||
|
|
||||||
|
return test;
|
||||||
|
}
|
Reference in New Issue
Block a user