From 60025220f5ff383ec4f67e1f9f79760e972b3062 Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Wed, 4 Jun 2014 12:23:40 +0100 Subject: [PATCH] add Enabler template argument to range_iterator, range_const_iterator and range_mutable_iterator extension points. --- doc/reference/synopsis.qbk | 2 +- include/boost/range/const_iterator.hpp | 2 +- include/boost/range/iterator.hpp | 2 +- include/boost/range/mutable_iterator.hpp | 64 ++++++---- test/Jamfile.v2 | 1 + test/iterator_ext.cpp | 153 +++++++++++++++++++++++ 6 files changed, 194 insertions(+), 30 deletions(-) create mode 100644 test/iterator_ext.cpp diff --git a/doc/reference/synopsis.qbk b/doc/reference/synopsis.qbk index bfef5c1..26f9641 100644 --- a/doc/reference/synopsis.qbk +++ b/doc/reference/synopsis.qbk @@ -12,7 +12,7 @@ namespace boost // Single Pass Range metafunctions // - template< class T > + template< class T, class Enabler=void > struct range_iterator; template< class T > diff --git a/include/boost/range/const_iterator.hpp b/include/boost/range/const_iterator.hpp index 1876794..e22ba84 100644 --- a/include/boost/range/const_iterator.hpp +++ b/include/boost/range/const_iterator.hpp @@ -62,7 +62,7 @@ struct range_const_iterator< T[sz] > } // namespace range_detail -template +template struct range_const_iterator : range_detail::range_const_iterator< BOOST_DEDUCED_TYPENAME remove_reference::type diff --git a/include/boost/range/iterator.hpp b/include/boost/range/iterator.hpp index 3ba9952..7f32c85 100644 --- a/include/boost/range/iterator.hpp +++ b/include/boost/range/iterator.hpp @@ -47,7 +47,7 @@ namespace boost #endif - template< typename C > + template< typename C, typename Enabler=void > struct range_iterator { #if BOOST_WORKAROUND(BOOST_MSVC, == 1310) diff --git a/include/boost/range/mutable_iterator.hpp b/include/boost/range/mutable_iterator.hpp index 387262f..22bf212 100644 --- a/include/boost/range/mutable_iterator.hpp +++ b/include/boost/range/mutable_iterator.hpp @@ -31,37 +31,47 @@ namespace boost // default ////////////////////////////////////////////////////////////////////////// - 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::type> - {}; - - ////////////////////////////////////////////////////////////////////////// - // pair - ////////////////////////////////////////////////////////////////////////// - - template< typename Iterator > - struct range_mutable_iterator< std::pair > + namespace range_detail { - typedef Iterator type; - }; - ////////////////////////////////////////////////////////////////////////// - // array - ////////////////////////////////////////////////////////////////////////// +BOOST_RANGE_EXTRACT_OPTIONAL_TYPE( iterator ) - template< typename T, std::size_t sz > - struct range_mutable_iterator< T[sz] > - { - typedef T* type; - }; +template< typename C > +struct range_mutable_iterator + : range_detail::extract_iterator< + BOOST_DEDUCED_TYPENAME remove_reference::type> +{}; + +////////////////////////////////////////////////////////////////////////// +// pair +////////////////////////////////////////////////////////////////////////// + +template< typename Iterator > +struct range_mutable_iterator< std::pair > +{ + typedef Iterator type; +}; + +////////////////////////////////////////////////////////////////////////// +// array +////////////////////////////////////////////////////////////////////////// + +template< typename T, std::size_t sz > +struct range_mutable_iterator< T[sz] > +{ + typedef T* type; +}; + + } // namespace range_detail + +template +struct range_mutable_iterator + : range_detail::range_mutable_iterator< + BOOST_DEDUCED_TYPENAME remove_reference::type + > +{ +}; } // namespace boost - #endif diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 187b78d..4dae50d 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -187,6 +187,7 @@ test-suite range : [ range-test irange ] [ range-test istream_range ] [ range-test iterator ] + [ range-test iterator_ext ] [ range-test iterator_pair ] [ range-test iterator_range ] [ range-test iterator_range_drop ] diff --git a/test/iterator_ext.cpp b/test/iterator_ext.cpp new file mode 100644 index 0000000..820bf2a --- /dev/null +++ b/test/iterator_ext.cpp @@ -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 +#include +#include +#include +#include + +#include +#include + +#include + +namespace boost_range_test +{ + +struct point +{ + int x; + int y; +}; + +class shape +{ +public: + virtual ~shape() + { + } + + const std::vector& points() const + { + return m_points; + } + +private: + std::vector m_points; +}; + +class rectangle : public shape +{ +}; + +class circle : public shape +{ +}; + +class container +{ + typedef std::vector impl_t; +}; + +} // namespace boost_range_test + +namespace boost +{ + template + 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::type + >::type + > + >::type + > + { + typedef std::vector::iterator type; + }; + + template + 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::type + >::type + > + >::type + > + { + typedef std::vector::const_iterator type; + }; + + template<> + struct range_mutable_iterator + { + typedef std::vector::iterator type; + }; + + template<> + struct range_const_iterator + { + typedef std::vector::const_iterator type; + }; +} + +namespace boost_range_test +{ + template + void test_iterator_impl() + { + BOOST_STATIC_ASSERT(( + boost::is_same< + std::vector::iterator, + typename boost::range_iterator::type + >::value)); + + BOOST_STATIC_ASSERT(( + boost::is_same< + std::vector::const_iterator, + typename boost::range_iterator::type + >::value)); + + #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT(( + boost::is_same< + std::vector::iterator, + typename boost::range_iterator::type + >::value)); + #endif + } + + void test_iterator() + { + test_iterator_impl(); + test_iterator_impl(); + test_iterator_impl(); + + test_iterator_impl(); + } +} // 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; +}