diff --git a/include/boost/range/iterator_range_core.hpp b/include/boost/range/iterator_range_core.hpp index 7ef7523..438f38c 100755 --- a/include/boost/range/iterator_range_core.hpp +++ b/include/boost/range/iterator_range_core.hpp @@ -71,6 +71,24 @@ namespace boost boost::begin(r), boost::end(r) ); } + + template< class Left, class Right > + inline bool greater_than( const Left& l, const Right& r ) + { + return less_than(r,l); + } + + template< class Left, class Right > + inline bool less_or_equal_than( const Left& l, const Right& r ) + { + return !iterator_range_detail::less_than(r,l); + } + + template< class Left, class Right > + inline bool greater_or_equal_than( const Left& l, const Right& r ) + { + return !iterator_range_detail::less_than(l,r); + } // This version is maintained since it is used in other boost libraries // such as Boost.Assign @@ -271,6 +289,21 @@ namespace boost { 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 @@ -370,6 +403,27 @@ namespace boost { return iterator_range_detail::less_than( l, r ); } + + template< class IteratorT, class ForwardRange > + inline bool operator<=( const ForwardRange& l, + const iterator_range& r ) + { + 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 ) + { + return iterator_range_detail::greater_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 @@ -416,6 +470,48 @@ namespace boost { 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 diff --git a/test/iterator_range.cpp b/test/iterator_range.cpp index 7c53a8b..8e9f380 100644 --- a/test/iterator_range.cpp +++ b/test/iterator_range.cpp @@ -24,6 +24,7 @@ #include #include #include +#include void check_reference_type(); @@ -102,17 +103,127 @@ void check_iterator_range() check_reference_type(); } +namespace iterator_range_test_detail +{ + struct less + { + template< class Left, class Right > + bool operator()(const Left& l, const Right& r) const + { + return l < r; + } + }; + + struct greater + { + template< class Left, class Right > + bool operator()(const Left& l, const Right& r) const + { + return l > r; + } + }; + + struct less_or_equal + { + template< class Left, class Right > + bool operator()(const Left& l, const Right& r) const + { + return l <= r; + } + }; + + struct greater_or_equal + { + template< class Left, class Right > + bool operator()(const Left& l, const Right& r) const + { + return l >= r; + } + }; + + struct equal_to + { + template< class Left, class Right > + bool operator()(const Left& l, const Right& r) const + { + return l == r; + } + }; + + struct not_equal_to + { + template< class Left, class Right > + bool operator()(const Left& l, const Right& r) const + { + return l != r; + } + }; + + template< class Pred > + void check_iterator_range_operators_impl(Pred pred) + { + std::vector vals; + vals.push_back(std::string()); + vals.push_back("a"); + vals.push_back("b"); + vals.push_back("z"); + vals.push_back("ab"); + vals.push_back("ba"); + vals.push_back("abc"); + vals.push_back("cba"); + vals.push_back("aa"); + vals.push_back("aaa"); + vals.push_back("aab"); + vals.push_back("bba"); + + typedef std::string::const_iterator citer; + typedef boost::iterator_range iter_range; + + typedef std::vector::const_iterator value_const_iterator; + value_const_iterator first_val = vals.begin(); + value_const_iterator last_val = vals.end(); + + for (value_const_iterator left_it = first_val; left_it != last_val; ++left_it) + { + const std::string& leftValue = *left_it; + for (value_const_iterator right_it = first_val; right_it != last_val; ++right_it) + { + const std::string& rightValue = *right_it; + iter_range left = boost::make_iterator_range(leftValue); + iter_range right = boost::make_iterator_range(rightValue); + + const bool reference = pred(leftValue, rightValue); + + BOOST_CHECK_EQUAL( pred(left, right), reference ); + BOOST_CHECK_EQUAL( pred(left, rightValue), reference ); + BOOST_CHECK_EQUAL( pred(leftValue, right), reference ); + } + } + } +} // namespace iterator_range_test_detail + +template +inline void check_iterator_range_operator() +{ + iterator_range_test_detail::check_iterator_range_operators_impl( + Pred()); +} boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) { boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" ); - test->add( BOOST_TEST_CASE( &check_iterator_range ) ); + test->add(BOOST_TEST_CASE(&check_iterator_range)); + test->add(BOOST_TEST_CASE(&check_iterator_range_operator)); + test->add(BOOST_TEST_CASE(&check_iterator_range_operator)); + test->add(BOOST_TEST_CASE(&check_iterator_range_operator)); + test->add(BOOST_TEST_CASE(&check_iterator_range_operator)); + test->add(BOOST_TEST_CASE(&check_iterator_range_operator)); + test->add(BOOST_TEST_CASE(&check_iterator_range_operator)); return test; } - // // // Check that constness is propgated correct from diff --git a/test/test_driver/range_return_test_driver.hpp b/test/test_driver/range_return_test_driver.hpp index bcd2533..3dfd2a2 100644 --- a/test/test_driver/range_return_test_driver.hpp +++ b/test/test_driver/range_return_test_driver.hpp @@ -371,7 +371,7 @@ namespace boost Container reference(cont); Container test(cont); - + iterator_t range_result = policy.test_iter(test); iterator_t reference_it = policy.reference(reference); @@ -391,7 +391,8 @@ namespace boost Container reference(cont); Container test_cont(cont); - range_return_t range_result = test_range_t()(policy, test_cont); + test_range_t test_range_fn; + range_return_t range_result = test_range_fn(policy, test_cont); iterator_t reference_it = policy.reference(reference); check_results::test(test_cont, reference,