The C++11 algorithms std::is_sorted and std::is_sorted_until both require ForwardIterators. However, the Boost.Range version boost::is_sorted only requires SinglePassRanges which corresponds to InputIterators. In particular, it delegates to an an iterator-based implementation like this:
template<class Iterator, class Comp>
inline Iterator is_sorted_until (Iterator first, Iterator last, Comp c) {
if (first == last)
return last;
Iterator it = first; ++it;
for (; it != last; first = it, ++it)
if (c(*it, *first))
return it;
return it;
}
Here we see a *first iterator dereference that happens after the ++it iterator increment. This means that Iterator should have ForwardIterator as its required category. Why? Because the Standard says so in
24.2.3 Input iterators [input.iterators]/p2 (see table 107 with the line about ++r)
post: any copies of the previous value of
rare no longer required either to be dereferenceable or to be in the domain of==.
Note: this is not intended to be "a proof by single example", but it seems that any comparison based algorithm (e.g. adjacent_find) would necessarily require forward iterators in order to be able to make a comparison between two iterators.
Question: why doesn't the Boost.Range version of is_sorted require the stronger concept of ForwardRange (and ForwardIterator for its low-level routines) that is required by std::is_sorted? Is it a bug in Boost.Range?