Init
This commit is contained in:
271
cppdraft/algorithms/requirements.md
Normal file
271
cppdraft/algorithms/requirements.md
Normal file
@@ -0,0 +1,271 @@
|
||||
[algorithms.requirements]
|
||||
|
||||
# 26 Algorithms library [[algorithms]](./#algorithms)
|
||||
|
||||
## 26.2 Algorithms requirements [algorithms.requirements]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L32)
|
||||
|
||||
All of the algorithms
|
||||
are separated from the particular implementations of data structures and
|
||||
are parameterized by iterator types[.](#1.sentence-1)
|
||||
|
||||
Because of this, they can work with program-defined data structures,
|
||||
as long as these data structures have iterator types
|
||||
satisfying the assumptions on the algorithms[.](#1.sentence-2)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L40)
|
||||
|
||||
The entities defined in the std::ranges namespace in this Clause and
|
||||
specified as function templates are
|
||||
algorithm function objects ([[alg.func.obj]](alg.func.obj "16.3.3.4 Algorithm function objects"))[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L45)
|
||||
|
||||
For purposes of determining the existence of data races,
|
||||
algorithms shall not modify objects referenced through an iterator argument
|
||||
unless the specification requires such modification[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L50)
|
||||
|
||||
Throughout this Clause, where the template parameters are not constrained,
|
||||
the names of template parameters are used to express type requirements[.](#4.sentence-1)
|
||||
|
||||
- [(4.1)](#4.1)
|
||||
|
||||
If an algorithm's *Effects* element specifies
|
||||
that a value pointed to by any iterator passed as an argument is modified,
|
||||
then the type of that argument shall meet
|
||||
the requirements of a mutable iterator ([[iterator.requirements]](iterator.requirements "24.3 Iterator requirements"))[.](#4.1.sentence-1)
|
||||
|
||||
- [(4.2)](#4.2)
|
||||
|
||||
If an algorithm's template parameter is named InputIterator, InputIterator1, or InputIterator2,
|
||||
the template argument shall meet the [*Cpp17InputIterator*](input.iterators#:Cpp17InputIterator "24.3.5.3 Input iterators [input.iterators]") requirements ([[input.iterators]](input.iterators "24.3.5.3 Input iterators"))[.](#4.2.sentence-1)
|
||||
|
||||
- [(4.3)](#4.3)
|
||||
|
||||
If an algorithm's template parameter is named OutputIterator, OutputIterator1, or OutputIterator2,
|
||||
the template argument shall meet the [*Cpp17OutputIterator*](output.iterators#:Cpp17OutputIterator "24.3.5.4 Output iterators [output.iterators]") requirements ([[output.iterators]](output.iterators "24.3.5.4 Output iterators"))[.](#4.3.sentence-1)
|
||||
|
||||
- [(4.4)](#4.4)
|
||||
|
||||
If an algorithm's template parameter is named ForwardIterator, ForwardIterator1, ForwardIterator2, or NoThrowForwardIterator,
|
||||
the template argument shall meet the [*Cpp17ForwardIterator*](forward.iterators#:Cpp17ForwardIterator "24.3.5.5 Forward iterators [forward.iterators]") requirements ([[forward.iterators]](forward.iterators "24.3.5.5 Forward iterators"))
|
||||
if it is required to be a mutable iterator, or
|
||||
model [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_iterator [iterator.concept.forward]") ([[iterator.concept.forward]](iterator.concept.forward "24.3.4.11 Concept forward_iterator")) otherwise[.](#4.4.sentence-1)
|
||||
|
||||
- [(4.5)](#4.5)
|
||||
|
||||
If an algorithm's template parameter is named NoThrowForwardIterator,
|
||||
the template argument
|
||||
is also required to have the property that no exceptions are thrown
|
||||
from increment, assignment, or comparison of, or
|
||||
indirection through, valid iterators[.](#4.5.sentence-1)
|
||||
|
||||
- [(4.6)](#4.6)
|
||||
|
||||
If an algorithm's template parameter is named BidirectionalIterator, BidirectionalIterator1, or BidirectionalIterator2,
|
||||
the template argument shall meet the [*Cpp17BidirectionalIterator*](bidirectional.iterators#:Cpp17BidirectionalIterator "24.3.5.6 Bidirectional iterators [bidirectional.iterators]") requirements ([[bidirectional.iterators]](bidirectional.iterators "24.3.5.6 Bidirectional iterators"))
|
||||
if it is required to be a mutable iterator, or model [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12 Concept bidirectional_iterator [iterator.concept.bidir]") ([[iterator.concept.bidir]](iterator.concept.bidir "24.3.4.12 Concept bidirectional_iterator")) otherwise[.](#4.6.sentence-1)
|
||||
|
||||
- [(4.7)](#4.7)
|
||||
|
||||
If an algorithm's template parameter is named RandomAccessIterator, RandomAccessIterator1, or RandomAccessIterator2,
|
||||
the template argument shall meet the [*Cpp17RandomAccessIterator*](random.access.iterators#:Cpp17RandomAccessIterator "24.3.5.7 Random access iterators [random.access.iterators]") requirements ([[random.access.iterators]](random.access.iterators "24.3.5.7 Random access iterators"))
|
||||
if it is required to be a mutable iterator, or model [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_access_iterator [iterator.concept.random.access]") ([[iterator.concept.random.access]](iterator.concept.random.access "24.3.4.13 Concept random_access_iterator")) otherwise[.](#4.7.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
These requirements do not affect iterator arguments that are constrained,
|
||||
for which iterator category and mutability requirements
|
||||
are expressed explicitly[.](#4.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L115)
|
||||
|
||||
Both in-place and copying versions are provided for certain algorithms[.](#5.sentence-1)[200](#footnote-200 "The decision whether to include a copying version was usually based on complexity considerations. When the cost of doing the operation dominates the cost of copy, the copying version is not included. For example, sort_copy is not included because the cost of sorting is much more significant, and users can invoke copy followed by sort.")
|
||||
|
||||
When such a version is provided for *algorithm* it is called*algorithm_copy*[.](#5.sentence-2)
|
||||
|
||||
Algorithms that take predicates end with the suffix _if (which follows the suffix _copy)[.](#5.sentence-3)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L131)
|
||||
|
||||
When not otherwise constrained, the Predicate parameter is used
|
||||
whenever an algorithm expects a function object ([[function.objects]](function.objects "22.10 Function objects")) that,
|
||||
when applied to the result of dereferencing the corresponding iterator,
|
||||
returns a value testable as true[.](#6.sentence-1)
|
||||
|
||||
If an algorithm takes Predicate pred as its argument andfirst as its iterator argument with value type T,
|
||||
the expression pred(*first) shall be well-formed and
|
||||
the type decltype(pred(*first)) shall model[*boolean-testable*](concept.booleantestable#concept:boolean-testable "18.5.2 Boolean testability [concept.booleantestable]") ([[concept.booleantestable]](concept.booleantestable "18.5.2 Boolean testability"))[.](#6.sentence-2)
|
||||
|
||||
The function object pred shall not apply any non-constant function
|
||||
through its argument[.](#6.sentence-3)
|
||||
|
||||
Given a glvalue u of type (possibly const) T that designates the same object as *first,pred(u) shall be a valid expression
|
||||
that is equal to pred(*first)[.](#6.sentence-4)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L148)
|
||||
|
||||
When not otherwise constrained, the BinaryPredicate parameter is used
|
||||
whenever an algorithm expects a function object that, when applied
|
||||
to the result of dereferencing two corresponding iterators or
|
||||
to dereferencing an iterator and type T when T is part of the signature,
|
||||
returns a value testable as true[.](#7.sentence-1)
|
||||
|
||||
If an algorithm takes BinaryPredicate binary_pred as its argument andfirst1 and first2 as its iterator arguments
|
||||
with respective value types T1 and T2,
|
||||
the expression binary_pred(*first1, *first2) shall be well-formed and
|
||||
the type decltype(binary_pred(*first1, *first2)) shall model[*boolean-testable*](concept.booleantestable#concept:boolean-testable "18.5.2 Boolean testability [concept.booleantestable]")[.](#7.sentence-2)
|
||||
|
||||
Unless otherwise specified,BinaryPredicate always takes the first iterator's value_type as its first argument, that is, in those cases when T value is part of the signature,
|
||||
the expression binary_pred(*first1, value) shall be well-formed and
|
||||
the type decltype(binary_pred(*first1, value)) shall model[*boolean-testable*](concept.booleantestable#concept:boolean-testable "18.5.2 Boolean testability [concept.booleantestable]")[.](#7.sentence-3)
|
||||
|
||||
binary_pred shall not apply any non-constant function
|
||||
through any of its arguments[.](#7.sentence-4)
|
||||
|
||||
Given a glvalue u of type (possibly const) T1 that designates the same object as *first1, and
|
||||
a glvalue v of type (possibly const) T2 that designates the same object as *first2,binary_pred(u, *first2),binary_pred(*first1, v), andbinary_pred(u, v) shall each be a valid expression that is equal tobinary_pred(*first1, *first2), andbinary_pred(u, value) shall be a valid expression that is equal tobinary_pred(*first1, value)[.](#7.sentence-5)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L183)
|
||||
|
||||
The parametersUnaryOperation,BinaryOperation,BinaryOperation1,
|
||||
and BinaryOperation2 are used
|
||||
whenever an algorithm expects a function object ([[function.objects]](function.objects "22.10 Function objects"))[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L192)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
Unless otherwise specified, algorithms that take function objects as arguments
|
||||
can copy those function objects freely[.](#9.sentence-1)
|
||||
|
||||
If object identity is important,
|
||||
a wrapper class that points to a non-copied implementation object
|
||||
such as reference_wrapper<T> ([[refwrap]](refwrap "22.10.6 Class template reference_wrapper")), or some equivalent solution,
|
||||
can be used[.](#9.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L202)
|
||||
|
||||
When the description of an algorithm gives an expression such as*first == value for a condition, the expression
|
||||
shall evaluate to either true or false in boolean contexts[.](#10.sentence-1)
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L207)
|
||||
|
||||
In the description of the algorithms, operator + is used for some of the iterator categories
|
||||
for which it does not have to be defined[.](#11.sentence-1)
|
||||
|
||||
In these cases the semantics of a + n are the same as those ofauto tmp = a;for (; n < 0; ++n) --tmp;for (; n > 0; --n) ++tmp;return tmp;
|
||||
|
||||
Similarly, operator - is used
|
||||
for some combinations of iterators and sentinel types
|
||||
for which it does not have to be defined[.](#11.sentence-3)
|
||||
|
||||
If [a, b) denotes a range,
|
||||
the semantics of b - a in these cases are the same as those ofiter_difference_t<decltype(a)> n = 0;for (auto tmp = a; tmp != b; ++tmp) ++n;return n; and if [b, a) denotes a range, the same as those ofiter_difference_t<decltype(b)> n = 0;for (auto tmp = b; tmp != a; ++tmp) --n;return n;
|
||||
|
||||
For each iterator i and sentinel s produced from a range r,
|
||||
the semantics of s - i has the same type, value, and value category
|
||||
as ranges::distance(i, s)[.](#11.sentence-5)
|
||||
|
||||
[*Note [3](#note-3)*:
|
||||
|
||||
The implementation can use ranges::distance(r) when that produces the same value as ranges::distance(i, s)[.](#11.sentence-6)
|
||||
|
||||
This can be more efficient for sized ranges[.](#11.sentence-7)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L244)
|
||||
|
||||
In the description of the algorithms,
|
||||
given an iterator a whose difference type is D, and
|
||||
an expression n of integer-like type other than cv D,
|
||||
the semantics of a + n and a - n are, respectively,
|
||||
those of a + D(n) and a - D(n)[.](#12.sentence-1)
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L251)
|
||||
|
||||
In the description of algorithm return values,
|
||||
a sentinel value s denoting the end of a range [i, s)
|
||||
is sometimes returned where an iterator is expected[.](#13.sentence-1)
|
||||
|
||||
In these cases,
|
||||
the semantics are as if the sentinel is converted into an iterator usingranges::next(i, s)[.](#13.sentence-2)
|
||||
|
||||
[14](#14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L259)
|
||||
|
||||
Overloads of algorithms that take [range](range.range#concept:range "25.4.2 Ranges [range.range]") arguments ([[range.range]](range.range "25.4.2 Ranges"))
|
||||
behave as if they are implemented by
|
||||
dispatching to the overload in namespace ranges that takes separate iterator and sentinel arguments,
|
||||
where for each range argument r
|
||||
|
||||
- [(14.1)](#14.1)
|
||||
|
||||
a corresponding iterator argument is initialized with ranges::begin(r) and
|
||||
|
||||
- [(14.2)](#14.2)
|
||||
|
||||
a corresponding sentinel argument is initialized with ranges::end(r),
|
||||
or ranges::next(ranges::begin(r), ranges::end(r)) if the type of r models [forward_range](range.refinements#concept:forward_range "25.4.6 Other range refinements [range.refinements]") and computing ranges::next meets the specified complexity requirements[.](#14.sentence-1)
|
||||
|
||||
[15](#15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L275)
|
||||
|
||||
The well-formedness and behavior of a call to an algorithm with
|
||||
an explicitly-specified template argument list
|
||||
is unspecified, except where explicitly stated otherwise[.](#15.sentence-1)
|
||||
|
||||
[*Note [4](#note-4)*:
|
||||
|
||||
Consequently, an implementation can declare an algorithm with
|
||||
different template parameters than those presented[.](#15.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[200)](#footnote-200)[200)](#footnoteref-200)
|
||||
|
||||
The decision whether to include a copying version was
|
||||
usually based on complexity considerations[.](#footnote-200.sentence-1)
|
||||
|
||||
When the cost of doing the operation dominates the cost of copy,
|
||||
the copying version is not included[.](#footnote-200.sentence-2)
|
||||
|
||||
For example, sort_copy is not included
|
||||
because the cost of sorting is much more significant,
|
||||
and users can invoke copy followed by sort[.](#footnote-200.sentence-3)
|
||||
Reference in New Issue
Block a user