Files
cppdraft_translate/cppdraft/algorithms/requirements.md
2025-10-25 03:02:53 +03:00

272 lines
14 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.4Algorithm 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.3Iterator 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.3Input iterators[input.iterators]") requirements ([[input.iterators]](input.iterators "24.3.5.3Input 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.4Output iterators[output.iterators]") requirements ([[output.iterators]](output.iterators "24.3.5.4Output 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.5Forward iterators[forward.iterators]") requirements ([[forward.iterators]](forward.iterators "24.3.5.5Forward iterators"))
if it is required to be a mutable iterator, or
model [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11Concept forward_­iterator[iterator.concept.forward]") ([[iterator.concept.forward]](iterator.concept.forward "24.3.4.11Concept 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.6Bidirectional iterators[bidirectional.iterators]") requirements ([[bidirectional.iterators]](bidirectional.iterators "24.3.5.6Bidirectional iterators"))
if it is required to be a mutable iterator, or model [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]") ([[iterator.concept.bidir]](iterator.concept.bidir "24.3.4.12Concept 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.7Random access iterators[random.access.iterators]") requirements ([[random.access.iterators]](random.access.iterators "24.3.5.7Random 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.13Concept random_­access_­iterator[iterator.concept.random.access]") ([[iterator.concept.random.access]](iterator.concept.random.access "24.3.4.13Concept 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.10Function 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.2Boolean testability[concept.booleantestable]") ([[concept.booleantestable]](concept.booleantestable "18.5.2Boolean 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.2Boolean 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.2Boolean 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.10Function 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.6Class 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.2Ranges[range.range]") arguments ([[range.range]](range.range "25.4.2Ranges"))
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.6Other 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)