272 lines
14 KiB
Markdown
272 lines
14 KiB
Markdown
[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)
|