From 1d91272a551df2cd1776d6447c0e39a14f660c17 Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Sat, 22 Feb 2014 22:31:48 +0000 Subject: [PATCH] trac 6715 - iterator_range operators work automatically in derived. --- include/boost/range/iterator_range_core.hpp | 286 +++++++++---------- test/Jamfile.v2 | 1 + test/ticket_6715_iterator_range_equality.cpp | 44 +++ 3 files changed, 175 insertions(+), 156 deletions(-) create mode 100644 test/ticket_6715_iterator_range_equality.cpp diff --git a/include/boost/range/iterator_range_core.hpp b/include/boost/range/iterator_range_core.hpp index f985641..967a457 100644 --- a/include/boost/range/iterator_range_core.hpp +++ b/include/boost/range/iterator_range_core.hpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -77,7 +78,7 @@ namespace boost template< class Left, class Right > inline bool greater_than( const Left& l, const Right& r ) { - return less_than(r,l); + return iterator_range_detail::less_than(r,l); } template< class Left, class Right > @@ -102,6 +103,8 @@ namespace boost struct range_tag { }; struct const_range_tag { }; + + struct iterator_range_tag { }; } // iterator range template class -----------------------------------------// @@ -125,6 +128,7 @@ namespace boost */ template class iterator_range + : public iterator_range_detail::iterator_range_tag { typedef range_detail::safe_bool< IteratorT iterator_range::* > safe_bool_t; protected: // Used by sub_range @@ -268,46 +272,11 @@ namespace boost return empty(); } - bool equal( const iterator_range& r ) const + bool equal(const iterator_range& r) const { return m_Begin == r.m_Begin && m_End == r.m_End; } - -#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING - - bool operator==( const iterator_range& r ) const - { - return boost::equal( *this, r ); - } - - bool operator!=( const iterator_range& r ) const - { - return !operator==(r); - } - - bool operator<( const iterator_range& r ) const - { - return iterator_range_detail::less_than( *this, r ); - } - - bool operator>( const iterator_range& r ) const - { - return iterator_range_detail::greater_than( *this, r ); - } - - bool operator<=( const iterator_range& r ) const - { - return iterator_range_detail::less_or_equal_than( *this, r ); - } - - bool operator>=( const iterator_range& r ) const - { - return iterator_range_detail::greater_or_equal_than( *this, r ); - } - -#endif - public: // convenience reference front() const { @@ -383,138 +352,143 @@ namespace boost ///////////////////////////////////////////////////////////////////// // comparison operators ///////////////////////////////////////////////////////////////////// - - template< class IteratorT, class ForwardRange > - inline bool operator==( const ForwardRange& l, - const iterator_range& r ) + template + inline BOOST_DEDUCED_TYPENAME enable_if< + mpl::or_< + is_convertible< + const SinglePassRange1&, + const iterator_range_detail::iterator_range_tag& + >, + is_convertible< + const SinglePassRange2&, + const iterator_range_detail::iterator_range_tag& + > + >, + bool + >::type + operator==(const SinglePassRange1& l, const SinglePassRange2& r) { - return boost::equal( l, r ); + BOOST_RANGE_CONCEPT_ASSERT(( + boost::SinglePassRangeConcept)); + BOOST_RANGE_CONCEPT_ASSERT(( + boost::SinglePassRangeConcept)); + return boost::equal(l, r); + } + + template + inline BOOST_DEDUCED_TYPENAME enable_if< + mpl::or_< + is_convertible< + const SinglePassRange1&, + const iterator_range_detail::iterator_range_tag& + >, + is_convertible< + const SinglePassRange2&, + const iterator_range_detail::iterator_range_tag& + > + >, + bool + >::type + operator!=(const SinglePassRange1& l, const SinglePassRange2& r) + { + BOOST_RANGE_CONCEPT_ASSERT(( + boost::SinglePassRangeConcept)); + BOOST_RANGE_CONCEPT_ASSERT(( + boost::SinglePassRangeConcept)); + return !boost::equal(l, r); } - template< class IteratorT, class ForwardRange > - inline bool operator!=( const ForwardRange& l, - const iterator_range& r ) + template + inline BOOST_DEDUCED_TYPENAME enable_if< + mpl::or_< + is_convertible< + const SinglePassRange1&, + const iterator_range_detail::iterator_range_tag& + >, + is_convertible< + const SinglePassRange2&, + const iterator_range_detail::iterator_range_tag& + > + >, + bool + >::type + operator<(const SinglePassRange1& l, const SinglePassRange2& r) { - return !boost::equal( l, r ); + BOOST_RANGE_CONCEPT_ASSERT(( + boost::SinglePassRangeConcept)); + BOOST_RANGE_CONCEPT_ASSERT(( + boost::SinglePassRangeConcept)); + return iterator_range_detail::less_than(l, r); } - - template< class IteratorT, class ForwardRange > - inline bool operator<( const ForwardRange& l, - const iterator_range& r ) + + template + inline BOOST_DEDUCED_TYPENAME enable_if< + mpl::or_< + is_convertible< + const SinglePassRange1&, + const iterator_range_detail::iterator_range_tag& + >, + is_convertible< + const SinglePassRange2&, + const iterator_range_detail::iterator_range_tag& + > + >, + bool + >::type + operator<=(const SinglePassRange1& l, const SinglePassRange2& r) { - return iterator_range_detail::less_than( l, r ); + BOOST_RANGE_CONCEPT_ASSERT(( + boost::SinglePassRangeConcept)); + BOOST_RANGE_CONCEPT_ASSERT(( + boost::SinglePassRangeConcept)); + return iterator_range_detail::less_or_equal_than(l, r); } - template< class IteratorT, class ForwardRange > - inline bool operator<=( const ForwardRange& l, - const iterator_range& r ) + template + inline BOOST_DEDUCED_TYPENAME enable_if< + mpl::or_< + is_convertible< + const SinglePassRange1&, + const iterator_range_detail::iterator_range_tag& + >, + is_convertible< + const SinglePassRange2&, + const iterator_range_detail::iterator_range_tag& + > + >, + bool + >::type + operator>(const SinglePassRange1& l, const SinglePassRange2& r) { - return iterator_range_detail::less_or_equal_than( l, r ); + BOOST_RANGE_CONCEPT_ASSERT(( + boost::SinglePassRangeConcept)); + BOOST_RANGE_CONCEPT_ASSERT(( + boost::SinglePassRangeConcept)); + return iterator_range_detail::greater_than(l, r); } - template< class IteratorT, class ForwardRange > - inline bool operator>( const ForwardRange& l, - const iterator_range& r ) + template + inline BOOST_DEDUCED_TYPENAME enable_if< + mpl::or_< + is_convertible< + const SinglePassRange1&, + const iterator_range_detail::iterator_range_tag& + >, + is_convertible< + const SinglePassRange2&, + const iterator_range_detail::iterator_range_tag& + > + >, + bool + >::type + operator>=(const SinglePassRange1& l, const SinglePassRange2& r) { - return iterator_range_detail::greater_than( l, r ); + BOOST_RANGE_CONCEPT_ASSERT(( + boost::SinglePassRangeConcept)); + BOOST_RANGE_CONCEPT_ASSERT(( + boost::SinglePassRangeConcept)); + return iterator_range_detail::greater_or_equal_than(l, r); } - - template< class IteratorT, class ForwardRange > - inline bool operator>=( const ForwardRange& l, - const iterator_range& r ) - { - return iterator_range_detail::greater_or_equal_than( l, r ); - } - -#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING -#else - template< class Iterator1T, class Iterator2T > - inline bool operator==( const iterator_range& l, - const iterator_range& r ) - { - return boost::equal( l, r ); - } - - template< class IteratorT, class ForwardRange > - inline bool operator==( const iterator_range& l, - const ForwardRange& r ) - { - return boost::equal( l, r ); - } - - - template< class Iterator1T, class Iterator2T > - inline bool operator!=( const iterator_range& l, - const iterator_range& r ) - { - return !boost::equal( l, r ); - } - - template< class IteratorT, class ForwardRange > - inline bool operator!=( const iterator_range& l, - const ForwardRange& r ) - { - return !boost::equal( l, r ); - } - - - template< class Iterator1T, class Iterator2T > - inline bool operator<( const iterator_range& l, - const iterator_range& r ) - { - return iterator_range_detail::less_than( l, r ); - } - - template< class IteratorT, class ForwardRange > - inline bool operator<( const iterator_range& l, - const ForwardRange& r ) - { - return iterator_range_detail::less_than( l, r ); - } - - template< class Iterator1T, class Iterator2T > - inline bool operator<=( const iterator_range& l, - const iterator_range& r ) - { - return iterator_range_detail::less_or_equal_than( l, r ); - } - - template< class IteratorT, class ForwardRange > - inline bool operator<=( const iterator_range& l, - const ForwardRange& r ) - { - return iterator_range_detail::less_or_equal_than( l, r ); - } - - template< class Iterator1T, class Iterator2T > - inline bool operator>( const iterator_range& l, - const iterator_range& r ) - { - return iterator_range_detail::greater_than( l, r ); - } - - template< class IteratorT, class ForwardRange > - inline bool operator>( const iterator_range& l, - const ForwardRange& r ) - { - return iterator_range_detail::greater_than( l, r ); - } - - template< class Iterator1T, class Iterator2T > - inline bool operator>=( const iterator_range& l, - const iterator_range& r ) - { - return iterator_range_detail::greater_or_equal_than( l, r ); - } - - template< class IteratorT, class ForwardRange > - inline bool operator>=( const iterator_range& l, - const ForwardRange& r ) - { - return iterator_range_detail::greater_or_equal_than( l, r ); - } - -#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING // iterator range utilities -----------------------------------------// diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 1df869d..0871332 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -162,6 +162,7 @@ test-suite range : [ range-test ticket_5547 ] [ range-test ticket_5556_is_sorted_namespace ] [ range-test ticket_5811_indirected_optional ] + [ range-test ticket_6715_iterator_range_equality ] [ range-test ticket_6944 ] ; diff --git a/test/ticket_6715_iterator_range_equality.cpp b/test/ticket_6715_iterator_range_equality.cpp new file mode 100644 index 0000000..0ca1d42 --- /dev/null +++ b/test/ticket_6715_iterator_range_equality.cpp @@ -0,0 +1,44 @@ +// 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 + +namespace boost +{ + namespace + { + class str_ref : public boost::iterator_range + { + }; + + void test_ticket_6715_iterator_range_equality() + { + str_ref a; + str_ref b; + BOOST_CHECK(a == b); + } + } +} + +boost::unit_test::test_suite* +init_unit_test_suite(int argc, char* argv[]) +{ + boost::unit_test::test_suite* test + = BOOST_TEST_SUITE( + "RangeTestSuite.ticket_6715_iterator_range_equality"); + + test->add(BOOST_TEST_CASE( + &boost::test_ticket_6715_iterator_range_equality)); + + return test; +}