From 26edcb7b513fd2ff1d9a8cdef6657bd3ed007732 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Thu, 12 Jul 2012 03:25:58 +0000 Subject: [PATCH] Fix behavior of is_sorted_until; thanks to Michel Morin for the report [SVN r79433] --- doc/ordered-hpp.qbk | 4 +++- include/boost/algorithm/cxx11/is_sorted.hpp | 16 ++++++---------- test/ordered_test.cpp | 8 ++++---- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/doc/ordered-hpp.qbk b/doc/ordered-hpp.qbk index a7632ac..687066a 100644 --- a/doc/ordered-hpp.qbk +++ b/doc/ordered-hpp.qbk @@ -38,7 +38,9 @@ Iterator requirements: The `is_sorted` functions will work on all kinds of itera [heading is_sorted_until] -The function `is_sorted_until(sequence, predicate)` compares each sequential pair of elements in the sequence, checking if they satisfy the predicate. it returns the first element of the sequence that does not satisfy the predicate with its' predecessor. In short, it returns the element in the sequence that is "out of order". If all adjacent pairs satisfy the predicate, then it will return one past the last element of the sequence. +If `distance(first, last) < 2`, then `is_sorted ( first, last )` returns `last`. Otherwise, it returns the last iterator i in [first,last] for which the range [first,i) is sorted. + +In short, it returns the element in the sequence that is "out of order". If the entire sequence is sorted (according to the predicate), then it will return `last`. `` namespace boost { namespace algorithm { diff --git a/include/boost/algorithm/cxx11/is_sorted.hpp b/include/boost/algorithm/cxx11/is_sorted.hpp index 20180b7..b0505d3 100644 --- a/include/boost/algorithm/cxx11/is_sorted.hpp +++ b/include/boost/algorithm/cxx11/is_sorted.hpp @@ -46,7 +46,7 @@ using std::is_sorted; // Section 25.4.1.5 ForwardIterator next = first; while ( ++next != last ) { - if ( !p ( *first, *next )) + if ( p ( *next, *first )) return next; first = next; } @@ -63,7 +63,7 @@ using std::is_sorted; // Section 25.4.1.5 ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last ) { typedef typename std::iterator_traits::value_type value_type; - return boost::algorithm::is_sorted_until ( first, last, std::less_equal()); + return boost::algorithm::is_sorted_until ( first, last, std::less()); } @@ -125,10 +125,6 @@ using std::is_sorted; // Section 25.4.1.5 return boost::algorithm::is_sorted_until ( boost::begin ( range ), boost::end ( range )); } -namespace detail { - typedef struct { typedef bool type; } bool_; -}; - /// \fn is_sorted ( const R &range, Pred p ) /// \return whether or not the entire range R is sorted /// (according to the comparison predicate 'p'). @@ -173,7 +169,7 @@ namespace detail { bool is_increasing ( ForwardIterator first, ForwardIterator last ) { typedef typename std::iterator_traits::value_type value_type; - return boost::algorithm::is_sorted (first, last, std::less_equal()); + return boost::algorithm::is_sorted (first, last, std::less()); } @@ -206,7 +202,7 @@ namespace detail { bool is_decreasing ( ForwardIterator first, ForwardIterator last ) { typedef typename std::iterator_traits::value_type value_type; - return boost::algorithm::is_sorted (first, last, std::greater_equal()); + return boost::algorithm::is_sorted (first, last, std::greater()); } /// \fn is_decreasing ( const R &range ) @@ -238,7 +234,7 @@ namespace detail { bool is_strictly_increasing ( ForwardIterator first, ForwardIterator last ) { typedef typename std::iterator_traits::value_type value_type; - return boost::algorithm::is_sorted (first, last, std::less()); + return boost::algorithm::is_sorted (first, last, std::less_equal()); } /// \fn is_strictly_increasing ( const R &range ) @@ -269,7 +265,7 @@ namespace detail { bool is_strictly_decreasing ( ForwardIterator first, ForwardIterator last ) { typedef typename std::iterator_traits::value_type value_type; - return boost::algorithm::is_sorted (first, last, std::greater()); + return boost::algorithm::is_sorted (first, last, std::greater_equal()); } /// \fn is_strictly_decreasing ( const R &range ) diff --git a/test/ordered_test.cpp b/test/ordered_test.cpp index 42e1219..8265c5b 100644 --- a/test/ordered_test.cpp +++ b/test/ordered_test.cpp @@ -54,10 +54,10 @@ test_ordered(void) BOOST_CHECK ( ba::is_sorted_until ( a_range(strictlyIncreasingValues), std::less()) == boost::end(strictlyIncreasingValues)); // Check for const and non-const arrays - BOOST_CHECK ( ba::is_sorted_until ( b_e(constantValues), std::less()) != a_end(constantValues)); - BOOST_CHECK ( ba::is_sorted_until ( a_range(constantValues), std::less()) != boost::end(constantValues)); - BOOST_CHECK ( ba::is_sorted_until ( b_e(nonConstantArray), std::less()) != a_end(nonConstantArray)); - BOOST_CHECK ( ba::is_sorted_until ( a_range(nonConstantArray), std::less()) != boost::end(nonConstantArray)); + BOOST_CHECK ( ba::is_sorted_until ( b_e(constantValues), std::less()) == a_end(constantValues)); + BOOST_CHECK ( ba::is_sorted_until ( a_range(constantValues), std::less()) == boost::end(constantValues)); + BOOST_CHECK ( ba::is_sorted_until ( b_e(nonConstantArray), std::less()) == a_end(nonConstantArray)); + BOOST_CHECK ( ba::is_sorted_until ( a_range(nonConstantArray), std::less()) == boost::end(nonConstantArray)); BOOST_CHECK ( ba::is_sorted_until ( b_e(randomValues), std::less()) == &randomValues[2] ); BOOST_CHECK ( ba::is_sorted_until ( b_e(randomValues)) == &randomValues[2] );