diff --git a/include/boost/range/iterator_range_core.hpp b/include/boost/range/iterator_range_core.hpp index afbf3ff..143796b 100644 --- a/include/boost/range/iterator_range_core.hpp +++ b/include/boost/range/iterator_range_core.hpp @@ -26,9 +26,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -539,143 +541,174 @@ public: ///////////////////////////////////////////////////////////////////// // comparison operators ///////////////////////////////////////////////////////////////////// - template - inline BOOST_DEDUCED_TYPENAME ::boost::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& - > - >, + + template< class IteratorT, class ForwardRange > + inline BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, bool >::type - operator==(const SinglePassRange1& l, const SinglePassRange2& r) + operator==( const ForwardRange& l, const iterator_range& r ) { - BOOST_RANGE_CONCEPT_ASSERT(( - boost::SinglePassRangeConcept)); - BOOST_RANGE_CONCEPT_ASSERT(( - boost::SinglePassRangeConcept)); - return boost::equal(l, r); - } - - template - inline BOOST_DEDUCED_TYPENAME ::boost::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); + return boost::equal( l, r ); } - template - inline BOOST_DEDUCED_TYPENAME ::boost::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& - > - >, + template< class IteratorT, class ForwardRange > + inline BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, bool >::type - operator<(const SinglePassRange1& l, const SinglePassRange2& r) + operator!=( const ForwardRange& l, const iterator_range& r ) { - BOOST_RANGE_CONCEPT_ASSERT(( - boost::SinglePassRangeConcept)); - BOOST_RANGE_CONCEPT_ASSERT(( - boost::SinglePassRangeConcept)); - return iterator_range_detail::less_than(l, r); + return !boost::equal( l, r ); } - - template - inline BOOST_DEDUCED_TYPENAME ::boost::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& - > - >, + + template< class IteratorT, class ForwardRange > + inline BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, bool >::type - operator<=(const SinglePassRange1& l, const SinglePassRange2& r) + operator<( const ForwardRange& l, const iterator_range& r ) { - BOOST_RANGE_CONCEPT_ASSERT(( - boost::SinglePassRangeConcept)); - BOOST_RANGE_CONCEPT_ASSERT(( - boost::SinglePassRangeConcept)); - return iterator_range_detail::less_or_equal_than(l, r); + return iterator_range_detail::less_than( l, r ); } - template - inline BOOST_DEDUCED_TYPENAME ::boost::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& - > - >, + template< class IteratorT, class ForwardRange > + inline BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, bool >::type - operator>(const SinglePassRange1& l, const SinglePassRange2& r) + operator<=( const ForwardRange& l, const iterator_range& r ) { - BOOST_RANGE_CONCEPT_ASSERT(( - boost::SinglePassRangeConcept)); - BOOST_RANGE_CONCEPT_ASSERT(( - boost::SinglePassRangeConcept)); - return iterator_range_detail::greater_than(l, r); + return iterator_range_detail::less_or_equal_than( l, r ); } - template - inline BOOST_DEDUCED_TYPENAME ::boost::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& - > - >, + template< class IteratorT, class ForwardRange > + inline BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, bool >::type - operator>=(const SinglePassRange1& l, const SinglePassRange2& r) + operator>( const ForwardRange& l, const iterator_range& r ) { - BOOST_RANGE_CONCEPT_ASSERT(( - boost::SinglePassRangeConcept)); - BOOST_RANGE_CONCEPT_ASSERT(( - boost::SinglePassRangeConcept)); - return iterator_range_detail::greater_or_equal_than(l, r); + return iterator_range_detail::greater_than( l, r ); } + + template< class IteratorT, class ForwardRange > + inline BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, + bool + >::type + 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 BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, + bool + >::type + 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 BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, + bool + >::type + 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 BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, + bool + >::type + 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 BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, + bool + >::type + 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 BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, + bool + >::type + 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 BOOST_DEDUCED_TYPENAME boost::enable_if< + mpl::not_ >, + bool + >::type + 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 2c6a2a0..dcc20c6 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -194,6 +194,7 @@ test-suite range : [ range-test iterator_pair ] [ range-test iterator_range ] [ range-test iterator_range_drop ] + [ range-test iterator_range_equality_bug ] [ range-test iterator_range_hash ] [ range-test iterator_range_variant ] # [ range-test mfc : $(VC71_ROOT)/atlmfc/include ] diff --git a/test/iterator_range_equality_bug.cpp b/test/iterator_range_equality_bug.cpp new file mode 100644 index 0000000..eea47cb --- /dev/null +++ b/test/iterator_range_equality_bug.cpp @@ -0,0 +1,39 @@ +// 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/ +// +// As reported in https://groups.google.com/forum/#!msg/boost-developers-archive/6JVNg7ZPb4k/RAlvPUec4MAJ + +#include +#include +#include + +namespace boost +{ + enum {unnamed}; + struct S { + bool operator<(int) const {return false;} + bool operator==(int) const {return false;} + }; + template + bool foo(T i) + { + return i < unnamed || i == unnamed; + } +} + +int main() +{ + using boost::lambda::_1; + (void)(_1 == 42); + (void)(42 == _1); + + boost::foo(42); + boost::foo(boost::S()); +}