From ef161533538baa2779c1388f61488a20108c6783 Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Mon, 25 Feb 2013 22:31:52 +0000 Subject: [PATCH] Gather does not (in general) work with forward iterators, even though it does on some systems [SVN r83158] --- doc/gather.qbk | 16 ++++++++-------- include/boost/algorithm/gather.hpp | 17 +++++++++-------- test/gather_test1.cpp | 4 +--- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/doc/gather.qbk b/doc/gather.qbk index f46429a..b50e85a 100644 --- a/doc/gather.qbk +++ b/doc/gather.qbk @@ -22,13 +22,13 @@ There are two versions; one takes two iterators, and the other takes a range. `` namespace boost { namespace algorithm { -template -std::pair -gather ( ForwardIterator first, ForwardIterator last, ForwardIterator pivot, Pred pred ); +template +std::pair +gather ( BidirectionalIterator first, BidirectionalIterator last, BidirectionalIterator pivot, Pred pred ); -template -std::pair::type, typename boost::range_iterator::type> -gather ( ForwardRange &range, typename boost::range_iterator::type pivot, Pred pred ); +template +std::pair::type, typename boost::range_iterator::type> +gather ( const BidirectionalRange &range, typename boost::range_iterator::type pivot, Pred pred ); }} `` @@ -53,11 +53,11 @@ where `first` and `second` are the fields of the pair that is returned by the ca [heading Iterator Requirements] -`gather` work on all iterators except input or output iterators. +`gather` work on bidirectional iterators or better. This requirement comes from the usage of `stable_partition`, which requires bidirectional iterators. Some standard libraries (libstdc++ and libc++, for example) have implementations of `stable_partition` that work with forward iterators. If that is the case, then `gather` will work with forward iterators as well. [heading Storage Requirements] -`gather` uses stable_partition, which will attempt to allocate temporary memory, but will work in-situ if there is none available. +`gather` uses `stable_partition`, which will attempt to allocate temporary memory, but will work in-situ if there is none available. [heading Complexity] diff --git a/include/boost/algorithm/gather.hpp b/include/boost/algorithm/gather.hpp index ec7a7a7..944bc94 100644 --- a/include/boost/algorithm/gather.hpp +++ b/include/boost/algorithm/gather.hpp @@ -80,9 +80,10 @@ namespace boost { namespace algorithm { */ template < - typename ForwardIterator, // Iter models ForwardIterator - typename Pred> // Pred models UnaryPredicate -std::pair gather ( ForwardIterator first, ForwardIterator last, ForwardIterator pivot, Pred pred ) + typename BidirectionalIterator, // Iter models BidirectionalIterator + typename Pred> // Pred models UnaryPredicate +std::pair gather + ( BidirectionalIterator first, BidirectionalIterator last, BidirectionalIterator pivot, Pred pred ) { // The first call partitions everything up to (but not including) the pivot element, // while the second call partitions the rest of the sequence. @@ -99,14 +100,14 @@ std::pair gather ( ForwardIterator first, Forwa */ template < - typename ForwardRange, // + typename BidirectionalRange, // typename Pred> // Pred models UnaryPredicate std::pair< - typename boost::range_iterator::type, - typename boost::range_iterator::type> + typename boost::range_iterator::type, + typename boost::range_iterator::type> gather ( - ForwardRange &range, - typename boost::range_iterator::type pivot, + const BidirectionalRange &range, + typename boost::range_iterator::type pivot, Pred pred ) { return boost::algorithm::gather ( boost::begin ( range ), boost::end ( range ), pivot, pred ); diff --git a/test/gather_test1.cpp b/test/gather_test1.cpp index 0e57b6e..28f63b5 100644 --- a/test/gather_test1.cpp +++ b/test/gather_test1.cpp @@ -55,14 +55,12 @@ void test_iterators ( Iterator first, Iterator last, Predicate comp, std::size_t template void test_iterator_types ( const Container &c, Predicate comp, std::size_t offset ) { typedef std::vector vec; - typedef forward_iterator FI; + typedef bidirectional_iterator BDI; typedef random_access_iterator RAI; vec v; v.assign ( c.begin (), c.end ()); - test_iterators ( FI ( v.begin ()), FI ( v.end ()), comp, offset ); - v.assign ( c.begin (), c.end ()); test_iterators ( BDI ( v.begin ()), BDI ( v.end ()), comp, offset ); v.assign ( c.begin (), c.end ()); test_iterators ( RAI ( v.begin ()), RAI ( v.end ()), comp, offset );