|
Boost-Commit : |
From: chris_at_[hidden]
Date: 2008-04-30 12:40:41
Author: chrisj
Date: 2008-04-30 12:40:40 EDT (Wed, 30 Apr 2008)
New Revision: 44937
URL: http://svn.boost.org/trac/boost/changeset/44937
Log:
Use 'SwappableIterator' much more in clib-algorithms.tex, and add issue 29 documenting the change
Added:
sandbox/committee/concepts/issues/issues/issue29.xml (contents, props changed)
Text files modified:
sandbox/committee/concepts/stdlib/clib-algorithms.tex | 124 ++++++++++++++++++++++++---------------
1 files changed, 76 insertions(+), 48 deletions(-)
Added: sandbox/committee/concepts/issues/issues/issue29.xml
==============================================================================
--- (empty file)
+++ sandbox/committee/concepts/issues/issues/issue29.xml 2008-04-30 12:40:40 EDT (Wed, 30 Apr 2008)
@@ -0,0 +1,37 @@
+<?xml version='1.0' encoding='iso-8859-1' standalone='no'?>
+<!DOCTYPE issue SYSTEM "lwg-issue.dtd" [
+ <!ENTITY nbsp " ">
+] >
+
+<issue num="29" status="New">
+<title>Concepts on mutating algorithms are confusing</title>
+<section><sref ref="[algorithms]"/></section>
+<submitter>Christopher Jefferson</submitter>
+<date>29 Apr 2008</date>
+
+<discussion>
+ <p>The concepts on the mutating algorithms are confusing and leak too much about the implementation. For example <tt>push_heap</tt> requires <tt>MoveConstructible</tt> and <tt>MoveAssignable</tt>, but <tt>pop_heap</tt> also requires <tt>Swappable</tt>. These arise from the functions used in practical implementations, but mean using them in constrained templates requires looking up the exact concepts required. At the cost of a slightly less efficient implementation, all of the following algorithms can be implemented using just <tt>IteratorSwappable</tt>, along with a predicate or <tt>LessThanComparable</tt>:
+ </p>
+
+ <p>
+ <tt>reverse, rotate, random_shuffle, partition, stable_partition, sort, stable_sort, partial_sort, nth_element, inplace_merge, push_heap, pop_heap, make_heap, sort_heap, next_permutation, prev_permutation</tt>
+</p>
+
+
+<p>Further, <tt>partial_sort_copy</tt> can be implemented requiring only <tt>SwappableIterator</tt> on the result array. All of these changes have been tested with a modification of libstdc++. Of course implementations can implement optimised versions of these methods when <tt>MoveConstructable</tt> and <tt>MoveAssignable</tt> are available.
+</p>
+</discussion>
+
+<resolution>
+ <p>
+ Replace any references to <tt>MoveConstructible, MoveAssignable</tt> and <tt>Swappable</tt> in the requires section of <tt>reverse, rotate, random_shuffle, partition, stable_partition, sort, stable_sort, partial_sort, nth_element, inplace_merge, push_heap, pop_heap, make_heap, sort_heap, next_permutation, prev_permutation</tt> with <tt>SwappableIterator</tt>, and remove all references to <tt>SameType</tt>. Further, replace the concepts:
+ </p>
+
+ <pre>
+ <tt>SameType<RAIter::value_type&, RAIter::reference> && Swappable<RAIter::value_type> &&
+ MoveConstructible<RAIter::value_type> && MoveAssignable<RAIter::value_type> &&</tt>
+ </pre>
+
+ <p> with <tt>SwappableIterator<RAIter></tt> in both copies if <tt>partial_sort_copy</tt></p>
+</resolution>
+</issue>
Modified: sandbox/committee/concepts/stdlib/clib-algorithms.tex
==============================================================================
--- sandbox/committee/concepts/stdlib/clib-algorithms.tex (original)
+++ sandbox/committee/concepts/stdlib/clib-algorithms.tex 2008-04-30 12:40:40 EDT (Wed, 30 Apr 2008)
@@ -334,14 +334,16 @@
OutIter @\farg{result}@, Pred @\farg{pred}@);
template<MutableBidirectionalIterator Iter>
- requires SameType<Iter::value_type&, Iter::reference> && Swappable<Iter::value_type>
+ requires @\removedCC{SameType<Iter::value_type\&, Iter::reference> \&\& Swappable<Iter::value_type>}@
+ @\addedCC{SwappableIterator<Iter>}@
void reverse(Iter @\farg{first}@, Iter @\farg{last}@);
template<BidirectionalIterator InIter, OutputIterator<auto, InIter::value_type> OutIter>
OutIter reverse_copy(InIter @\farg{first}@,
InIter @\farg{last}@, OutIter @\farg{result}@);
template<ForwardIterator Iter>
- requires SameType<Iter::value_type&, Iter::reference> && Swappable<Iter::value_type>
+ requires @\removedCC{SameType<Iter::value_type\&, Iter::reference> \&\& Swappable<Iter::value_type>}@
+ @\addedCC{SwappableIterator<Iter>}@
void rotate(Iter @\farg{first}@, Iter @\farg{middle}@,
Iter @\farg{last}@);
template<ForwardIterator InIter, OutputIterator<auto, InIter::value_type> OutIter>
@@ -349,12 +351,13 @@
InIter @\farg{last}@, OutIter @\farg{result}@);
template<MutableRandomAccessIterator Iter>
- requires SameType<Iter::value_type&, Iter::reference> && Swappable<Iter::value_type>
+ requires @\removedCC{SameType<Iter::value_type\&, Iter::reference> \&\& Swappable<Iter::value_type>}@
+ @\addedCC{SwappableIterator<Iter>}@
void random_shuffle(Iter @\farg{first}@,
Iter @\farg{last}@);
template<MutableRandomAccessIterator Iter, Callable<auto, Iter::difference_type> Rand>
- requires SameType<Iter::value_type&, Iter::reference> && Swappable<Iter::value_type> &&
- Convertible<Rand::result_type, Iter::difference_type>
+ requires @\removedCC{SameType<Iter::value_type\&, Iter::reference> \&\& Swappable<Iter::value_type> \&\& }@
+ @\addedCC{SwappableIterator<Iter> \&\&}@ Convertible<Rand::result_type, Iter::difference_type>
void random_shuffle(Iter @\farg{first}@,
Iter @\farg{last}@,
Rand& @\farg{rand}@);
@@ -365,58 +368,67 @@
@\textcolor{black}{// \ref{alg.partitions}, partitions:}@
template<BidirectionalIterator Iter, Predicate<auto, Iter::reference> Pred>
- @\color{addclr}@requires SameType<Iter::value_type&, Iter::reference> && Swappable<Iter::value_type>
+ @\color{addclr}@requires @\removedCC{SameType<Iter::value_type\&, Iter::reference> \&\& Swappable<Iter::value_type>}@
+ @\addedCC{SwappableIterator<Iter>}@
Iter partition(Iter @\farg{first}@, Iter @\farg{last}@, Pred @\farg{pred}@);
template<MutableBidirectionalIterator Iter, Predicate<auto Iter::reference> Pred>
- requires SameType<Iter::value_type&, Iter::reference> && Swappable<Iter::value_type> &&
- MoveConstructible<Iter::value_type> && MoveAssignable<Iter::value_type>
+ requires @\removedCC{SameType<Iter::value_type\&, Iter::reference> \&\& Swappable<Iter::value_type> \&\&}@
+ @\removedCC{MoveConstructible<Iter::value_type> \&\& MoveAssignable<Iter::value_type>}@
+ @\addedCC{SwappableIterator<Iter>}@
Iter stable_partition(Iter @\farg{first}@, Iter @\farg{last}@, Pred @\farg{pred}@);
@\textcolor{black}{// \ref{alg.sorting}, sorting and related operations:}@
@\textcolor{black}{// \ref{alg.sort}, sorting:}@
template<MutableRandomAccessIterator Iter>
- requires SameType<Iter::value_type&, Iter::reference> && Swappable<Iter::value_type> &&
- MoveConstructible<Iter::value_type> && MoveAssignable<Iter::value_type> &&
+ requires @\removedCC{SameType<Iter::value_type\&, Iter::reference> \&\& Swappable<Iter::value_type> \&\&}@
+ @\removedCC{MoveConstructible<Iter::value_type> \&\& MoveAssignable<Iter::value_type> \&\&}@
+ @\addedCC{SwappableIterator<Iter> \&\&}@
LessThanComparable<Iter::value_type>
void sort(Iter @\farg{first}@, Iter @\farg{last}@);
template<MutableRandomAccessIterator Iter,
Predicate<auto, Iter::value_type, Iter::value_type> Compare>
- requires SameType<Iter::value_type&, Iter::reference> && Swappable<Iter::value_type> &&
- MoveConstructible<Iter::value_type> && MoveAssignable<Iter::value_type>
+ requires @\removedCC{SameType<Iter::value_type\&, Iter::reference> \&\& Swappable<Iter::value_type> \&\&}@
+ @\removedCC{MoveConstructible<Iter::value_type> \&\& MoveAssignable<Iter::value_type>}@
+ @\addedCC{SwappableIterator<Iter>}@
void sort(Iter @\farg{first}@, Iter @\farg{last}@,
Compare @\farg{comp}@);
template<MutableRandomAccessIterator Iter>
- requires SameType<Iter::value_type&, Iter::reference> && Swappable<Iter::value_type> &&
- MoveConstructible<Iter::value_type> && MoveAssignable<Iter::value_type> &&
+ requires @\removedCC{SameType<Iter::value_type\&, Iter::reference> \&\& Swappable<Iter::value_type> \&\&}@
+ @\removedCC{MoveConstructible<Iter::value_type> \&\& MoveAssignable<Iter::value_type> \&\&}@
+ @\addedCC{SwappableIterator<Iter> \&\&}@
LessThanComparable<Iter::value_type>
void stable_sort(Iter @\farg{first}@, Iter @\farg{last}@);
template<MutableRandomAccessIterator Iter,
Predicate<auto, Iter::value_type, Iter::value_type> Compare>
- requires SameType<Iter::value_type&, Iter::reference> && Swappable<Iter::value_type> &&
- MoveConstructible<Iter::value_type> && MoveAssignable<Iter::value_type>
+ requires @\removedCC{SameType<Iter::value_type\&, Iter::reference> \&\& Swappable<Iter::value_type> \&\&}@
+ @\removedCC{MoveConstructible<Iter::value_type> \&\& MoveAssignable<Iter::value_type>}@
+ @\addedCC{SwappableIterator<Iter>}@
void stable_sort(Iter @\farg{first}@, Iter @\farg{last}@,
Compare @\farg{comp}@);
template<MutableRandomAccessIterator Iter>
- requires SameType<Iter::value_type&, Iter::reference> && Swappable<Iter::value_type> &&
- MoveConstructible<Iter::value_type> && MoveAssignable<Iter::value_type> @\addedCC{\&\&}@
+ requires @\removedCC{SameType<Iter::value_type\&, Iter::reference> \&\& Swappable<Iter::value_type> \&\&}@
+ @\removedCC{MoveConstructible<Iter::value_type> \&\& MoveAssignable<Iter::value_type>}@
+ @\addedCC{SwappableIterator<Iter>}@ @\addedCC{\&\&}@
@\addedCC{LessThanComparable<Iter::value_type>}@
void partial_sort(Iter @\farg{first}@,
Iter @\farg{middle}@,
Iter @\farg{last}@);
template<MutableRandomAccessIterator Iter,
Predicate<auto, Iter::value_type, Iter::value_type> Compare>
- requires SameType<Iter::value_type&, Iter::reference> && Swappable<Iter::value_type> &&
- MoveConstructible<Iter::value_type> && MoveAssignable<Iter::value_type>
+ requires @\removedCC{SameType<Iter::value_type\&, Iter::reference> \&\& Swappable<Iter::value_type> \&\&}@
+ @\removedCC{MoveConstructible<Iter::value_type> \&\& MoveAssignable<Iter::value_type>}@
+ @\addedCC{SwappableIterator<Iter>}@
void partial_sort(Iter @\farg{first}@,
Iter @\farg{middle}@,
Iter @\farg{last}@,
Compare @\farg{comp}@);
template<InputIterator InIter, MutableRandomAccessIterator RAIter>
requires CopyAssignable<RAIter::reference, InIter::value_type> &&
- SameType<RAIter::value_type&, RAIter::reference> && Swappable<RAIter::value_type> &&
- MoveConstructible<RAIter::value_type> && MoveAssignable<RAIter::value_type> &&
+ @\removedCC{SameType<RAIter::value_type\&, RAIter::reference> \&\& Swappable<RAIter::value_type> \&\&}@
+ @\removedCC{MoveConstructible<RAIter::value_type> \&\& MoveAssignable<RAIter::value_type> \&\&}@
+ @\addedCC{SwappableIterator<RAIter> \&\&}@
HasLess<InIter::value_type, RAIter::value_type> &&
HasLess<RAIter::value_type, InIter::value_type> &&
HasLess<RAIter::value_type>
@@ -424,8 +436,9 @@
RAIter @\farg{result_first}@, RAIter @\farg{result_last}@);
template<InputIterator InIter, MutableRandomAccessIterator RAIter, class Compare>
requires CopyAssignable<RAIter::reference, InIter::value_type> &&
- SameType<RAIter::value_type&, RAIter::reference> && Swappable<RAIter::value_type> &&
- MoveConstructible<RAIter::value_type> && MoveAssignable<RAIter::value_type> &&
+ @\removedCC{SameType<RAIter::value_type\&, RAIter::reference> \&\& Swappable<RAIter::value_type> \&\&}@
+ @\removedCC{MoveConstructible<RAIter::value_type> \&\& MoveAssignable<RAIter::value_type> \&\&}@
+ @\addedCC{SwappableIterator<RAIter> \&\&}@
Predicate<Compare, InIter::value_type, RAIter::value_type> &&
Predicate<Compare, RAIter::value_type, InIter::value_type> &&
Predicate<Compare, RAIter::value_type>
@@ -447,15 +460,17 @@
Compare @\farg{comp}@);
template<MutableRandomAccessIterator Iter>
- requires SameType<Iter::value_type&, Iter::reference> && Swappable<Iter::value_type> &&
- MoveConstructible<Iter::value_type> && MoveAssignable<Iter::value_type> &&
+ requires @\removedCC{SameType<Iter::value_type\&, Iter::reference> \&\& Swappable<Iter::value_type> \&\&}@
+ @\removedCC{MoveConstructible<Iter::value_type> \&\& MoveAssignable<Iter::value_type> \&\&}@
+ @\addedCC{SwappableIterator<Iter> \&\&}@
LessThanComparable<Iter::value_type>
void nth_element(Iter @\farg{first}@, Iter @\farg{nth}@,
Iter @\farg{last}@);
template<MutableRandomAccessIterator Iter,
Predicate<auto, Iter::value_type, Iter::value_type> Compare>
- requires SameType<Iter::value_type&, Iter::reference> && Swappable<Iter::value_type> &&
- MoveConstructible<Iter::value_type> && MoveAssignable<Iter::value_type>
+ requires @\removedCC{SameType<Iter::value_type\&, Iter::reference> \&\& Swappable<Iter::value_type> \&\&}@
+ @\removedCC{MoveConstructible<Iter::value_type> \&\& MoveAssignable<Iter::value_type>}@
+ @\addedCC{SwappableIterator<Iter>}@
void nth_element(Iter @\farg{first}@, Iter @\farg{nth}@,
Iter @\farg{last}@, Compare @\farg{comp}@);
@@ -518,16 +533,18 @@
OutIter @\farg{result}@, Compare @\farg{comp}@);
template<MutableBidirectionalIterator Iter>
- requires SameType<Iter::value_type&, Iter::reference> && Swappable<Iter::value_type> &&
- MoveConstructible<Iter::value_type> && MoveAssignable<Iter::value_type> &&
+ requires @\removedCC{SameType<Iter::value_type\&, Iter::reference> \&\& Swappable<Iter::value_type> \&\&}@
+ @\removedCC{MoveConstructible<Iter::value_type> \&\& MoveAssignable<Iter::value_type> \&\&}@
+ @\addedCC{SwappableIterator<Iter> \&\&}@
LessThanComparable<Iter::value_type>
void inplace_merge(Iter @\farg{first}@,
Iter @\farg{middle}@,
Iter @\farg{last}@);
template<MutableBidirectionalIterator Iter,
Predicate<auto, Iter::value_type, Iter::value_type> Compare>
- requires SameType<Iter::value_type&, Iter::reference> && Swappable<Iter::value_type> &&
- MoveConstructible<Iter::value_type> && MoveAssignable<Iter::value_type>
+ requires @\removedCC{SameType<Iter::value_type\&, Iter::reference> \&\& Swappable<Iter::value_type> \&\&}@
+ @\removedCC{MoveConstructible<Iter::value_type> \&\& MoveAssignable<Iter::value_type>}@
+ @\addedCC{SwappableIterator<Iter>}@
void inplace_merge(Iter @\farg{first}@,
Iter @\farg{middle}@,
Iter @\farg{last}@, Compare @\farg{comp}@);
@@ -606,44 +623,51 @@
@\textcolor{black}{// \ref{alg.heap.operations}, heap operations:}@
template<MutableRandomAccessIterator Iter>
- requires MoveConstructible<Iter::value_type> && MoveAssignable<Iter::value_type> &&
+ requires @\removedCC{MoveConstructible<Iter::value_type> \&\& MoveAssignable<Iter::value_type> \&\&}@
+ @\addedCC{SwappableIterator<Iter> \&\&}@
LessThanComparable<Iter::value_type>
void push_heap(Iter @\farg{first}@, Iter @\farg{last}@);
template<MutableRandomAccessIterator Iter,
Predicate<auto, Iter::value_type, Iter::value_type> Compare>
- requires MoveConstructible<Iter::value_type> && MoveAssignable<Iter::value_type>
+ requires @\removedCC{MoveConstructible<Iter::value_type> \&\& MoveAssignable<Iter::value_type>}@
+ @\addedCC{SwappableIterator<Iter>}@
void push_heap(Iter @\farg{first}@, Iter @\farg{last}@,
Compare @\farg{comp}@);
template<MutableRandomAccessIterator Iter>
- requires MoveConstructible<Iter::value_type> && MoveAssignable<Iter::value_type> &&
- Swappable<Iter::value_type> && LessThanComparable<Iter::value_type>
+ requires @\removedCC{MoveConstructible<Iter::value_type> \&\& MoveAssignable<Iter::value_type> \&\&}@
+ @\removedCC{Swappable<Iter::value_type>}@
+ @\addedCC{SwappableIterator<Iter>}@ && LessThanComparable<Iter::value_type>
void pop_heap(Iter @\farg{first}@, Iter @\farg{last}@);
template<MutableRandomAccessIterator Iter,
Predicate<auto, Iter::value_type, Iter::value_type> Compare>
- requires MoveConstructible<Iter::value_type> && MoveAssignable<Iter::value_type> &&
- Swappable<Iter::value_type>
+ requires @\removedCC{MoveConstructible<Iter::value_type> \&\& MoveAssignable<Iter::value_type> \&\&}@
+ @\removedCC{Swappable<Iter::value_type>}@
+ @\addedCC{SwappableIterator<Iter>}@
void pop_heap(Iter @\farg{first}@, Iter @\farg{last}@,
Compare @\farg{comp}@);
template<MutableRandomAccessIterator Iter>
- requires MoveConstructible<Iter::value_type> && MoveAssignable<Iter::value_type> &&
+ requires @\removedCC{MoveConstructible<Iter::value_type> \&\& MoveAssignable<Iter::value_type> \&\&}@
+ @\addedCC{SwappableIterator<Iter> \&\&}@
LessThanComparable<Iter::value_type>
void make_heap(Iter @\farg{first}@, Iter @\farg{last}@);
template<MutableRandomAccessIterator Iter,
Predicate<auto, Iter::value_type, Iter::value_type> Compare>
- requires MoveConstructible<Iter::value_type> && MoveAssignable<Iter::value_type>
+ requires @\removedCC{MoveConstructible<Iter::value_type> \&\& MoveAssignable<Iter::value_type>}@
+ @\addedCC{SwappableIterator<Iter>}@
void make_heap(Iter @\farg{first}@, Iter @\farg{last}@,
Compare @\farg{comp}@);
template<MutableRandomAccessIterator Iter>
- requires MoveConstructible<Iter::value_type> && MoveAssignable<Iter::value_type> &&
- Swappable<Iter::value_type> && LessThanComparable<Iter::value_type>
+ requires @\removedCC{MoveConstructible<Iter::value_type> \&\& MoveAssignable<Iter::value_type> \&\&}@
+ @\removedCC{Swappable<Iter::value_type>}@
+ @\addedCC{SwappableIterator<Iter>}@ && LessThanComparable<Iter::value_type>
void sort_heap(Iter @\farg{first}@, Iter @\farg{last}@);
template<MutableRandomAccessIterator Iter,
Predicate<auto, Iter::value_type, Iter::value_type> Compare>
- requires MoveConstructible<Iter::value_type> && MoveAssignable<Iter::value_type> &&
- Swappable<Iter::value_type>
+ requires @\removedCC{MoveConstructible<Iter::value_type> \&\& MoveAssignable<Iter::value_type>}@
+ @\addedCC{SwappableIterator<Iter>}@
void sort_heap(Iter @\farg{first}@, Iter @\farg{last}@,
Compare @\farg{comp}@);
@@ -730,20 +754,24 @@
@\textcolor{black}{// \ref{alg.permutation.generators}, permutations:}@
template<MutableBidirectionalIterator Iter>
- requires SameType<Iter::value_type&, Iter::reference> && Swappable<Iter::value_type> &&
+ requires @\removedCC{SameType<Iter::value_type\&, Iter::reference> \&\& Swappable<Iter::value_type> \&\&}@
+ @\addedCC{SwappableIterator<Iter>}@
@\textcolor{addclr}{LessThanComparable}@<Iter::reference>
bool next_permutation(Iter @\farg{first}@, Iter @\farg{last}@);
template<MutableBidirectionalIterator Iter,
Predicate<auto, Iter::reference, Iter::reference> Compare>
- requires SameType<Iter::value_type&, Iter::reference> && Swappable<Iter::value_type>
+ requires @\removedCC{SameType<Iter::value_type\&, Iter::reference> \&\& Swappable<Iter::value_type>}@
+ @\addedCC{SwappableIterator<Iter>}@
@\textcolor{addclr}{}@bool next_permutation(Iter @\farg{first}@, Iter @\farg{last}@, Compare @\farg{comp}@);
template<MutableBidirectionalIterator Iter>
- requires SameType<Iter::value_type&, Iter::reference> && Swappable<Iter::value_type> &&
+ requires @\removedCC{SameType<Iter::value_type\&, Iter::reference> \&\& Swappable<Iter::value_type> \&\&}@
+ @\addedCC{SwappableIterator<Iter>}@
@\textcolor{addclr}{}@LessThanComparable<Iter::reference>
bool prev_permutation(Iter @\farg{first}@, Iter @\farg{last}@);
template<MutableBidirectionalIterator Iter,
Predicate<auto, Iter::reference, Iter::reference> Compare>
- requires SameType<Iter::value_type&, Iter::reference> && Swappable<Iter::value_type>
+ requires @\removedCC{SameType<Iter::value_type\&, Iter::reference> \&\& Swappable<Iter::value_type>}@
+ @\addedCC{SwappableIterator<Iter>}@
bool prev_permutation(Iter @\farg{first}@, Iter @\farg{last}@, Compare @\farg{comp}@);
}
\end{codeblock}
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk