Title
Requirements for partition() and stable_partition() too strong
Status
c++11
Section
[alg.partitions]
Submitter
Sean Parent, Joe Gottman

Created on 2005-05-04.00:00:00 last changed 154 months ago

Messages

Date: 2010-10-21.18:28:33

[ Mont Tremblant: Moved to Open, request motivation and use cases by next meeting. Sean provided further rationale by post-meeting mailing. ]

Date: 2010-10-21.18:28:33

Rationale:

Partition is a "foundation" algorithm useful in many contexts (like sorting as just one example) - my motivation for extending it to include forward iterators is foward_list - without this extension you can't partition an foward_list (without writing your own partition). Holes like this in the standard library weaken the argument for generic programming (ideally I'd be able to provide a library that would refine std::partition() to other concepts without fear of conflicting with other libraries doing the same - but that is a digression). I consider the fact that partition isn't defined to work for ForwardIterator a minor embarrassment.

Date: 2010-10-21.18:28:33

Proposed resolution:

Change 25.2.12 from

template<class BidirectionalIterator, class Predicate> 
BidirectionalIterator partition(BidirectionalIterato r first, 
                                BidirectionalIterator last, 
                                Predicate pred); 

to

template<class ForwardIterator, class Predicate> 
ForwardIterator partition(ForwardIterator first, 
                          ForwardIterator last, 
                          Predicate pred); 

Change the complexity from

At most (last - first)/2 swaps are done. Exactly (last - first) applications of the predicate are done.

to

If ForwardIterator is a bidirectional_iterator, at most (last - first)/2 swaps are done; otherwise at most (last - first) swaps are done. Exactly (last - first) applications of the predicate are done.

Date: 2010-10-21.18:28:33

[ 2009-07 Frankfurt ]

Hinnant: if you want to partition your std::forward_list, you'll need partition() to accept ForwardIterators.

No objection to Ready.

Move to Ready.

Date: 2009-04-30.00:00:00

[ 2009-04-30 Alisdair adds: ]

Now we have concepts this is easier to express!

Proposed resolution:

Add the following signature to:

Header <algorithm> synopsis [algorithms.syn]
p3 Partitions [alg.partitions]

 template<ForwardIterator Iter, Predicate<auto, Iter::value_type> Pred>
   requires ShuffleIterator<Iter>
         && CopyConstructible<Pred>
   Iter partition(Iter first, Iter last, Pred pred);

Update p3 Partitions [alg.partitions]:

Complexity: At most (last - first)/2 swaps. Exactly last - first applications of the predicate are done. If Iter satisfies BidirectionalIterator, at most (last - first)/2 swaps. Exactly last - first applications of the predicate are done.

If Iter merely satisfied ForwardIterator at most (last - first) swaps are done. Exactly (last - first) applications of the predicate are done.

[Editorial note: I looked for existing precedent in how we might call out distinct overloads overloads from a set of constrained templates, but there is not much existing practice to lean on. advance/distance were the only algorithms I could find, and that wording is no clearer.]

Date: 2005-05-04.00:00:00

Problem: The iterator requirements for partition() and stable_partition() [25.2.12] are listed as BidirectionalIterator, however, there are efficient algorithms for these functions that only require ForwardIterator that have been known since before the standard existed. The SGI implementation includes these (see http://www.sgi.com/tech/stl/partition.html and http://www.sgi.com/tech/stl/stable_partition.html).

History
Date User Action Args
2011-08-23 20:07:26adminsetstatus: wp -> c++11
2010-10-21 18:28:33adminsetmessages: + msg2855
2010-10-21 18:28:33adminsetmessages: + msg2854
2010-10-21 18:28:33adminsetmessages: + msg2853
2010-10-21 18:28:33adminsetmessages: + msg2852
2010-10-21 18:28:33adminsetmessages: + msg2851
2005-05-04 00:00:00admincreate