1. Motivation
Standard parallel algorithms with execution policies which set semantic requirements to user-provided callable objects were a good start for supporting parallelism in the C++ standard.
The C++ Ranges library - ranges, views, etc. - is a powerful facility to produce lazily evaluated pipelines that can be processed by range-based algorithms. Together they provide a productive and expressive API with the room for extra optimizations.
Combining these two powerful features by adding support for execution policies to the range-based algorithms opens an opportunity to fuse several computations into one parallel algorithm call, thus reducing the overhead on parallelism. That is especially valuable for heterogeneous implementations of parallel algorithms, for which the range-based API helps reducing the number of kernels submitted to an accelerator.
Users are already using ranges and range adaptors by passing range iterators to the existing non-range parallel algorithms. [P2408R5] was adopted to enable this. This pattern is often featured when teaching C++ parallel algorithms and appears in many codebases.
and
are especially common, as many compute workloads want to iterate over indices, not
objects, and many work with multidimensional data.
is also common, as it enables fusion of element-wise
operations into a single parallel algorithm call, which can avoid the need for temporary storage and is more
performant than two separate calls.
However, passing range iterators to non-range algorithms is unwieldy and verbose. It is surprising to users that they cannot simply pass the ranges to the parallel algorithms as they would for serial algorithms.
Scalar-Vector Multiply | |
---|---|
Before | After |
|
|
Matrix Transpose | |
---|---|
Before | After |
|
|
Earlier, [P2500R2] proposed to add the range-based C++ parallel algorithms together with its primary goal of extending algorithms with schedulers. We have decided to split those parts to separate papers, which could progress independently.
2. Design overview
This paper proposes execution policy support for C++ range-based algorithms. In the nutshell, the proposal extends C++ range algorithms with overloads taking any standard or implementation defined C++ execution policy as a function parameter. These overloads are further referred to as parallel range algorithms.
The proposal is targeted to C++26.
2.1. Design summary
2.1.1. Differences to serial range algorithms
Comparing to the C++20 serial range algorithms, we propose the following modifications:
-
The execution policy parameter is added.
-
andfor_each
return only an iterator but not the function.for_each_n -
Parallel range algorithms take a range, not an iterator, as the output for the overloads with ranges, and additionally take an output sentinel for the "iterator and sentinel" overloads. (§ 2.7 Taking range as the output)
-
Until better parallelism-friendly abstractions are proposed, parallel algorithms require
. (§ 2.6 Requiring random_access_iterator or random_access_range)random_access_ { iterator , range } -
All input and output data sequences must be bounded. (§ 2.8 Requiring ranges to be bounded)
2.1.2. Differences to C++17 parallel algorithms
In addition to data sequences being passed as either ranges or "iterator and sentinel" pairs, the following differences to the C++17 parallel algorithms are proposed:
-
returns an iterator, notfor_each
.void -
Algorithms require
, and not LegacyForwardIterator.random_access_ { iterator , range } -
All input and output data sequences must be bounded.
2.1.3. Other design aspects
-
The parallel range algorithms support all standard and implementation-defined execution policies. (§ 2.3 Supported execution policies)
-
Except as mentioned above, the parallel range algorithms should return the same type as the corresponding serial range algorithms. (§ 2.4 Algorithm return types)
-
The proposed algorithms extend the overload set of algorithm function objects defined in
. (§ 2.5 Extending the overload sets of algorithm function objects)std :: ranges -
The proposed algorithms should require callable object passed to an algorithm to be
where possible. (§ 2.9 Requirements for callable parameters)regular_invocable -
The proposed algorithms should follow the design of C++17 parallel algorithms with regard to
support. (§ 2.10 constexpr parallel range algorithms)constexpr
2.1.4. An example of the proposed API
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , random_access_iterator O , sized_sentinel_for < O > OutS , copy_constructible F , class Proj = identity > requires indirectly_writable < O , indirect_result_t < F & , projected < I , Proj >>> ranges :: unary_transform_result < I , O > ranges :: transform ( ExecutionPolicy && exec , I first , S last , O result , OutS result_last , F op , Proj proj = {}); template < execution - policy ExecutionPolicy , ranges :: random_access_range R , ranges :: random_access_range OutR , copy_constructible F , class Proj = identity > requires indirectly_writable < ranges :: iterator_t < OutR > , indirect_result_t < F & , projected < ranges :: iterator_t < R > , Proj >>> && sized_range < R > && sized_range < OutR > ranges :: unary_transform_result < ranges :: borrowed_iterator_t < R > , ranges :: borrowed_iterator_t < OutR >> ranges :: transform ( ExecutionPolicy && exec , R && r , OutR && result , F op , Proj proj = {});
2.2. Coexistence with schedulers
We believe that adding parallel range algorithms does not have the risk of conflict with anticipated scheduler-based algorithms, because an execution policy does not satisfy the requirements for a policy-aware scheduler ([P2500R2]), a sender ([P3300R0]), or really anything else from [P2300R9] that can be used to specify such algorithms.
At this point we do not, however, discuss how the appearance of schedulers may or should impact the execution rules for parallel algorithms specified in [algorithms.parallel.exec], and just assume that the same rules apply to the range algorithms with execution policies.
2.3. Supported execution policies
Parallel range algorithms should operate with the same set of execution policies as the existing parallel algorithms,
that is,
,
,
, and
in the
namespace, as well as any implementation-defined
execution policies.
We do not propose the parallel range algorithms to be customizable for application-defined execution policies. We expect such custom policies to become unnecessary once the standard algorithms are capable of working with schedulers/senders/receivers.
2.4. Algorithm return types
We explored possible algorithm return types and came to conclusion that returning the same type as serial range algorithms is the preferred option to make the changes for enabling parallelism minimal.
auto res = std :: ranges :: sort ( v );
becomes:
auto res = std :: ranges :: sort ( std :: execution :: par , v );
However,
and
require special consideration because previous
design decisions suggest that there should be a difference between serial and parallel versions.
The following table summarizes return value types for the existing variants of these two algorithms:
API | Return type |
---|---|
|
|
Parallel
|
|
|
|
Parallel
|
|
|
|
, + overload
|
|
|
|
While the serial
returns the obtained function object with all modifications it might have accumulated,
the return type for the parallel
is
because, as stated in the standard, "parallelization often
does not permit efficient state accumulation". For efficient parallelism an implementation can make multiple copies of
the function object, which for that purpose is allowed to be copyable and not just movable like for the serial
.
That implies that users cannot rely on any state accumulation within that function object, so it does not make sense
(and might be even dangerous) to return it.
In
, the return type of
and
is unified to return both an iterator and the function
object.
Based on the analysis above and the feedback from SG9 we think that the most reasonable return type
for parallel variants of
and
should be:
API | Return type |
---|---|
Parallel
|
|
Parallel , + overload
|
|
Parallel
|
|
2.5. Extending the overload sets of algorithm function objects
We believe the proposed functionality should have the same properties and general behavior as serial range algorithms, particularly regarding the name lookup.
With the adoption of [P3136R0], function templates in the
namespace have been respecified as algorithm function objects. These objects are defined as sets of one or more overloaded function templates,
which names designate the objects.
The parallel range algorithms we propose will extend the overload sets for the respective algorithm function objects. The name lookup rules for such objects will apply automatically. It is covered by the wording proposed in [P3136R0]; additional changes are not needed.
From the implementation standpoint, adding parallel versions of the range algorithms to the overload set should not be a problem. Please see § 4 Possible implementation of a parallel range algorithm for more information.
2.6. Requiring random_access_iterator
or random_access_range
C++17 parallel algorithms minimally require LegacyForwardIterator for data sequences, but in our opinion, it is not quite suitable for an efficient parallel implementation. Therefore for parallel range algorithms we propose to require random access ranges and iterators.
Using parallel algorithms with forward ranges will in most cases give little to no benefit, and may even reduce performance due to extra overheads. We believe that forward ranges and iterators are bad abstractions for parallel data processing, and allowing those could result in wrong expectations and unsatisfactory user experience with parallel algorithms.
Many parallel programming models that are well known and widely used in the industry, including OpenMP, OpenCL, CUDA, SYCL, oneTBB, define iteration or data spaces for their parallel constructs in ways that allow creating sufficient parallel work quickly and efficiently. A key property for this is the ability to split the work into smaller chunks. These programming models allow to control the amount of work per chunk and sometimes the ways chunks are created and/or scheduled. All these also support iteration spaces up to at least 3 dimensions.
Except for
in oneTBB which can work with forward iterators, these parallel programming models
require random access iterators or some equivalent, such as numeric indexes or pointers. This is natural,
as referring to an arbitrary point in the iteration space at constant time is the main and by far simplest way
to create parallel work. Forward iterators, on the other hand, are notoriously bad for splitting a sequence
that can only be done in linear time. Moreover, if the output of an algorithm should preserve the order of its input,
which is typical for the C++ algorithms, it requires additional synchronization or/and additional space with forward
iterators and comes almost for granted with random access ones.
These very programming models are often used as backends to implement the C++ standard parallelism. Not surprisingly,
most implementations fall back to serial processing if data sequences have no random access. Of the GNU libstdc++,
LLVM libc++, and MSVC’s standard library, only the latter attempts to process forward iterator based sequences in parallel,
for which it first needs to serially iterate over a whole sequence once or even twice.
oneAPI DPC++ library (oneDPL) supports forward iterators only for a very few algorithms,
only for
and only in the implementation based on oneTBB.
According to the SG1/SG9 feedback we have got earlier, there seemingly are two main reasons why others do not want to restrict parallel algorithms by only random access ranges:
-
That would prevent some useful views, such as
, from being used with parallel range algorithms.filter_view -
That would be inconsistent with the C++17 parallel algorithms.
Given the other aspects of the proposed design, we believe some degree of inconsistency with C++17 parallel algorithms is inevitable and should not become a gating factor for important design decisions.
The question of supporting the standard views that do not provide random access is very important. We think though
that it should better be addressed through proper abstractions and new concepts defining iteration spaces, including
multidimensional ones, suitable for parallel algorithms. We intend to work on developing these (likely in another paper),
however it requires time and effort to make it right, and we think trying to squeeze that into C++26 adds significant risks.
For now, random access ranges with known bounds (see § 2.8 Requiring ranges to be bounded) is probably the best approximation
that exists in the standard. Starting from that and gradually enabling other types of iteration spaces
in a source-compatible manner seems to us better than blanket allowance of any
.
2.7. Taking range as the output
We propose taking a range as the output for the overloads that take ranges for input. Similarly, we propose requiring a sentinel for the output where the input is passed as "iterator and sentinel".
The benefits of this range-as-the-output approach, comparing to taking a single iterator for the output, are:
-
It creates a safer API where all data sequences have known bounds. Specifically, the
andsized_range
concepts will be applied to the output sequences in the same way as to the input sequences.sized_sentinel_for -
Not for all algorithms the output size is defined by the input size. An example is
(and similar algorithms with filtering semantics), where the output sequence might be shorter than the input one. Knowing the expected size of the output may open opportunities for more efficient implementations.copy_if -
Passing a range for the output makes code a bit simpler in the cases typical for parallel execution.
On the joint SG1 and SG9 discussion of [P3179R2] the audience expressed several concerns about the idea and requested to stay with iterators for the output until deeper investigation is made.
To address the concerns, we wrote a separate paper [P3490R0] with the detailed investigation of the topic, suggesting there a compromise solution with adding separate function template overloads for both iterator-as-the-output and range-as-the-output. See [P3490R0] for more details.
Eventually SG9 accepted our original proposal to use ranges for the output, without extra overloads for legacy convenience.
2.8. Requiring ranges to be bounded
One of the requirements we want to put on the parallel range algorithms is to disallow unbounded input and output. The reasons for that are:
-
For efficient parallel implementation we need to know the iteration space bounds. Otherwise, it’s hard to apply the "divide and conquer" strategy for creating work for multiple execution threads.
-
While serial range algorithms allow passing an "infinite" range like
, it may result in an endless loop. It’s hard to imagine usefulness of that in the case of parallel execution. Requiring data sequences to be bounded potentially prevents errors at run-time.std :: ranges :: views :: iota ( 0 ) -
Using explicitly bounded output ranges follows established practices of secure coding, which recommend or even require to always specify the size of the output in order to prevent out-of-range data modifications.
If several provided ranges or sequences are bounded, an algorithm should stop as soon as the end is reached for the shortest one.
There are already precedents in the standard that an algorithm takes two sequences with potentially different input sizes
and chooses the smaller size as the number of iterations it is going to make, such as
and
. For the record,
(including the overload with execution policy) doesn’t support
different input sizes, while
does.
In the case of two input ranges or sequences, for a few algorithms - namely,
,
, and
-
it could be sufficient for just one range to be bounded and the other assumed to have at least as many elements
as the bounded one. This enables unbounded ranges such as
in certain useful patterns, for example:
void normalize_parallel ( range auto && v ) { auto mx = reduce ( execution :: par , v , ranges :: max {}); transform ( execution :: par , v , views :: repeat ( mx ), v . begin (), divides ); }
However, SG9 decided to require
for all inputs, with the plan to relax these constraints
for
once there is a way to statically detect infinite ranges like
(as opposed to finite unsized
ranges, such as null terminated strings).
2.9. Requirements for callable parameters
In [P3179R0] we proposed that parallel range algorithms should require function objects for predicates, comparators, etc.
to have
-qualified
, with the intent to provide compile-time diagnostics for mutable function objects
which might be unsafe for parallel execution. We have got contradictory feedback from SG1 and SG9 on that topic:
SG1 preferred to keep the behavior consistent with C++17 parallel algorithms, while SG9 supported our design intent.
We did extra investigation and decided that requiring
-qualified operator at compile-time is not strictly necessary
because:
-
The vast majority of the serial range algorithms requires function objects to be
(or its derivatives), which already has the semantic requirement of not modifying either the function object or its arguments. While not enforced at compile-time, it seems good enough for our purpose because it demands having the same function object state between invocations (independently ofregular_invocable
qualifier), and it is consistent with serial range algorithms.const -
Remaining algorithms should be considered individually. For example,
using a mutablefor_each
is of less concern if the algorithm does not return the function object (see more detailed analysis below). Foroperator ()
, a non-mutable callable appears to be of very limited use: in order to produce multiple values while not taking any arguments, a generator should typically maintain and update some state.generate
The following example works fine for serial code. While it compiles for parallel code, users should not assume that the
semantics remains intact. Since the parallel version of
requires function object to be copyable, it
is not guaranteed that all
iterations are processed by the same function object. Practically speaking, users
cannot rely on accumulating any state modifications in a parallel
call.
struct callable { void operator ()( int & x ) { ++ x ; ++ i ; // a data race if the callable is executed concurrently } int get_i () const { return i ; } private : int i = 0 ; }; callable c ; // serial for_each call auto fun = std :: for_each ( v . begin (), v . end (), c ); // parallel for_each call // The callable object cannot be read because parallel for_each version purposefully returns void std :: for_each ( std :: execution :: par , v . begin (), v . end (), c ); // for_each serial range version call auto [ _ , fun ] = std :: ranges :: for_each ( v . begin (), v . end (), c );
We allow the same callable to be used in the proposed
.
// callable is used from the previous code snippet callable c ; // The returned iterator is ignored std :: ranges :: for_each ( std :: execution :: par , v . begin (), v . end (), c );
Again, even though
accumulates state modifications, one cannot rely on that because an algorithm implementation
is allowed to make as many copies of
as it wants. Of course, this can be overcome by using
but that might lead to data races.
// callable is used from the previous code snippet // Wrapping a callable object with std::reference_wrapper compiles, but might result in data races callable c ; std :: ranges :: for_each ( std :: execution :: par , v . begin (), v . end (), std :: ref ( c ));
Our conclusion is that it’s user responsibility to provide such a callable that avoids data races, same as for C++17 parallel algorithms.
2.10. constexpr
parallel range algorithms
[P2902R0] suggests allowing algorithms with execution policies to be used in constant expressions. We do not consider that as a primary design goal for our work, however we will happily align with that proposal in the future once it progresses towards adoption into the working draft.
3. More examples
3.1. Change existing code to use parallel range algorithms
One of the goals is to require a minimal amount of changes when switching from the existing API to parallel range algorithms. However, that simplicity should not create hidden issues negatively impacting the overall user experience. We believe that the proposal provides a good balance in that regard.
As an example, let’s look at using
to apply a lambda function to all elements of a
.
For the serial range-based
call:
std :: ranges :: for_each ( v , []( auto & x ) { ++ x ; });
switching to the parallel version will look like:
std :: ranges :: for_each ( std :: execution :: par , v , []( auto & x ) { ++ x ; });
In this simple case, the only change is an execution policy added as the first function argument. It will also hold for
the "iterator and sentinel" overload of
.
The C++17 parallel
call:
std :: for_each ( std :: execution :: par , v . begin (), v . end (), []( auto & x ) { ++ x ; });
can be changed to one of the following:
// Using iterator and sentinel std :: ranges :: for_each ( std :: execution :: par , v . begin (), v . end (), []( auto & x ) { ++ x ; }); // Using vector as a range std :: ranges :: for_each ( std :: execution :: par , v , []( auto & x ) { ++ x ; });
So, here only changing the namespace is necessary, though users might also change
to just
.
However, for other algorithms more changes might be necessary.
3.2. Less parallel algorithm calls and better expressiveness
Let’s consider the following example:
reverse ( policy , begin ( data ), end ( data )); transform ( policy , begin ( data ), end ( data ), begin ( result ), []( auto i ){ return i * i ; }); auto res = find_if ( policy , begin ( result ), end ( result ), pred );
It has three stages and eventually tries to answer the question if the input sequence contains an element after reversing and transforming it. The interesting considerations are:
-
Since the example has three parallel stages, it adds extra overhead for parallel computation per algorithm.
-
The first two stages will complete for all elements before the
stage is started, though it is not required for correctness. If reverse and transformation would be done on the fly, a good implementation ofany_of
might have skipped the remaining work whenany_of
returnspred true
, thus providing more performance.
Let’s make it better:
// With fancy iterators auto res = find_if ( policy , make_transform_iterator ( make_reverse_iterator ( end ( data )), []( auto i ){ return i * i ; }), make_transform_iterator ( make_reverse_iterator ( begin ( data )), []( auto i ){ return i * i ; }), pred );
Now there is only one parallel algorithm call, and
can skip unneeded work. However, this
variation also has interesting considerations:
-
First, it doesn’t compile. We use
to pass the transformation function, but the twotransform iterator
expressions use two different lambdas, and the iterator type formake_transform_iterator
cannot be deduced because the types ofany_of
do not match. One of the options to make it compile is to store a lambda in a variable.transform_iterator -
Second, it requires using a non-standard iterator.
-
Third, the expressiveness of the code is not good: it is hard to read while easy to make a mistake like the one described in the first bullet.
Let’s improve the example further with the proposed API:
// With ranges auto res = find_if ( policy , data | views :: reverse | views :: transform ([]( auto i ){ return i * i ; }), pred );
The example above lacks the drawbacks described for the previous variations:
-
There is only one algorithm call;
-
The implementation might skip unnecessary work;
-
There is no room for the lambda type mistake;
-
The readability is much better compared to the second variation and not worse than in the first one.
4. Possible implementation of a parallel range algorithm
Here we show a possible implementation of
with the new overloads
proposed in § 8.9 Modify for_each in [alg.foreach]:
// A possible implementation of std::ranges::for_each namespace ranges { namespace __detail { struct __for_each_fn { // ... // Existing serial overloads // ... // The overload for unsequenced and parallel policies. Requires random_access_iterator template < class ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirectly_unary_invocable < projected < I , Proj >> Fun > requires is_execution_policy_v < std :: remove_cvref_t < ExecutionPolicy >> I operator ()( ExecutionPolicy && exec , I first , S last , Fun f , Proj proj = {}) const { // properly handle the execution policy; // for the reference, a serial implementation is provided for (; first != last ; ++ first ) { std :: invoke ( f , std :: invoke ( proj , * first )); } return first ; } template < class ExecutionPolicy , random_access_range R , class Proj = identity , indirectly_unary_invocable < projected < iterator_t < R > , Proj >> Fun > requires sized_range < R > ranges :: borrowed_iterator_t < R > operator ()( ExecutionPolicy && exec , R && r , Fun f , Proj proj = {}) const { return ( * this )( std :: forward < ExecutionPolicy > ( exec ), std :: ranges :: begin ( r ), std :: ranges :: end ( r ), f , proj ); } }; // struct for_each } // namespace __detail inline namespace __for_each_fn_namespace { inline constexpr __detail :: __for_each_fn for_each ; } // __for_each_fn_namespace } // namespace ranges
5. The proposal scope
5.1. In-scope
5.1.1. The counterparts of C++17 parallel algorithms in std :: ranges
namespace
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
|
|
|
|
5.1.2. Algorithms in std :: ranges
namespace only
The algorithms below are easy to add because they are either expressible via existing parallel algorithms or an analogue with very close semantics exists:
algorithms to add
| algorithms used as the guidance
|
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5.2. Out-of-scope
5.2.1. The counterparts of exiting algorithms without ExecutionPolicy
Below we list the algorithms below without
in C++17 and where
parameter doesn’t seem
to add value:
-
push_heap -
pop_heap -
sort_heap -
next_permutation -
prev_permutation -
lower_bound -
upper_bound -
equal_range -
binary_search -
partition_point
Below we list the algorithms below without
in C++17, where
parameter might make sense
but requires deeper investigation:
-
iota -
make_heap -
is_permutation -
copy_backward -
move_backward -
(RNG specific)sample -
(RNG specific)shuffle
Below we list
only algorithms where we don’t add the
parameter:
-
fold_left -
fold_left_first -
fold_right -
fold_right_last -
fold_left_with_iter -
fold_left_first_with_iter -
(RNG specific,generate_random
parameter was already discussed during [P1068R11] review)ExecutionPolicy
5.2.2. Absence of some serial range-based algorithms
We understand that some useful algorithms do not yet exist in
, for example, most of generalized numeric
operations [numeric.ops]. The goal of this paper is however limited to
adding overloads with
to the existing algorithms in the
namespace. Any follow-up paper
that adds
algorithms to
should also consider adding dedicated overloads with
.
6. Implementation experience
The oneAPI DPC++ Library (oneDPL) developer guide covers parallel range algorithms we’ve implemented so far. The oneAPI specification provides formal signatures of these algorithms. The implementation supports execution policies for CPUs (semantically aligned with the C++ standard) and for SYCL devices, and it works with a subset of the standard C++ views.
We use the range-as-the-output approach where applicable: in
,
,
, and
.
We don’t foresee any issues with implementability for the rest of the proposed parallel algorithms because all of them were already implemented in C++17 and new APIs that we propose are expressible via the existing ones.
7. Further work
7.1. Issues to address
Having known bugs and feedback from SG1 and SG9, the plan of work prior to the next committee F2F meeting in Austria, 2025 is the following:
-
Update [algorithm.syn].
-
Consider adding the algorithm descriptions to the wording, even if no changes are made.
7.2. Thread-safe views examination
We need to understand better whether using some
with parallel algorithms might result in data races.
While some investigation was done by other authors in [P3159R0], it’s mostly not about the data races but about
ability to parallelize processing of data represented by various views.
We need to invest more time to understand the implications of sharing a state between
and
on the possibility
of data races. One example is
, where iterators keep pointers to the function object that is stored
in the view itself.
Here are questions we want to answer (potentially not a complete list):
-
Do users have enough control to guarantee absence of data races for such views?
-
Are races not possible because of implementation strategy chosen by standard libraries?
-
Do we need to add extra requirements towards thread safety to the standard views?
8. Formal wording
8.1. Add the feature test macro to [version.syn]
#define __cpp_lib_parallel_algorithm 201603L // also in <algorithm>, <numeric>
#define __cpp_lib_parallel_range_algorithms 20����L // also in <algorithm>, <memory>
#define __cpp_lib_philox_engine 202406L // also in <random>
8.2. Modify [algorithms.parallel.defns]
Parallel algorithms access objects indirectly accessible via their arguments by invoking the following functions:
-
All operations of the categories of the iterators , sentinels or mdspan types that the algorithm is instantiated with.
-
Operations on those sequence elements that are required by its specification.
-
User-provided
functioninvocable objects to be applied during the execution of the algorithm, if required by the specification. -
Operations on those
functioninvocable objects required by the specification.
8.3. Modify [algorithms.parallel.user]
Unless otherwise specified,
function
invocable
objects passed into parallel algorithms as objects of type
,
,
,
,
,
,
,
,
and the operators used by the analogous overloads to these parallel algorithms that are formed by an invocation
with the specified default predicate or operation (where applicable) shall not directly or indirectly modify objects via their arguments,
nor shall they rely on the identity of the provided objects.
8.4. Modify [algorithms.parallel.overloads]
Parallel algorithms shall not participate in overload resolution unless
is true
.
template < class T > concept execution - policy = // exposition only is_execution_policy_v < remove_cvref_t < ExecutionPolicy >>
8.5. Modify all_of
in [alg.all.of]
template < input_iterator I , sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > constexpr bool ranges :: all_of ( I first , S last , Pred pred , Proj proj = {}); template < input_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > constexpr bool ranges :: all_of ( R && r , Pred pred , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > bool ranges :: all_of ( ExecutionPolicy && exec , I first , S last , Pred pred , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires sized_range < R > bool ranges :: all_of ( ExecutionPolicy && exec , R && r , Pred pred , Proj proj = {});
8.6. Modify any_of
in [alg.any.of]
template < input_iterator I , sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > constexpr bool ranges :: any_of ( I first , S last , Pred pred , Proj proj = {}); template < input_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > constexpr bool ranges :: any_of ( R && r , Pred pred , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > bool ranges :: any_of ( ExecutionPolicy && exec , I first , S last , Pred pred , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires sized_range < R > bool ranges :: any_of ( ExecutionPolicy && exec , R && r , Pred pred , Proj proj = {});
8.7. Modify none_of
in [alg.none.of]
template < input_iterator I , sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > constexpr bool ranges :: none_of ( I first , S last , Pred pred , Proj proj = {}); template < input_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > constexpr bool ranges :: none_of ( R && r , Pred pred , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > bool ranges :: none_of ( ExecutionPolicy && exec , I first , S last , Pred pred , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires sized_range < R > bool ranges :: none_of ( ExecutionPolicy && exec , R && r , Pred pred , Proj proj = {});
8.8. Modify contains
in [alg.contains]
template < input_iterator I , sentinel_for < I > S , class Proj = identity , class T = projected_value_t < I , Proj >> requires indirect_binary_predicate < ranges :: equal_to , projected < I , Proj > , const T *> constexpr bool ranges :: contains ( I first , S last , const T & value , Proj proj = {}); template < input_range R , class Proj = identity , class T = projected_value_t < iterator_t < R > , Proj >> requires indirect_binary_predicate < ranges :: equal_to , projected < iterator_t < R > , Proj > , const T *> constexpr bool ranges :: contains ( R && r , const T & value , Proj proj = {});
Returns:
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , class T = projected_value_t < I , Proj >> requires indirect_binary_predicate < ranges :: equal_to , projected < I , Proj > , const T *> bool ranges :: contains ( ExecutionPolicy && exec , I first , S last , const T & value , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , class T = projected_value_t < iterator_t < R > , Proj >> requires indirect_binary_predicate < ranges :: equal_to , projected < iterator_t < R > , Proj > , const T *> && sized_range < R > bool ranges :: contains ( ExecutionPolicy && exec , R && r , const T & value , Proj proj = {});
Returns:
template < forward_iterator I1 , sentinel_for < I1 > S1 , forward_iterator I2 , sentinel_for < I2 > S2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < I1 , I2 , Pred , Proj1 , Proj2 > constexpr bool ranges :: contains_subrange ( I1 first1 , S1 last1 , I2 first2 , S2 last2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < forward_range R1 , forward_range R2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < iterator_t < R1 > , iterator_t < R2 > , Pred , Proj1 , Proj2 > constexpr bool ranges :: contains_subrange ( R1 && r1 , R2 && r2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
Returns:
template < execution - policy ExecutionPolicy , random_access_iterator I1 , sized_sentinel_for < I1 > S1 , random_access_iterator I2 , sized_sentinel_for < I2 > S2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < I1 , I2 , Pred , Proj1 , Proj2 > bool ranges :: contains_subrange ( ExecutionPolicy && exec , I1 first1 , S1 last1 , I2 first2 , S2 last2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < execution - policy ExecutionPolicy , random_access_range R1 , random_access_range R2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < iterator_t < R1 > , iterator_t < R2 > , Pred , Proj1 , Proj2 > && sized_range < R1 > && sized_range < R2 > bool ranges :: contains_subrange ( ExecutionPolicy && exec , R1 && r1 , R2 && r2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
Returns:
8.9. Modify for_each
in [alg.foreach]
template < input_iterator I , sentinel_for < I > S , class Proj = identity , indirectly_unary_invocable < projected < I , Proj >> Fun > constexpr ranges :: for_each_result < I , Fun > ranges :: for_each ( I first , S last , Fun f , Proj proj = {}); template < input_range R , class Proj = identity , indirectly_unary_invocable < projected < iterator_t < R > , Proj >> Fun > constexpr ranges :: for_each_result < borrowed_iterator_t < R > , Fun > ranges :: for_each ( R && r , Fun f , Proj proj = {});
Effects: Calls
for every iterator
in the range
, starting from
and proceeding to
.
[Note x: If the result of
is a mutable reference,
can apply non-constant functions. — end note]
Returns:
Complexity: Applies
and
exactly
times.
Remarks: If
returns a result, the result is ignored.
[Note x: The overloads in namespace
require
to model
. — end note]
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirectly_unary_invocable < projected < I , Proj >> Fun > I ranges :: for_each ( ExecutionPolicy && exec , I first , S last , Fun f , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirectly_unary_invocable < projected < iterator_t < R > , Proj >> Fun > requires sized_range < R > borrowed_iterator_t < R > ranges :: for_each ( ExecutionPolicy && exec , R && r , Fun f , Proj proj = {});
Effects: Calls
for every iterator
in the range
.
[Note x: If the result of
is a mutable reference,
can apply non-constant functions. — end note]
Returns:
Complexity: Applies
and
exactly
times.
Remarks: If
returns a result, the result is ignored. Implementations do not have the freedom granted under
[algorithms.parallel.exec] to make arbitrary copies of elements from the input sequence.
[Note x: The overloads in namespace
require
to model
. — end note]
[Note x: Do not return a copy of its
parameter, since parallelization often does not permit efficient state
accumulation. — end note]
template < input_iterator I , class Proj = identity , indirectly_unary_invocable < projected < I , Proj >> Fun > constexpr ranges :: for_each_n_result < I , Fun > ranges :: for_each_n ( I first , iter_difference_t < I > n , Fun f , Proj proj = {});
Preconditions:
is true
.
Effects: Calls
for every iterator
in the range
in order.
[Note x: If the result of
is a mutable reference,
can apply non-constant functions. — end note]
Returns:
.
Remarks: If
returns a result, the result is ignored.
[Note x: The overload in namespace
requires
to model
. — end note]
template < execution - policy ExecutionPolicy , random_access_iterator I , class Proj = identity , indirectly_unary_invocable < projected < I , Proj >> Fun > I ranges :: for_each_n ( ExecutionPolicy && exec , I first , iter_difference_t < I > n , Fun f , Proj proj = {});
Preconditions:
is true
.
Effects: Calls
for every iterator
in the range
.
[Note x: If the result of
is a mutable reference,
can apply non-constant functions. — end note]
Returns:
.
Remarks: If
returns a result, the result is ignored.
[Note x: The overload in namespace
requires
to model
. — end note]
[Note x: Does not return a copy of its
parameter, since parallelization often does not permit efficient state
accumulation. — end note]
8.10. Modify find
in [alg.find]
template < input_iterator I , sentinel_for < I > S , class Proj = identity , class T = projected_value_t < I , Proj >> requires indirect_binary_predicate < ranges :: equal_to , projected < I , Proj > , const T *> constexpr I ranges :: find ( I first , S last , const T & value , Proj proj = {}); template < input_range R , class Proj = identity , class T = projected_value_t < iterator_t < R > , Proj >> requires indirect_binary_predicate < ranges :: equal_to , projected < iterator_t < R > , Proj > , const T *> constexpr borrowed_iterator_t < R > ranges :: find ( R && r , const T & value , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , class T = projected_value_t < I , Proj >> requires indirect_binary_predicate < ranges :: equal_to , projected < I , Proj > , const T *> I ranges :: find ( ExecutionPolicy && exec , I first , S last , const T & value , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , class T = projected_value_t < iterator_t < R > , Proj >> requires indirect_binary_predicate < ranges :: equal_to , projected < iterator_t < R > , Proj > , const T *> && sized_range < R > borrowed_iterator_t < R > ranges :: find ( ExecutionPolicy && exec , R && r , const T & value , Proj proj = {});
template < input_iterator I , sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > constexpr I ranges :: find_if ( I first , S last , Pred pred , Proj proj = {}); template < input_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > constexpr borrowed_iterator_t < R > ranges :: find_if ( R && r , Pred pred , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > I ranges :: find_if ( ExecutionPolicy && exec , I first , S last , Pred pred , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires sized_range < R > borrowed_iterator_t < R > ranges :: find_if ( ExecutionPolicy && exec , R && r , Pred pred , Proj proj = {});
template < input_iterator I , sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > constexpr I ranges :: find_if_not ( I first , S last , Pred pred , Proj proj = {}); template < input_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > constexpr borrowed_iterator_t < R > ranges :: find_if_not ( R && r , Pred pred , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > I ranges :: find_if_not ( ExecutionPolicy && exec , I first , S last , Pred pred , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires sized_range < R > borrowed_iterator_t < R > ranges :: find_if_not ( ExecutionPolicy && exec , R && r , Pred pred , Proj proj = {});
8.11. Modify find_last
in [alg.find.last]
template < forward_iterator I , sentinel_for < I > S , class Proj = identity , class T = projected_value_t < I , Proj >> requires indirect_binary_predicate < ranges :: equal_to , projected < I , Proj > , const T *> constexpr subrange < I > ranges :: find_last ( I first , S last , const T & value , Proj proj = {}); template < forward_range R , class Proj = identity , class T = projected_value_t < iterator_t < R > , Proj >> requires indirect_binary_predicate < ranges :: equal_to , projected < iterator_t < R > , Proj > , const T *> constexpr borrowed_subrange_t < R > ranges :: find_last ( R && r , const T & value , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , class T = projected_value_t < I , Proj >> requires indirect_binary_predicate < ranges :: equal_to , projected < I , Proj > , const T *> subrange < I > ranges :: find_last ( ExecutionPolicy && exec , I first , S last , const T & value , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , class T = projected_value_t < iterator_t < R > , Proj >> requires indirect_binary_predicate < ranges :: equal_to , projected < iterator_t < R > , Proj > , const T *> && sized_range < R > borrowed_subrange_t < R > ranges :: find_last ( ExecutionPolicy && exec , R && r , const T & value , Proj proj = {});
template < forward_iterator I , sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > constexpr subrange < I > ranges :: find_last_if ( I first , S last , Pred pred , Proj proj = {}); template < forward_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > constexpr borrowed_subrange_t < R > ranges :: find_last_if ( R && r , Pred pred , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > subrange < I > ranges :: find_last_if ( ExecutionPolicy && exec , I first , S last , Pred pred , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires sized_range < R > borrowed_subrange_t < R > ranges :: find_last_if ( ExecutionPolicy && exec , R && r , Pred pred , Proj proj = {});
template < forward_iterator I , sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > constexpr subrange < I > ranges :: find_last_if_not ( I first , S last , Pred pred , Proj proj = {}); template < forward_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > constexpr borrowed_subrange_t < R > ranges :: find_last_if_not ( R && r , Pred pred , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > subrange < I > ranges :: find_last_if_not ( ExecutionPolicy && exec , I first , S last , Pred pred , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires sized_range < R > borrowed_subrange_t < R > ranges :: find_last_if_not ( ExecutionPolicy && exec , R && r , Pred pred , Proj proj = {});
8.12. Modify find_end
in [alg.find.end]
template < forward_iterator I1 , sentinel_for < I1 > S1 , forward_iterator I2 , sentinel_for < I2 > S2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < I1 , I2 , Pred , Proj1 , Proj2 > constexpr subrange < I1 > ranges :: find_end ( I1 first1 , S1 last1 , I2 first2 , S2 last2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < forward_range R1 , forward_range R2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < iterator_t < R1 > , iterator_t < R2 > , Pred , Proj1 , Proj2 > constexpr borrowed_subrange_t < R1 > ranges :: find_end ( R1 && r1 , R2 && r2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template < execution - policy ExecutionPolicy , random_access_iterator I1 , sized_sentinel_for < I1 > S1 , random_access_iterator I2 , sized_sentinel_for < I2 > S2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < I1 , I2 , Pred , Proj1 , Proj2 > subrange < I1 > ranges :: find_end ( ExecutionPolicy && exec , I1 first1 , S1 last1 , I2 first2 , S2 last2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < execution - policy ExecutionPolicy , random_access_range R1 , random_access_range R2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < iterator_t < R1 > , iterator_t < R2 > , Pred , Proj1 , Proj2 > && sized_range < R1 > && sized_range < R2 > borrowed_subrange_t < R1 > ranges :: find_end ( ExecutionPolicy && exec , R1 && r1 , R2 && r2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
8.13. Modify find_first_of
in [alg.find.first.of]
template < input_iterator I1 , sentinel_for < I1 > S1 , forward_iterator I2 , sentinel_for < I2 > S2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < I1 , I2 , Pred , Proj1 , Proj2 > constexpr I1 ranges :: find_first_of ( I1 first1 , S1 last1 , I2 first2 , S2 last2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < input_range R1 , forward_range R2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < iterator_t < R1 > , iterator_t < R2 > , Pred , Proj1 , Proj2 > constexpr borrowed_iterator_t < R1 > ranges :: find_first_of ( R1 && r1 , R2 && r2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template < execution - policy ExecutionPolicy , random_access_iterator I1 , sized_sentinel_for < I1 > S1 , random_access_iterator I2 , sized_sentinel_for < I2 > S2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < I1 , I2 , Pred , Proj1 , Proj2 > I1 ranges :: find_first_of ( ExecutionPolicy && exec , I1 first1 , S1 last1 , I2 first2 , S2 last2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < execution - policy ExecutionPolicy , random_access_range R1 , random_access_range R2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < iterator_t < R1 > , iterator_t < R2 > , Pred , Proj1 , Proj2 > && sized_range < R1 > && sized_range < R2 > borrowed_iterator_t < R1 > ranges :: find_first_of ( ExecutionPolicy && exec , R1 && r1 , R2 && r2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
8.14. Modify adjacent_find
in [alg.adjacent.find]
template < forward_iterator I , sentinel_for < I > S , class Proj = identity , indirect_binary_predicate < projected < I , Proj > , projected < I , Proj >> Pred = ranges :: equal_to > constexpr I ranges :: adjacent_find ( I first , S last , Pred pred = {}, Proj proj = {}); template < forward_range R , class Proj = identity , indirect_binary_predicate < projected < iterator_t < R > , Proj > , projected < iterator_t < R > , Proj >> Pred = ranges :: equal_to > constexpr borrowed_iterator_t < R > ranges :: adjacent_find ( R && r , Pred pred = {}, Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_binary_predicate < projected < I , Proj > , projected < I , Proj >> Pred = ranges :: equal_to > I ranges :: adjacent_find ( ExecutionPolicy && exec , I first , S last , Pred pred = {}, Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_binary_predicate < projected < iterator_t < R > , Proj > , projected < iterator_t < R > , Proj >> Pred = ranges :: equal_to > requires sized_range < R > borrowed_iterator_t < R > ranges :: adjacent_find ( ExecutionPolicy && exec , R && r , Pred pred = {}, Proj proj = {});
8.15. Modify count
in [alg.count]
template < input_iterator I , sentinel_for < I > S , class Proj = identity , class T = projected_value_t < I , Proj >> requires indirect_binary_predicate < ranges :: equal_to , projected < I , Proj > , const T *> constexpr iter_difference_t < I > ranges :: count ( I first , S last , const T & value , Proj proj = {}); template < input_range R , class Proj = identity , class T = projected_value_t < iterator_t < R > , Proj >> requires indirect_binary_predicate < ranges :: equal_to , projected < iterator_t < R > , Proj > , const T *> constexpr range_difference_t < R > ranges :: count ( R && r , const T & value , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , class T = projected_value_t < I , Proj >> requires indirect_binary_predicate < ranges :: equal_to , projected < I , Proj > , const T *> iter_difference_t < I > ranges :: count ( ExecutionPolicy && exec , I first , S last , const T & value , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , class T = projected_value_t < iterator_t < R > , Proj >> requires indirect_binary_predicate < ranges :: equal_to , projected < iterator_t < R > , Proj > , const T *> && sized_range < R > range_difference_t < R > ranges :: count ( ExecutionPolicy && exec , R && r , const T & value , Proj proj = {});
template < input_iterator I , sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > constexpr iter_difference_t < I > ranges :: count_if ( I first , S last , Pred pred , Proj proj = {}); template < input_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > constexpr range_difference_t < R > ranges :: count_if ( R && r , Pred pred , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > iter_difference_t < I > ranges :: count_if ( ExecutionPolicy && exec , I first , S last , Pred pred , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires sized_range < R > range_difference_t < R > ranges :: count_if ( ExecutionPolicy && exec , R && r , Pred pred , Proj proj = {});
8.16. Modify mismatch
in [alg.mismatch]
template < input_iterator I1 , sentinel_for < I1 > S1 , input_iterator I2 , sentinel_for < I2 > S2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < I1 , I2 , Pred , Proj1 , Proj2 > constexpr ranges :: mismatch_result < I1 , I2 > ranges :: mismatch ( I1 first1 , S1 last1 , I2 first2 , S2 last2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < input_range R1 , input_range R2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < iterator_t < R1 > , iterator_t < R2 > , Pred , Proj1 , Proj2 > constexpr ranges :: mismatch_result < borrowed_iterator_t < R1 > , borrowed_iterator_t < R2 >> ranges :: mismatch ( R1 && r1 , R2 && r2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template < execution - policy ExecutionPolicy , random_access_iterator I1 , sized_sentinel_for < I1 > S1 , random_access_iterator I2 , sized_sentinel_for < I2 > S2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < I1 , I2 , Pred , Proj1 , Proj2 > ranges :: mismatch_result < I1 , I2 > ranges :: mismatch ( ExecutionPolicy && exec , I1 first1 , S1 last1 , I2 first2 , S2 last2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < execution - policy ExecutionPolicy , random_access_range R1 , random_access_range R2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < iterator_t < R1 > , iterator_t < R2 > , Pred , Proj1 , Proj2 > && sized_range < R1 > && sized_range < R2 > ranges :: mismatch_result < borrowed_iterator_t < R1 > , borrowed_iterator_t < R2 >> ranges :: mismatch ( ExecutionPolicy && exec , R1 && r1 , R2 && r2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
8.17. Modify equal
in [alg.equal]
template < input_iterator I1 , sentinel_for < I1 > S1 , input_iterator I2 , sentinel_for < I2 > S2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < I1 , I2 , Pred , Proj1 , Proj2 > constexpr bool ranges :: equal ( I1 first1 , S1 last1 , I2 first2 , S2 last2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < input_range R1 , input_range R2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < iterator_t < R1 > , iterator_t < R2 > , Pred , Proj1 , Proj2 > constexpr bool ranges :: equal ( R1 && r1 , R2 && r2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template < execution - policy ExecutionPolicy , random_access_iterator I1 , sized_sentinel_for < I1 > S1 , random_access_iterator I2 , sized_sentinel_for < I2 > S2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < I1 , I2 , Pred , Proj1 , Proj2 > bool ranges :: equal ( ExecutionPolicy && exec , I1 first1 , S1 last1 , I2 first2 , S2 last2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < execution - policy ExecutionPolicy , random_access_range R1 , random_access_range R2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < iterator_t < R1 > , iterator_t < R2 > , Pred , Proj1 , Proj2 > && sized_range < R1 > && sized_range < R2 > bool ranges :: equal ( ExecutionPolicy && exec , R1 && r1 , R2 && r2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
8.18. Modify search
in [alg.search]
template < forward_iterator I1 , sentinel_for < I1 > S1 , forward_iterator I2 , sentinel_for < I2 > S2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < I1 , I2 , Pred , Proj1 , Proj2 > constexpr subrange < I1 > ranges :: search ( I1 first1 , S1 last1 , I2 first2 , S2 last2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < forward_range R1 , forward_range R2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < iterator_t < R1 > , iterator_t < R2 > , Pred , Proj1 , Proj2 > constexpr borrowed_subrange_t < R1 > ranges :: search ( R1 && r1 , R2 && r2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template < execution - policy ExecutionPolicy , random_access_iterator I1 , sized_sentinel_for < I1 > S1 , random_access_iterator I2 , sized_sentinel_for < I2 > S2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < I1 , I2 , Pred , Proj1 , Proj2 > subrange < I1 > ranges :: search ( ExecutionPolicy && exec , I1 first1 , S1 last1 , I2 first2 , S2 last2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < execution - policy ExecutionPolicy , random_access_range R1 , random_access_range R2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < iterator_t < R1 > , iterator_t < R2 > , Pred , Proj1 , Proj2 > && sized_range < R1 > && sized_range < R2 > borrowed_subrange_t < R1 > ranges :: search ( ExecutionPolicy && exec , R1 && r1 , R2 && r2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template < forward_iterator I , sentinel_for < I > S , class Pred = ranges :: equal_to , class Proj = identity , class T = projected_value_t < I , Proj >> requires indirectly_comparable < I , const T * , Pred , Proj > constexpr subrange < I > ranges :: search_n ( I first , S last , iter_difference_t < I > count , const T & value , Pred pred = {}, Proj proj = {}); template < forward_range R , class Pred = ranges :: equal_to , class Proj = identity , class T = projected_value_t < iterator_t < R > , Proj >> requires indirectly_comparable < iterator_t < R > , const T * , Pred , Proj > constexpr borrowed_subrange_t < R > ranges :: search_n ( R && r , range_difference_t < R > count , const T & value , Pred pred = {}, Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Pred = ranges :: equal_to , class Proj = identity , class T = projected_value_t < I , Proj >> requires indirectly_comparable < I , const T * , Pred , Proj > subrange < I > ranges :: search_n ( ExecutionPolicy && exec , I first , S last , iter_difference_t < I > count , const T & value , Pred pred = {}, Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Pred = ranges :: equal_to , class Proj = identity , class T = projected_value_t < iterator_t < R > , Proj >> requires indirectly_comparable < iterator_t < R > , const T * , Pred , Proj > && sized_range < R > borrowed_subrange_t < R > ranges :: search_n ( ExecutionPolicy && exec , R && r , range_difference_t < R > count , const T & value , Pred pred = {}, Proj proj = {});
8.19. Modify starts_with
in [alg.starts.with]
template < input_iterator I1 , sentinel_for < I1 > S1 , input_iterator I2 , sentinel_for < I2 > S2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < I1 , I2 , Pred , Proj1 , Proj2 > constexpr bool ranges :: starts_with ( I1 first1 , S1 last1 , I2 first2 , S2 last2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < input_range R1 , input_range R2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < iterator_t < R1 > , iterator_t < R2 > , Pred , Proj1 , Proj2 > constexpr bool ranges :: starts_with ( R1 && r1 , R2 && r2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
Returns:
template < execution - policy ExecutionPolicy , random_access_iterator I1 , sized_sentinel_for < I1 > S1 , random_access_iterator I2 , sized_sentinel_for < I2 > S2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < I1 , I2 , Pred , Proj1 , Proj2 > bool ranges :: starts_with ( ExecutionPolicy && exec , I1 first1 , S1 last1 , I2 first2 , S2 last2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < execution - policy ExecutionPolicy , random_access_range R1 , random_access_range R2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < iterator_t < R1 > , iterator_t < R2 > , Pred , Proj1 , Proj2 > && sized_range < R1 > && sized_range < R2 > bool ranges :: starts_with ( ExecutionPolicy && exec , R1 && r1 , R2 && r2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
Returns:
8.20. Modify ends_with
in [alg.ends.with]
template < input_iterator I1 , sentinel_for < I1 > S1 , input_iterator I2 , sentinel_for < I2 > S2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires ( forward_iterator < I1 > || sized_sentinel_for < S1 , I1 > ) && ( forward_iterator < I2 > || sized_sentinel_for < S2 , I2 > ) && indirectly_comparable < I1 , I2 , Pred , Proj1 , Proj2 > constexpr bool ranges :: ends_with ( I1 first1 , S1 last1 , I2 first2 , S2 last2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
Let
be
and
be
.
Returns: false
if
, otherwise
template < execution - policy ExecutionPolicy , random_access_iterator I1 , sized_sentinel_for < I1 > S1 , random_access_iterator I2 , sized_sentinel_for < I2 > S2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires indirectly_comparable < I1 , I2 , Pred , Proj1 , Proj2 > bool ranges :: ends_with ( ExecutionPolicy && exec , I1 first1 , S1 last1 , I2 first2 , S2 last2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
Let
be
and
be
.
Returns: false
if
, otherwise
template < input_range R1 , input_range R2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires ( forward_range < R1 > || sized_range < R1 > ) && ( forward_range < R2 > || sized_range < R2 > ) && indirectly_comparable < iterator_t < R1 > , iterator_t < R2 > , Pred , Proj1 , Proj2 > constexpr bool ranges :: ends_with ( R1 && r1 , R2 && r2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
Let
be
and
be
.
Returns: false
if
, otherwise
template < execution - policy ExecutionPolicy , random_access_range R1 , random_access_range R2 , class Pred = ranges :: equal_to , class Proj1 = identity , class Proj2 = identity > requires ( sized_range < R1 > && sized_range < R2 > ) && indirectly_comparable < iterator_t < R1 > , iterator_t < R2 > , Pred , Proj1 , Proj2 > bool ranges :: ends_with ( ExecutionPolicy && exec , R1 && r1 , R2 && r2 , Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
Let
be
and
be
.
Returns: false
if
, otherwise
8.21. Modify copy
in [alg.copy]
template < execution - policy ExecutionPolicy , class ForwardIterator1 , class ForwardIterator2 > ForwardIterator2 copy ( ExecutionPolicy && policy , ForwardIterator1 first , ForwardIterator1 last , ForwardIterator2 result );
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , random_access_iterator O , sized_sentinel_for < O > OutS > requires indirectly_copyable < I , O > ranges :: copy_result < I , O > ranges :: copy ( ExecutionPolicy && exec , I first , S last , O result , OutS result_last ); template < execution - policy ExecutionPolicy , random_access_range R , random_access_range OutR > requires indirectly_copyable < iterator_t < R > , iterator_t < OutR >> && sized_range < R > && sized_range < OutR > ranges :: copy_result < borrowed_iterator_t < R > , borrowed_iterator_t < OutR >> ranges :: copy ( ExecutionPolicy && exec , R && r , OutR && result );
template < input_iterator I , weakly_incrementable O > requires indirectly_copyable < I , O > constexpr ranges :: copy_n_result < I , O > ranges :: copy_n ( I first , iter_difference_t < I > n , O result );
template < execution - policy ExecutionPolicy , random_access_iterator I , random_access_iterator O > requires indirectly_copyable < I , O > ranges :: copy_n_result < I , O > ranges :: copy_n ( ExecutionPolicy && exec , I first , iter_difference_t < I > n , O result );
template < input_iterator I , sentinel_for < I > S , weakly_incrementable O , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > requires indirectly_copyable < I , O > constexpr ranges :: copy_if_result < I , O > ranges :: copy_if ( I first , S last , O result , Pred pred , Proj proj = {}); template < input_range R , weakly_incrementable O , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires indirectly_copyable < iterator_t < R > , O > constexpr ranges :: copy_if_result < borrowed_iterator_t < R > , O > ranges :: copy_if ( R && r , O result , Pred pred , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , random_access_iterator O , sized_sentinel_for < O > OutS , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > requires indirectly_copyable < I , O > ranges :: copy_if_result < I , O > ranges :: copy_if ( ExecutionPolicy && exec , I first , S last , O result , OutS result_last , Pred pred , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , random_access_iterator OutR , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires indirectly_copyable < iterator_t < R > , iterator_t < OutR >> && sized_range < R > && sized_range < OutR > ranges :: copy_if_result < borrowed_iterator_t < R > , borrowed_iterator_t < OutR >> ranges :: copy_if ( ExecutionPolicy && exec , R && r , OutR && result , Pred pred , Proj proj = {});
8.22. Modify move
in [alg.move]
template < execution - policy ExecutionPolicy , class ForwardIterator1 , class ForwardIterator2 > ForwardIterator2 move ( ExecutionPolicy && policy , ForwardIterator1 first , ForwardIterator1 last , ForwardIterator2 result );
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , random_access_iterator O , sized_sentinel_for < O > OutS > requires indirectly_movable < I , O > ranges :: move_result < I , O > ranges :: move ( ExecutionPolicy && exec , I first , S last , O result , OutS result_last ); template < execution - policy ExecutionPolicy , random_access_range R , random_access_range OutR > requires indirectly_movable < iterator_t < R > , iterator_t < OutR >> && sized_range < R > && sized_range < OutR > ranges :: move_result < borrowed_iterator_t < R > , borrowed_iterator_t < OutR >> ranges :: move ( ExecutionPolicy && exec , R && r , OutR && result );
8.23. Modify swap
in [alg.swap]
template < input_iterator I1 , sentinel_for < I1 > S1 , input_iterator I2 , sentinel_for < I2 > S2 > requires indirectly_swappable < I1 , I2 > constexpr ranges :: swap_ranges_result < I1 , I2 > ranges :: swap_ranges ( I1 first1 , S1 last1 , I2 first2 , S2 last2 ); template < input_range R1 , input_range R2 > requires indirectly_swappable < iterator_t < R1 > , iterator_t < R2 >> constexpr ranges :: swap_ranges_result < borrowed_iterator_t < R1 > , borrowed_iterator_t < R2 >> ranges :: swap_ranges ( R1 && r1 , R2 && r2 );
template < execution - policy ExecutionPolicy , random_access_iterator I1 , sized_sentinel_for < I1 > S1 , random_access_iterator I2 , sized_sentinel_for < I2 > S2 > requires indirectly_swappable < I1 , I2 > ranges :: swap_ranges_result < I1 , I2 > ranges :: swap_ranges ( ExecutionPolicy && exec , I1 first1 , S1 last1 , I2 first2 , S2 last2 ); template < execution - policy ExecutionPolicy , random_access_range R1 , random_access_range R2 > requires indirectly_swappable < iterator_t < R1 > , iterator_t < R2 >> && sized_range < R1 > && sized_range < R2 > ranges :: swap_ranges_result < borrowed_iterator_t < R1 > , borrowed_iterator_t < R2 >> ranges :: swap_ranges ( ExecutionPolicy && exec , R1 && r1 , R2 && r2 );
8.24. Modify transform
in [alg.transform]
template < input_iterator I , sentinel_for < I > S , weakly_incrementable O , copy_constructible F , class Proj = identity > requires indirectly_writable < O , indirect_result_t < F & , projected < I , Proj >>> constexpr ranges :: unary_transform_result < I , O > ranges :: transform ( I first1 , S last1 , O result , F op , Proj proj = {}); template < input_range R , weakly_incrementable O , copy_constructible F , class Proj = identity > requires indirectly_writable < O , indirect_result_t < F & , projected < iterator_t < R > , Proj >>> constexpr ranges :: unary_transform_result < borrowed_iterator_t < R > , O > ranges :: transform ( R && r , O result , F op , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , random_access_iterator O , sized_sentinel_for < O > OutS , copy_constructible F , class Proj = identity > requires indirectly_writable < O , indirect_result_t < F & , projected < I , Proj >>> ranges :: unary_transform_result < I , O > ranges :: transform ( ExecutionPolicy && exec , I first , S last , O result , OutS result_last , F op , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , random_access_range OutR , copy_constructible F , class Proj = identity > requires indirectly_writable < iterator_t < OutR > , indirect_result_t < F & , projected < iterator_t < R > , Proj >>> && sized_range < R > && sized_range < OutR > ranges :: unary_transform_result < borrowed_iterator_t < R > , borrowed_iterator_t < OutR >> ranges :: transform ( ExecutionPolicy && exec , R && r , OutR && result , F op , Proj proj = {});
template < input_iterator I1 , sentinel_for < I1 > S1 , input_iterator I2 , sentinel_for < I2 > S2 , weakly_incrementable O , copy_constructible F , class Proj1 = identity , class Proj2 = identity > requires indirectly_writable < O , indirect_result_t < F & , projected < I1 , Proj1 > , projected < I2 , Proj2 >>> constexpr ranges :: binary_transform_result < I1 , I2 , O > ranges :: transform ( I1 first1 , S1 last1 , I2 first2 , S2 last2 , O result , F binary_op , Proj1 proj1 = {}, Proj2 proj2 = {}); template < input_range R1 , input_range R2 , weakly_incrementable O , copy_constructible F , class Proj1 = identity , class Proj2 = identity > requires indirectly_writable < O , indirect_result_t < F & , projected < iterator_t < R1 > , Proj1 > , projected < iterator_t < R2 > , Proj2 >>> constexpr ranges :: binary_transform_result < borrowed_iterator_t < R1 > , borrowed_iterator_t < R2 > , O > ranges :: transform ( R1 && r1 , R2 && r2 , O result , F binary_op , Proj1 proj1 = {}, Proj2 proj2 = {});
template < execution - policy ExecutionPolicy , random_access_iterator I1 , sized_sentinel_for < I1 > S1 , random_access_iterator I2 , sized_sentinel_for < I2 > S2 , random_access_iterator O , sized_sentinel_for < O > OutS , copy_constructible F , class Proj1 = identity , class Proj2 = identity > requires indirectly_writable < O , indirect_result_t < F & , projected < I1 , Proj1 > , projected < I2 , Proj2 >>> ranges :: binary_transform_result < I1 , I2 , O > ranges :: transform ( ExecutionPolicy && exec , I1 first1 , S1 last1 , I2 first2 , S2 last2 , O result , OutS result_last , F binary_op , Proj1 proj1 = {}, Proj2 proj2 = {}); template < execution - policy ExecutionPolicy , random_access_range R1 , random_access_range R2 , random_access_range OutR , copy_constructible F , class Proj1 = identity , class Proj2 = identity > requires indirectly_writable < iterator_t < OutR > , indirect_result_t < F & , projected < iterator_t < R1 > , Proj1 > , projected < iterator_t < R2 > , Proj2 >>> && sized_range < R1 > && sized_range < R2 > && sized_range < OutR > ranges :: binary_transform_result < borrowed_iterator_t < R1 > , borrowed_iterator_t < R2 > , borrowed_iterator_t < OutR >> ranges :: transform ( ExecutionPolicy && exec , R1 && r1 , R2 && r2 , OutR && result , F binary_op , Proj1 proj1 = {}, Proj2 proj2 = {});
8.25. Modify replace
in [alg.replace]
template < input_iterator I , sentinel_for < I > S , class Proj = identity , class T1 = projected_value_t < I , Proj > , class T2 = T1 > requires indirectly_writable < I , const T2 &> && indirect_binary_predicate < ranges :: equal_to , projected < I , Proj > , const T1 *> constexpr I ranges :: replace ( I first , S last , const T1 & old_value , const T2 & new_value , Proj proj = {}); template < input_range R , class Proj = identity , class T1 = projected_value_t < iterator_t < R > , Proj > , class T2 = T1 > requires indirectly_writable < iterator_t < R > , const T2 &> && indirect_binary_predicate < ranges :: equal_to , projected < iterator_t < R > , Proj > , const T1 *> constexpr borrowed_iterator_t < R > ranges :: replace ( R && r , const T1 & old_value , const T2 & new_value , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , class T1 = projected_value_t < I , Proj > , class T2 = T1 > requires indirectly_writable < I , const T2 &> && indirect_binary_predicate < ranges :: equal_to , projected < I , Proj > , const T1 *> I ranges :: replace ( ExecutionPolicy && exec , I first , S last , const T1 & old_value , const T2 & new_value , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , class T1 = projected_value_t < iterator_t < R > , Proj > , class T2 = T1 > requires indirectly_writable < iterator_t < R > , const T2 &> && indirect_binary_predicate < ranges :: equal_to , projected < iterator_t < R > , Proj > , const T1 *> && sized_range < R > borrowed_iterator_t < R > ranges :: replace ( ExecutionPolicy && exec , R && r , const T1 & old_value , const T2 & new_value , Proj proj = {});
template < input_iterator I , sentinel_for < I > S , class Proj = identity , class T = projected_value_t < I , Proj > , indirect_unary_predicate < projected < I , Proj >> Pred > requires indirectly_writable < I , const T &> constexpr I ranges :: replace_if ( I first , S last , Pred pred , const T & new_value , Proj proj = {}); template < input_range R , class Proj = identity , class T = projected_value_t < iterator_t < R > , Proj > , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires indirectly_writable < iterator_t < R > , const T &> constexpr borrowed_iterator_t < R > ranges :: replace_if ( R && r , Pred pred , const T & new_value , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , class T = projected_value_t < I , Proj > , indirect_unary_predicate < projected < I , Proj >> Pred > requires indirectly_writable < I , const T &> I ranges :: replace_if ( ExecutionPolicy && exec , I first , S last , Pred pred , const T & new_value , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , class T = projected_value_t < iterator_t < R > , Proj > , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires indirectly_writable < iterator_t < R > , const T &> && sized_range < R > borrowed_iterator_t < R > ranges :: replace_if ( ExecutionPolicy && exec , R && r , Pred pred , const T & new_value , Proj proj = {});
template < input_iterator I , sentinel_for < I > S , class O , class Proj = identity , class T1 = projected_value_t < I , Proj > , class T2 = iter_value_t < O >> requires indirectly_copyable < I , O > && indirect_binary_predicate < ranges :: equal_to , projected < I , Proj > , const T1 *> && output_iterator < O , const T2 &> constexpr ranges :: replace_copy_result < I , O > ranges :: replace_copy ( I first , S last , O result , const T1 & old_value , const T2 & new_value , Proj proj = {}); template < input_range R , class O , class Proj = identity , class T1 = projected_value_t < iterator_t < R > , Proj > , class T2 = iter_value_t < O >> requires indirectly_copyable < iterator_t < R > , O > && indirect_binary_predicate < ranges :: equal_to , projected < iterator_t < R > , Proj > , const T1 *> && output_iterator < O , const T2 &> constexpr ranges :: replace_copy_result < borrowed_iterator_t < R > , O > ranges :: replace_copy ( R && r , O result , const T1 & old_value , const T2 & new_value , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , random_access_iterator O , sized_sentinel_for < O > OutS > , class Proj = identity , class T1 = projected_value_t < I , Proj > , class T2 = iter_value_t < O >> requires indirectly_copyable < I , O > && indirect_binary_predicate < ranges :: equal_to , projected < I , Proj > , const T1 *> && indirectly_writable < O , const T2 &> ranges :: replace_copy_result < I , O > ranges :: replace_copy ( ExecutionPolicy && exec , I first , S last , O result , OutS result_last , const T1 & old_value , const T2 & new_value , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , random_access_range OutR , class Proj = identity , class T1 = projected_value_t < iterator_t < R > , Proj > , class T2 = range_value_t < OutR >> requires indirectly_copyable < iterator_t < R > , iterator_t < OutR >> && indirect_binary_predicate < ranges :: equal_to , projected < iterator_t < R > , Proj > , const T1 *> && indirectly_writable < iterator_t < OutR > , const T2 &> && sized_range < R > && sized_range < OutR > ranges :: replace_copy_result < borrowed_iterator_t < R > , borrowed_iterator_t < OutR >> ranges :: replace_copy ( ExecutionPolicy && exec , R && r , OutR && result , const T1 & old_value , const T2 & new_value , Proj proj = {});
template < input_iterator I , sentinel_for < I > S , class O , class T = iter_value_t < O > , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > requires indirectly_copyable < I , O > && output_iterator < O , const T &> constexpr ranges :: replace_copy_if_result < I , O > ranges :: replace_copy_if ( I first , S last , O result , Pred pred , const T & new_value , Proj proj = {}); template < input_range R , class O , class T = iter_value_t < O > , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires indirectly_copyable < iterator_t < R > , O > && output_iterator < O , const T &> constexpr ranges :: replace_copy_if_result < borrowed_iterator_t < R > , O > ranges :: replace_copy_if ( R && r , O result , Pred pred , const T & new_value , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , random_access_iterator O , sized_sentinel_for < O > OutS > , class T = iter_value_t < O > , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > requires indirectly_copyable < I , O > && indirectly_writable < O , const T &> ranges :: replace_copy_if_result < I , O > ranges :: replace_copy_if ( ExecutionPolicy && exec , I first , S last , O result , OutS result_last , Pred pred , const T & new_value , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , random_access_range OutR , class T = range_value_t < OutR > , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires indirectly_copyable < iterator_t < R > , iterator_t < OutR >> && indirectly_writable < iterator_t < OutR > , const T &> && sized_range < R > && sized_range < OutR > ranges :: replace_copy_if_result < borrowed_iterator_t < R > , borrowed_iterator_t < OutR >> ranges :: replace_copy_if ( ExecutionPolicy && exec , R && r , OutR && result , Pred pred , const T & new_value , Proj proj = {});
8.26. Modify fill
in [alg.fill]
template < class O , sentinel_for < O > S , class T = iter_value_t < O >> requires output_iterator < O , const T &> constexpr O ranges :: fill ( O first , S last , const T & value ); template < class R , class T = range_value_t < R >> requires output_range < R , const T &> constexpr borrowed_iterator_t < R > ranges :: fill ( R && r , const T & value ); template < class O , class T = iter_value_t < O >> requires output_iterator < O , const T &> constexpr O ranges :: fill_n ( O first , iter_difference_t < O > n , const T & value );
template < execution - policy ExecutionPolicy , random_access_iterator O , sized_sentinel_for < O > S , class T = iter_value_t < O >> requires output_iterator < O , const T &> O ranges :: fill ( ExecutionPolicy && exec , O first , S last , const T & value ); template < execution - policy ExecutionPolicy , random_access_range R , class T = range_value_t < R >> requires output_range < R , const T &> && sized_range < R > borrowed_iterator_t < R > ranges :: fill ( ExecutionPolicy && exec , R && r , const T & value ); template < execution - policy ExecutionPolicy , random_access_iterator O , class T = iter_value_t < O >> requires indirectly_writable < O , const T &> O ranges :: fill_n ( ExecutionPolicy && exec , O first , iter_difference_t < O > n , const T & value );
8.27. Modify generate
in [alg.generate]
template < input_or_output_iterator O , sentinel_for < O > S , copy_constructible F > requires invocable < F &> && indirectly_writable < O , invoke_result_t < F &>> constexpr O ranges :: generate ( O first , S last , F gen ); template < class R , copy_constructible F > requires invocable < F &> && output_range < R , invoke_result_t < F &>> constexpr borrowed_iterator_t < R > ranges :: generate ( R && r , F gen ); template < input_or_output_iterator O , copy_constructible F > requires invocable < F &> && indirectly_writable < O , invoke_result_t < F &>> constexpr O ranges :: generate_n ( O first , iter_difference_t < O > n , F gen );
template < execution - policy ExecutionPolicy , random_access_iterator O , sized_sentinel_for < O > S , copy_constructible F > requires invocable < F &> && indirectly_writable < O , invoke_result_t < F &>> O ranges :: generate ( ExecutionPolicy && exec , O first , S last , F gen ); template < execution - policy ExecutionPolicy , random_access_range R , copy_constructible F > requires invocable < F &> && output_range < R , invoke_result_t < F &>> && sized_range < R > borrowed_iterator_t < R > ranges :: generate ( ExecutionPolicy && exec , R && r , F gen ); template < execution - policy ExecutionPolicy , random_access_iterator O , copy_constructible F > requires invocable < F &> && indirectly_writable < O , invoke_result_t < F &>> O ranges :: generate_n ( ExecutionPolicy && exec , O first , iter_difference_t < O > n , F gen );
8.28. Modify remove
in [alg.remove]
template < permutable I , sentinel_for < I > S , class Proj = identity , class T = projected_value_t < I , Proj >> requires indirect_binary_predicate < ranges :: equal_to , projected < I , Proj > , const T *> constexpr subrange < I > ranges :: remove ( I first , S last , const T & value , Proj proj = {}); template < forward_range R , class Proj = identity , class T = projected_value_t < iterator_t < R > , Proj >> requires permutable < iterator_t < R >> && indirect_binary_predicate < ranges :: equal_to , projected < iterator_t < R > , Proj > , const T *> constexpr borrowed_subrange_t < R > ranges :: remove ( R && r , const T & value , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , class T = projected_value_t < I , Proj >> requires indirect_binary_predicate < ranges :: equal_to , projected < I , Proj > , const T *> subrange < I > ranges :: remove ( ExecutionPolicy && exec , I first , S last , const T & value , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , class T = projected_value_t < iterator_t < R > , Proj >> requires permutable < iterator_t < R >> && indirect_binary_predicate < ranges :: equal_to , projected < iterator_t < R > , Proj > , const T *> && sized_range < R > borrowed_subrange_t < R > ranges :: remove ( ExecutionPolicy && exec , R && r , const T & value , Proj proj = {});
template < permutable I , sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > constexpr subrange < I > ranges :: remove_if ( I first , S last , Pred pred , Proj proj = {}); template < forward_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires permutable < iterator_t < R >> constexpr borrowed_subrange_t < R > ranges :: remove_if ( R && r , Pred pred , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > subrange < I > ranges :: remove_if ( ExecutionPolicy && exec , I first , S last , Pred pred , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires permutable < iterator_t < R >> && sized_range < R > borrowed_subrange_t < R > ranges :: remove_if ( ExecutionPolicy && exec , R && r , Pred pred , Proj proj = {});
template < input_iterator I , sentinel_for < I > S , weakly_incrementable O , class Proj = identity , class T = projected_value_t < I , Proj >> requires indirectly_copyable < I , O > && indirect_binary_predicate < ranges :: equal_to , projected < I , Proj > , const T *> constexpr ranges :: remove_copy_result < I , O > ranges :: remove_copy ( I first , S last , O result , const T & value , Proj proj = {}); template < input_range R , weakly_incrementable O , class Proj = identity , class T = projected_value_t < iterator_t < R > , Proj >> requires indirectly_copyable < iterator_t < R > , O > && indirect_binary_predicate < ranges :: equal_to , projected < iterator_t < R > , Proj > , const T *> constexpr ranges :: remove_copy_result < borrowed_iterator_t < R > , O > ranges :: remove_copy ( R && r , O result , const T & value , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , random_access_iterator O , sized_sentinel_for < O > OutS > , class Proj = identity , class T = projected_value_t < I , Proj >> requires indirectly_copyable < I , O > && indirect_binary_predicate < ranges :: equal_to , projected < I , Proj > , const T *> ranges :: remove_copy_result < I , O > ranges :: remove_copy ( ExecutionPolicy && exec , I first , S last , O result , OutS result_last , const T & value , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , random_access_range OutR , class Proj = identity , class T = projected_value_t < iterator_t < R > , Proj >> requires indirectly_copyable < iterator_t < R > , iterator_t < OutR >> && indirect_binary_predicate < ranges :: equal_to , projected < iterator_t < R > , Proj > , const T *> && sized_range < R > && sized_range < OutR > ranges :: remove_copy_result < borrowed_iterator_t < R > , borrowed_iterator_t < OutR >> ranges :: remove_copy ( ExecutionPolicy && exec , R && r , OutR && result , const T & value , Proj proj = {});
template < input_iterator I , sentinel_for < I > S , weakly_incrementable O , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > requires indirectly_copyable < I , O > constexpr ranges :: remove_copy_if_result < I , O > ranges :: remove_copy_if ( I first , S last , O result , Pred pred , Proj proj = {}); template < input_range R , weakly_incrementable O , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires indirectly_copyable < iterator_t < R > , O > constexpr ranges :: remove_copy_if_result < borrowed_iterator_t < R > , O > ranges :: remove_copy_if ( R && r , O result , Pred pred , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , random_access_iterator O , sized_sentinel_for < O > OutS > , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > requires indirectly_copyable < I , O > ranges :: remove_copy_if_result < I , O > ranges :: remove_copy_if ( ExecutionPolicy && exec , I first , S last , O result , OutS result_last , Pred pred , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , random_access_range OutR , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires indirectly_copyable < iterator_t < R > , iterator_t < OutR >> && sized_range < R > && sized_range < OutR > ranges :: remove_copy_if_result < borrowed_iterator_t < R > , borrowed_iterator_t < OutR >> ranges :: remove_copy_if ( ExecutionPolicy && exec , R && r , OutR && result , Pred pred , Proj proj = {});
8.29. Modify unique
in [alg.unique]
template < permutable I , sentinel_for < I > S , class Proj = identity , indirect_equivalence_relation < projected < I , Proj >> C = ranges :: equal_to > constexpr subrange < I > ranges :: unique ( I first , S last , C comp = {}, Proj proj = {}); template < forward_range R , class Proj = identity , indirect_equivalence_relation < projected < iterator_t < R > , Proj >> C = ranges :: equal_to > requires permutable < iterator_t < R >> constexpr borrowed_subrange_t < R > ranges :: unique ( R && r , C comp = {}, Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_equivalence_relation < projected < I , Proj >> C = ranges :: equal_to > requires permutable < I > subrange < I > ranges :: unique ( ExecutionPolicy && exec , I first , S last , C comp = {}, Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_equivalence_relation < projected < iterator_t < R > , Proj >> C = ranges :: equal_to > requires permutable < iterator_t < R >> && sized_range < R > borrowed_subrange_t < R > ranges :: unique ( ExecutionPolicy && exec , R && r , C comp = {}, Proj proj = {});
template < input_iterator I , sentinel_for < I > S , weakly_incrementable O , class Proj = identity , indirect_equivalence_relation < projected < I , Proj >> C = ranges :: equal_to > requires indirectly_copyable < I , O > && ( forward_iterator < I > || ( input_iterator < O > && same_as < iter_value_t < I > , iter_value_t < O >> ) || indirectly_copyable_storable < I , O > ) constexpr ranges :: unique_copy_result < I , O > ranges :: unique_copy ( I first , S last , O result , C comp = {}, Proj proj = {}); template < input_range R , weakly_incrementable O , class Proj = identity , indirect_equivalence_relation < projected < iterator_t < R > , Proj >> C = ranges :: equal_to > requires indirectly_copyable < iterator_t < R > , O > && ( forward_iterator < iterator_t < R >> || ( input_iterator < O > && same_as < range_value_t < R > , iter_value_t < O >> ) || indirectly_copyable_storable < iterator_t < R > , O > ) constexpr ranges :: unique_copy_result < borrowed_iterator_t < R > , O > ranges :: unique_copy ( R && r , O result , C comp = {}, Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , random_access_iterator O , sized_sentinel_for < O > OutS > , class Proj = identity , indirect_equivalence_relation < projected < I , Proj >> C = ranges :: equal_to > requires indirectly_copyable < I , O > ranges :: unique_copy_result < I , O > ranges :: unique_copy ( ExecutionPolicy && exec , I first , S last , O result , OutS result_last , C comp = {}, Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , random_access_range OutR , class Proj = identity , indirect_equivalence_relation < projected < iterator_t < R > , Proj >> C = ranges :: equal_to > requires indirectly_copyable < iterator_t < R > , iterator_t < OutR >> && sized_range < R > && sized_range < OutR > ranges :: unique_copy_result < borrowed_iterator_t < R > , borrowed_iterator_t < OutR >> ranges :: unique_copy ( ExecutionPolicy && exec , R && r , OutR && result , C comp = {}, Proj proj = {});
8.30. Modify reverse
in [alg.reverse]
template < bidirectional_iterator I , sentinel_for < I > S > requires permutable < I > constexpr I ranges :: reverse ( I first , S last ); template < bidirectional_range R > requires permutable < iterator_t < R >> constexpr borrowed_iterator_t < R > ranges :: reverse ( R && r );
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S > requires permutable < I > I ranges :: reverse ( ExecutionPolicy && exec , I first , S last ); template < execution - policy ExecutionPolicy , random_access_range R > requires permutable < iterator_t < R >> && sized_range < R > borrowed_iterator_t < R > ranges :: reverse ( ExecutionPolicy && exec , R && r );
template < bidirectional_iterator I , sentinel_for < I > S , weakly_incrementable O > requires indirectly_copyable < I , O > constexpr ranges :: reverse_copy_result < I , O > ranges :: reverse_copy ( I first , S last , O result ); template < bidirectional_range R , weakly_incrementable O > requires indirectly_copyable < iterator_t < R > , O > constexpr ranges :: reverse_copy_result < borrowed_iterator_t < R > , O > ranges :: reverse_copy ( R && r , O result );
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , random_access_iterator O , sized_sentinel_for < O > OutS > requires indirectly_copyable < I , O > ranges :: reverse_copy_result < I , O > ranges :: reverse_copy ( ExecutionPolicy && exec , I first , S last , O result , OutS result_last ); template < execution - policy ExecutionPolicy , random_access_range R , random_access_range OutR > requires indirectly_copyable < iterator_t < R > , iterator_t < OutR >> && sized_range < R > && sized_range < OutR > ranges :: reverse_copy_result < borrowed_iterator_t < R > , borrowed_iterator_t < OutR >> ranges :: reverse_copy ( ExecutionPolicy && exec , R && r , OutR && result );
8.31. Modify rotate
in [alg.rotate]
template < permutable I , sentinel_for < I > S > constexpr subrange < I > ranges :: rotate ( I first , I middle , S last );
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S > requires permutable < I > subrange < I > ranges :: rotate ( ExecutionPolicy && exec , I first , I middle , S last );
template < forward_range R > requires permutable < iterator_t < R >> constexpr borrowed_subrange_t < R > ranges :: rotate ( R && r , iterator_t < R > middle );
Effects: Equivalent to:
template < execution - policy ExecutionPolicy , random_access_range R > requires permutable < iterator_t < R >> && sized_range < R > borrowed_subrange_t < R > ranges :: rotate ( ExecutionPolicy && exec , R && r , iterator_t < R > middle );
Effects: Equivalent to:
template < forward_iterator I , sentinel_for < I > S , weakly_incrementable O > requires indirectly_copyable < I , O > constexpr ranges :: rotate_copy_result < I , O > ranges :: rotate_copy ( I first , I middle , S last , O result );
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , random_access_iterator O , sized_sentinel_for < O > OutS > requires indirectly_copyable < I , O > ranges :: rotate_copy_result < I , O > ranges :: rotate_copy ( ExecutionPolicy && exec , I first , I middle , S last , O result , OutS result_last );
template < forward_range R , weakly_incrementable O > requires indirectly_copyable < iterator_t < R > , O > constexpr ranges :: rotate_copy_result < borrowed_iterator_t < R > , O > ranges :: rotate_copy ( R && r , iterator_t < R > middle , O result );
Effects: Equivalent to:
template < execution - policy ExecutionPolicy , random_access_range R , random_access_range OutR > requires indirectly_copyable < iterator_t < R > , iterator_t < OutR >> && sized_range < R > && sized_range < OutR > ranges :: rotate_copy_result < borrowed_iterator_t < R > , borrowed_iterator_t < OutR >> ranges :: rotate_copy ( ExecutionPolicy && exec , R && r , iterator_t < R > middle , OutR && result );
Effects: Equivalent to:
8.32. Modify shift
in [alg.shift]
template < permutable I , sentinel_for < I > S > constexpr subrange < I > ranges :: shift_left ( I first , S last , iter_difference_t < I > n ); template < forward_range R > requires permutable < iterator_t < R >> constexpr borrowed_subrange_t < R > ranges :: shift_left ( R && r , range_difference_t < R > n )
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S > requires permutable < I > subrange < I > ranges :: shift_left ( ExecutionPolicy && exec , I first , S last , iter_difference_t < I > n ); template < execution - policy ExecutionPolicy , random_access_range R > requires permutable < iterator_t < R >> && sized_range < R > borrowed_subrange_t < R > ranges :: shift_left ( ExecutionPolicy && exec , R && r , range_difference_t < R > n );
template < permutable I , sentinel_for < I > S > constexpr subrange < I > ranges :: shift_right ( I first , S last , iter_difference_t < I > n ); template < forward_range R > requires permutable < iterator_t < R >> constexpr borrowed_subrange_t < R > ranges :: shift_right ( R && r , range_difference_t < R > n );
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S > requires permutable < I > subrange < I > ranges :: shift_right ( ExecutionPolicy && exec , I first , S last , iter_difference_t < I > n ); template < execution - policy ExecutionPolicy , random_access_range R > requires permutable < iterator_t < R >> && sized_range < R > borrowed_subrange_t < R > ranges :: shift_right ( ExecutionPolicy && exec , R && r , range_difference_t < R > n );
8.33. Modify sort
in [sort]
template < random_access_iterator I , sentinel_for < I > S , class Comp = ranges :: less , class Proj = identity > requires sortable < I , Comp , Proj > constexpr I ranges :: sort ( I first , S last , Comp comp = {}, Proj proj = {}); template < random_access_range R , class Comp = ranges :: less , class Proj = identity > requires sortable < iterator_t < R > , Comp , Proj > constexpr borrowed_iterator_t < R > ranges :: sort ( R && r , Comp comp = {}, Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Comp = ranges :: less , class Proj = identity > requires sortable < I , Comp , Proj > I ranges :: sort ( ExecutionPolicy && exec , I first , S last , Comp comp = {}, Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Comp = ranges :: less , class Proj = identity > requires sortable < iterator_t < R > , Comp , Proj > && sized_range < R > borrowed_iterator_t < R > ranges :: sort ( ExecutionPolicy && exec , R && r , Comp comp = {}, Proj proj = {});
8.34. Modify stable_sort
in [stable.sort]
template < random_access_iterator I , sentinel_for < I > S , class Comp = ranges :: less , class Proj = identity > requires sortable < I , Comp , Proj > constexpr I ranges :: stable_sort ( I first , S last , Comp comp = {}, Proj proj = {}); template < random_access_range R , class Comp = ranges :: less , class Proj = identity > requires sortable < iterator_t < R > , Comp , Proj > constexpr borrowed_iterator_t < R > ranges :: stable_sort ( R && r , Comp comp = {}, Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Comp = ranges :: less , class Proj = identity > requires sortable < I , Comp , Proj > I ranges :: stable_sort ( ExecutionPolicy && exec , I first , S last , Comp comp = {}, Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Comp = ranges :: less , class Proj = identity > requires sortable < iterator_t < R > , Comp , Proj > && sized_range < R > borrowed_iterator_t < R > ranges :: stable_sort ( ExecutionPolicy && exec , R && r , Comp comp = {}, Proj proj = {});
8.35. Modify partial_sort
in [partial.sort]
template < random_access_iterator I , sentinel_for < I > S , class Comp = ranges :: less , class Proj = identity > requires sortable < I , Comp , Proj > constexpr I ranges :: partial_sort ( I first , I middle , S last , Comp comp = {}, Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Comp = ranges :: less , class Proj = identity > requires sortable < I , Comp , Proj > I ranges :: partial_sort ( ExecutionPolicy && exec , I first , I middle , S last , Comp comp = {}, Proj proj = {});
template < random_access_range R , class Comp = ranges :: less , class Proj = identity > requires sortable < iterator_t < R > , Comp , Proj > constexpr borrowed_iterator_t < R > ranges :: partial_sort ( R && r , iterator_t < R > middle , Comp comp = {}, Proj proj = {});
Effects: Equivalent to:
template < execution - policy ExecutionPolicy , random_access_range R , class Comp = ranges :: less , class Proj = identity > requires sortable < iterator_t < R > , Comp , Proj > && sized_range < R > borrowed_iterator_t < R > ranges :: partial_sort ( ExecutionPolicy && exec , R && r , iterator_t < R > middle , Comp comp = {}, Proj proj = {});
Effects: Equivalent to:
8.36. Modify partial_sort_copy
in [partial.sort.copy]
template < input_iterator I1 , sentinel_for < I1 > S1 , random_access_iterator I2 , sentinel_for < I2 > S2 , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires indirectly_copyable < I1 , I2 > && sortable < I2 , Comp , Proj2 > && indirect_strict_weak_order < Comp , projected < I1 , Proj1 > , projected < I2 , Proj2 >> constexpr ranges :: partial_sort_copy_result < I1 , I2 > ranges :: partial_sort_copy ( I1 first , S1 last , I2 result_first , S2 result_last , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < input_range R1 , random_access_range R2 , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires indirectly_copyable < iterator_t < R1 > , iterator_t < R2 >> && sortable < iterator_t < R2 > , Comp , Proj2 > && indirect_strict_weak_order < Comp , projected < iterator_t < R1 > , Proj1 > , projected < iterator_t < R2 > , Proj2 >> constexpr ranges :: partial_sort_copy_result < borrowed_iterator_t < R1 > , borrowed_iterator_t < R2 >> ranges :: partial_sort_copy ( R1 && r , R2 && result_r , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template < execution - policy ExecutionPolicy , random_access_range I1 , sized_sentinel_for < I1 > S1 , random_access_iterator I2 , sized_sentinel_for < I2 > S2 , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires indirectly_copyable < I1 , I2 > && sortable < I2 , Comp , Proj2 > && indirect_strict_weak_order < Comp , projected < I1 , Proj1 > , projected < I2 , Proj2 >> ranges :: partial_sort_copy_result < I1 , I2 > ranges :: partial_sort_copy ( ExecutionPolicy && exec , I1 first , S1 last , I2 result_first , S2 result_last , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < execution - policy ExecutionPolicy , random_access_range R1 , random_access_range R2 , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires indirectly_copyable < iterator_t < R1 > , iterator_t < R2 >> && sortable < iterator_t < R2 > , Comp , Proj2 > && indirect_strict_weak_order < Comp , projected < iterator_t < R1 > , Proj1 > , projected < iterator_t < R2 > , Proj2 >> && sized_range < R1 > && sized_range < R2 > ranges :: partial_sort_copy_result < borrowed_iterator_t < R1 > , borrowed_iterator_t < R2 >> ranges :: partial_sort_copy ( ExecutionPolicy && exec , R1 && r , R2 && result_r , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
8.37. Modify is_sorted
in [is.sorted]
template < forward_iterator I , sentinel_for < I > S , class Proj = identity , indirect_strict_weak_order < projected < I , Proj >> Comp = ranges :: less > constexpr bool ranges :: is_sorted ( I first , S last , Comp comp = {}, Proj proj = {}); template < forward_range R , class Proj = identity , indirect_strict_weak_order < projected < iterator_t < R > , Proj >> Comp = ranges :: less > constexpr bool ranges :: is_sorted ( R && r , Comp comp = {}, Proj proj = {});
Effects: Equivalent to:
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_strict_weak_order < projected < I , Proj >> Comp = ranges :: less > bool ranges :: is_sorted ( ExecutionPolicy && exec , I first , S last , Comp comp = {}, Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_strict_weak_order < projected < iterator_t < R > , Proj >> Comp = ranges :: less > requires sized_range < R > bool ranges :: is_sorted ( ExecutionPolicy && exec , R && r , Comp comp = {}, Proj proj = {});
Effects: Equivalent to:
template < forward_iterator I , sentinel_for < I > S , class Proj = identity , indirect_strict_weak_order < projected < I , Proj >> Comp = ranges :: less > constexpr I ranges :: is_sorted_until ( I first , S last , Comp comp = {}, Proj proj = {}); template < forward_range R , class Proj = identity , indirect_strict_weak_order < projected < iterator_t < R > , Proj >> Comp = ranges :: less > constexpr borrowed_iterator_t < R > ranges :: is_sorted_until ( R && r , Comp comp = {}, Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_strict_weak_order < projected < I , Proj >> Comp = ranges :: less > I ranges :: is_sorted_until ( ExecutionPolicy && exec , I first , S last , Comp comp = {}, Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_strict_weak_order < projected < iterator_t < R > , Proj >> Comp = ranges :: less > requires sized_range < R > borrowed_iterator_t < R > ranges :: is_sorted_until ( ExecutionPolicy && exec , R && r , Comp comp = {}, Proj proj = {});
8.38. Modify nth_element
in [alg.nth.element]
template < random_access_iterator I , sentinel_for < I > S , class Comp = ranges :: less , class Proj = identity > requires sortable < I , Comp , Proj > constexpr I ranges :: nth_element ( I first , I nth , S last , Comp comp = {}, Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Comp = ranges :: less , class Proj = identity > requires sortable < I , Comp , Proj > I ranges :: nth_element ( ExecutionPolicy && exec , I first , I nth , S last , Comp comp = {}, Proj proj = {});
template < random_access_range R , class Comp = ranges :: less , class Proj = identity > requires sortable < iterator_t < R > , Comp , Proj > constexpr borrowed_iterator_t < R > ranges :: nth_element ( R && r , iterator_t < R > nth , Comp comp = {}, Proj proj = {});
Effects: Equivalent to:
template < execution - policy ExecutionPolicy , random_access_range R , class Comp = ranges :: less , class Proj = identity > requires sortable < iterator_t < R > , Comp , Proj > && sized_range < R > borrowed_iterator_t < R > ranges :: nth_element ( ExecutionPolicy && exec , R && r , iterator_t < R > nth , Comp comp = {}, Proj proj = {});
Effects: Equivalent to:
8.39. Modify partitions
in [alg.partitions]
template < input_iterator I , sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > constexpr bool ranges :: is_partitioned ( I first , S last , Pred pred , Proj proj = {}); template < input_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > constexpr bool ranges :: is_partitioned ( R && r , Pred pred , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > bool ranges :: is_partitioned ( ExecutionPolicy && exec , I first , S last , Pred pred , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires sized_range < R > bool ranges :: is_partitioned ( ExecutionPolicy && exec , R && r , Pred pred , Proj proj = {});
template < permutable I , sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > constexpr subrange < I > ranges :: partition ( I first , S last , Pred pred , Proj proj = {}); template < forward_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires permutable < iterator_t < R >> constexpr borrowed_subrange_t < R > ranges :: partition ( R && r , Pred pred , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > subrange < I > ranges :: partition ( ExecutionPolicy && exec , I first , S last , Pred pred , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires permutable < iterator_t < R >> && sized_range < R > borrowed_subrange_t < R > ranges :: partition ( ExecutionPolicy && exec , R && r , Pred pred , Proj proj = {});
template < bidirectional_iterator I , sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > requires permutable < I > constexpr subrange < I > ranges :: stable_partition ( I first , S last , Pred pred , Proj proj = {}); template < bidirectional_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires permutable < iterator_t < R >> constexpr borrowed_subrange_t < R > ranges :: stable_partition ( R && r , Pred pred , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > requires permutable < I > subrange < I > ranges :: stable_partition ( ExecutionPolicy && exec , I first , S last , Pred pred , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires permutable < iterator_t < R >> && sized_range < R > borrowed_subrange_t < R > ranges :: stable_partition ( ExecutionPolicy && exec , R && r , Pred pred , Proj proj = {});
template < input_iterator I , sentinel_for < I > S , weakly_incrementable O1 , weakly_incrementable O2 , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > requires indirectly_copyable < I , O1 > && indirectly_copyable < I , O2 > constexpr ranges :: partition_copy_result < I , O1 , O2 > ranges :: partition_copy ( I first , S last , O1 out_true , O2 out_false , Pred pred , Proj proj = {}); template < input_range R , weakly_incrementable O1 , weakly_incrementable O2 , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires indirectly_copyable < iterator_t < R > , O1 > && indirectly_copyable < iterator_t < R > , O2 > constexpr ranges :: partition_copy_result < borrowed_iterator_t < R > , O1 , O2 > ranges :: partition_copy ( R && r , O1 out_true , O2 out_false , Pred pred , Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , random_access_iterator O1 , sized_sentinel_for < O1 > OutS1 , random_access_iterator O2 , sized_sentinel_for < O2 > OutS2 , class Proj = identity , indirect_unary_predicate < projected < I , Proj >> Pred > requires indirectly_copyable < I , O1 > && indirectly_copyable < I , O2 > ranges :: partition_copy_result < I , O1 , O2 > ranges :: partition_copy ( ExecutionPolicy && exec , I first , S last , O1 out_true , OutS1 last_true , O2 out_false , OutS2 last_false , Pred pred , Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , random_access_range OutR1 , random_access_range OutR2 , class Proj = identity , indirect_unary_predicate < projected < iterator_t < R > , Proj >> Pred > requires indirectly_copyable < iterator_t < R > , iterator_t < OutR1 >> && indirectly_copyable < iterator_t < R > , iterator_t < OutR2 >> && sized_range < R > && sized_range < OutR1 > && sized_range < OutR2 > ranges :: partition_copy_result < borrowed_iterator_t < R > , borrowed_iterator_t < OutR1 > , borrowed_iterator_t < OutR2 >> ranges :: partition_copy ( ExecutionPolicy && exec , R && r , OutR1 && out_true , OutR2 && out_false , Pred pred , Proj proj = {});
8.40. Modify merge
in [alg.merge]
template < input_iterator I1 , sentinel_for < I1 > S1 , input_iterator I2 , sentinel_for < I2 > S2 , weakly_incrementable O , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires mergeable < I1 , I2 , O , Comp , Proj1 , Proj2 > constexpr ranges :: merge_result < I1 , I2 , O > ranges :: merge ( I1 first1 , S1 last1 , I2 first2 , S2 last2 , O result , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < input_range R1 , input_range R2 , weakly_incrementable O , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires mergeable < iterator_t < R1 > , iterator_t < R2 > , O , Comp , Proj1 , Proj2 > constexpr ranges :: merge_result < borrowed_iterator_t < R1 > , borrowed_iterator_t < R2 > , O > ranges :: merge ( R1 && r1 , R2 && r2 , O result , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template < execution - policy ExecutionPolicy , random_access_iterator I1 , sized_sentinel_for < I1 > S1 , random_access_iterator I2 , sized_sentinel_for < I2 > S2 , random_access_iterator O , sized_sentinel_for < O > OutS , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires mergeable < I1 , I2 , O , Comp , Proj1 , Proj2 > ranges :: merge_result < I1 , I2 , O > ranges :: merge ( ExecutionPolicy && exec , I1 first1 , S1 last1 , I2 first2 , S2 last2 , O result , OutS result_last , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < execution - policy ExecutionPolicy , random_access_range R1 , random_access_range R2 , random_access_range OutR , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires mergeable < iterator_t < R1 > , iterator_t < R2 > , iterator_t < OutR > , Comp , Proj1 , Proj2 > && sized_range < R1 > && sized_range < R2 > && sized_range < OutR > ranges :: merge_result < borrowed_iterator_t < R1 > , borrowed_iterator_t < R2 > , borrowed_iterator_t < OutR >> ranges :: merge ( ExecutionPolicy && exec , R1 && r1 , R2 && r2 , OutR && result , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template < bidirectional_iterator I , sentinel_for < I > S , class Comp = ranges :: less , class Proj = identity > requires sortable < I , Comp , Proj > constexpr I ranges :: inplace_merge ( I first , I middle , S last , Comp comp = {}, Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Comp = ranges :: less , class Proj = identity > requires sortable < I , Comp , Proj > I ranges :: inplace_merge ( ExecutionPolicy && exec , I first , I middle , S last , Comp comp = {}, Proj proj = {});
template < bidirectional_range R , class Comp = ranges :: less , class Proj = identity > requires sortable < iterator_t < R > , Comp , Proj > constexpr borrowed_iterator_t < R > ranges :: inplace_merge ( R && r , iterator_t < R > middle , Comp comp = {}, Proj proj = {});
Effects: Equivalent to:
template < execution - policy ExecutionPolicy , random_access_range R , class Comp = ranges :: less , class Proj = identity > requires sortable < iterator_t < R > , Comp , Proj > && sized_range < R > borrowed_iterator_t < R > ranges :: inplace_merge ( ExecutionPolicy && exec , R && r , iterator_t < R > middle , Comp comp = {}, Proj proj = {});
Effects: Equivalent to:
8.41. Modify includes
in [includes]
template < input_iterator I1 , sentinel_for < I1 > S1 , input_iterator I2 , sentinel_for < I2 > S2 , class Proj1 = identity , class Proj2 = identity , indirect_strict_weak_order < projected < I1 , Proj1 > , projected < I2 , Proj2 >> Comp = ranges :: less > constexpr bool ranges :: includes ( I1 first1 , S1 last1 , I2 first2 , S2 last2 , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < input_range R1 , input_range R2 , class Proj1 = identity , class Proj2 = identity , indirect_strict_weak_order < projected < iterator_t < R1 > , Proj1 > , projected < iterator_t < R2 > , Proj2 >> Comp = ranges :: less > constexpr bool ranges :: includes ( R1 && r1 , R2 && r2 , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template < execution - policy ExecutionPolicy , random_access_iterator I1 , sized_sentinel_for < I1 > S1 , random_access_iterator I2 , sized_sentinel_for < I2 > S2 , class Proj1 = identity , class Proj2 = identity , indirect_strict_weak_order < projected < I1 , Proj1 > , projected < I2 , Proj2 >> Comp = ranges :: less > bool ranges :: includes ( ExecutionPolicy && exec , I1 first1 , S1 last1 , I2 first2 , S2 last2 , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < execution - policy ExecutionPolicy , random_access_range R1 , random_access_range R2 , class Proj1 = identity , class Proj2 = identity , indirect_strict_weak_order < projected < iterator_t < R1 > , Proj1 > , projected < iterator_t < R2 > , Proj2 >> Comp = ranges :: less > requires sized_range < R1 > && sized_range < R2 > bool ranges :: includes ( ExecutionPolicy && exec , R1 && r1 , R2 && r2 , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
8.42. Modify set_union
in [set.union]
template < input_iterator I1 , sentinel_for < I1 > S1 , input_iterator I2 , sentinel_for < I2 > S2 , weakly_incrementable O , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires mergeable < I1 , I2 , O , Comp , Proj1 , Proj2 > constexpr ranges :: set_union_result < I1 , I2 , O > ranges :: set_union ( I1 first1 , S1 last1 , I2 first2 , S2 last2 , O result , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < input_range R1 , input_range R2 , weakly_incrementable O , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires mergeable < iterator_t < R1 > , iterator_t < R2 > , O , Comp , Proj1 , Proj2 > constexpr ranges :: set_union_result < borrowed_iterator_t < R1 > , borrowed_iterator_t < R2 > , O > ranges :: set_union ( R1 && r1 , R2 && r2 , O result , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template < execution - policy ExecutionPolicy , random_access_iterator I1 , sized_sentinel_for < I1 > S1 , random_access_iterator I2 , sized_sentinel_for < I2 > S2 , random_access_iterator O , sized_sentinel_for < O > OutS , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires mergeable < I1 , I2 , O , Comp , Proj1 , Proj2 > ranges :: set_union_result < I1 , I2 , O > ranges :: set_union ( ExecutionPolicy && exec , I1 first1 , S1 last1 , I2 first2 , S2 last2 , O result , OutS result_last , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < execution - policy ExecutionPolicy , random_access_range R1 , random_access_range R2 , random_access_range OutR , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires mergeable < iterator_t < R1 > , iterator_t < R2 > , iterator_t < OutR > , Comp , Proj1 , Proj2 > && sized_range < R1 > && sized_range < R2 > && sized_range < OutR > ranges :: set_union_result < borrowed_iterator_t < R1 > , borrowed_iterator_t < R2 > , borrowed_iterator_t < OutR >> ranges :: set_union ( ExecutionPolicy && exec , R1 && r1 , R2 && r2 , OutR && result , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
8.43. Modify set_intersection
in [set.intersection]
template < input_iterator I1 , sentinel_for < I1 > S1 , input_iterator I2 , sentinel_for < I2 > S2 , weakly_incrementable O , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires mergeable < I1 , I2 , O , Comp , Proj1 , Proj2 > constexpr ranges :: set_intersection_result < I1 , I2 , O > ranges :: set_intersection ( I1 first1 , S1 last1 , I2 first2 , S2 last2 , O result , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < input_range R1 , input_range R2 , weakly_incrementable O , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires mergeable < iterator_t < R1 > , iterator_t < R2 > , O , Comp , Proj1 , Proj2 > constexpr ranges :: set_intersection_result < borrowed_iterator_t < R1 > , borrowed_iterator_t < R2 > , O > ranges :: set_intersection ( R1 && r1 , R2 && r2 , O result , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template < execution - policy ExecutionPolicy , random_access_iterator I1 , sized_sentinel_for < I1 > S1 , random_access_iterator I2 , sized_sentinel_for < I2 > S2 , random_access_iterator O , sized_sentinel_for < O > OutS , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires mergeable < I1 , I2 , O , Comp , Proj1 , Proj2 > ranges :: set_intersection_result < I1 , I2 , O > ranges :: set_intersection ( ExecutionPolicy && exec , I1 first1 , S1 last1 , I2 first2 , S2 last2 , O result , OutS result_last , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < execution - policy ExecutionPolicy , random_access_range R1 , random_access_range R2 , random_access_range OutR , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires mergeable < iterator_t < R1 > , iterator_t < R2 > , iterator_t < OutR > , Comp , Proj1 , Proj2 > && sized_range < R1 > && sized_range < R2 > && sized_range < OutR > ranges :: set_intersection_result < borrowed_iterator_t < R1 > , borrowed_iterator_t < R2 > , borrowed_iterator_t < OutR >> ranges :: set_intersection ( ExecutionPolicy && exec , R1 && r1 , R2 && r2 , OutR && result , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
8.44. Modify set_difference
in [set.difference]
template < input_iterator I1 , sentinel_for < I1 > S1 , input_iterator I2 , sentinel_for < I2 > S2 , weakly_incrementable O , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires mergeable < I1 , I2 , O , Comp , Proj1 , Proj2 > constexpr ranges :: set_difference_result < I1 , O > ranges :: set_difference ( I1 first1 , S1 last1 , I2 first2 , S2 last2 , O result , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < input_range R1 , input_range R2 , weakly_incrementable O , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires mergeable < iterator_t < R1 > , iterator_t < R2 > , O , Comp , Proj1 , Proj2 > constexpr ranges :: set_difference_result < borrowed_iterator_t < R1 > , O > ranges :: set_difference ( R1 && r1 , R2 && r2 , O result , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template < execution - policy ExecutionPolicy , random_access_iterator I1 , sized_sentinel_for < I1 > S1 , random_access_iterator I2 , sized_sentinel_for < I2 > S2 , random_access_iterator O , sized_sentinel_for < O > OutS , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires mergeable < I1 , I2 , O , Comp , Proj1 , Proj2 > ranges :: set_difference_result < I1 , O > ranges :: set_difference ( ExecutionPolicy && exec , I1 first1 , S1 last1 , I2 first2 , S2 last2 , O result , OutS result_last , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < execution - policy ExecutionPolicy , random_access_range R1 , random_access_range R2 , random_access_range OutR , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires mergeable < iterator_t < R1 > , iterator_t < R2 > , iterator_t < OutR > , Comp , Proj1 , Proj2 > && sized_range < R1 > && sized_range < R2 > && sized_range < OutR > ranges :: set_difference_result < borrowed_iterator_t < R1 > , borrowed_iterator_t < OutR >> ranges :: set_difference ( ExecutionPolicy && exec , R1 && r1 , R2 && r2 , OutR && result , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
8.45. Modify set_symmetric_difference
in [set.symmetric.difference]
template < input_iterator I1 , sentinel_for < I1 > S1 , input_iterator I2 , sentinel_for < I2 > S2 , weakly_incrementable O , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires mergeable < I1 , I2 , O , Comp , Proj1 , Proj2 > constexpr ranges :: set_symmetric_difference_result < I1 , I2 , O > ranges :: set_symmetric_difference ( I1 first1 , S1 last1 , I2 first2 , S2 last2 , O result , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < input_range R1 , input_range R2 , weakly_incrementable O , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires mergeable < iterator_t < R1 > , iterator_t < R2 > , O , Comp , Proj1 , Proj2 > constexpr ranges :: set_symmetric_difference_result < borrowed_iterator_t < R1 > , borrowed_iterator_t < R2 > , O > ranges :: set_symmetric_difference ( R1 && r1 , R2 && r2 , O result , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template < execution - policy ExecutionPolicy , random_access_iterator I1 , sized_sentinel_for < I1 > S1 , random_access_iterator I2 , sized_sentinel_for < I2 > S2 , random_access_iterator O , sized_sentinel_for < O > OutS , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires mergeable < I1 , I2 , O , Comp , Proj1 , Proj2 > ranges :: set_symmetric_difference_result < I1 , I2 , O > ranges :: set_symmetric_difference ( ExecutionPolicy && exec , I1 first1 , S1 last1 , I2 first2 , S2 last2 , O result , OutS result_last , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < execution - policy ExecutionPolicy , random_access_range R1 , random_access_range R2 , random_access_range OutR , class Comp = ranges :: less , class Proj1 = identity , class Proj2 = identity > requires mergeable < iterator_t < R1 > , iterator_t < R2 > , iterator_t < OutR > , Comp , Proj1 , Proj2 > && sized_range < R1 > && sized_range < R2 > && sized_range < OutR > ranges :: set_symmetric_difference_result < borrowed_iterator_t < R1 > , borrowed_iterator_t < R2 > , borrowed_iterator_t < OutR >> ranges :: set_symmetric_difference ( ExecutionPolicy && exec , R1 && r1 , R2 && r2 , OutR && result , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
8.46. Modify is_heap
in [is.heap]
template < random_access_iterator I , sentinel_for < I > S , class Proj = identity , indirect_strict_weak_order < projected < I , Proj >> Comp = ranges :: less > constexpr bool ranges :: is_heap ( I first , S last , Comp comp = {}, Proj proj = {}); template < random_access_range R , class Proj = identity , indirect_strict_weak_order < projected < iterator_t < R > , Proj >> Comp = ranges :: less > constexpr bool ranges :: is_heap ( R && r , Comp comp = {}, Proj proj = {});
Effects: Equivalent to:
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_strict_weak_order < projected < I , Proj >> Comp = ranges :: less > bool ranges :: is_heap ( ExecutionPolicy && exec , I first , S last , Comp comp = {}, Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_strict_weak_order < projected < iterator_t < R > , Proj >> Comp = ranges :: less > requires sized_range < R > bool ranges :: is_heap ( ExecutionPolicy && exec , R && r , Comp comp = {}, Proj proj = {});
Effects: Equivalent to:
template < random_access_iterator I , sentinel_for < I > S , class Proj = identity , indirect_strict_weak_order < projected < I , Proj >> Comp = ranges :: less > constexpr I ranges :: is_heap_until ( I first , S last , Comp comp = {}, Proj proj = {}); template < random_access_range R , class Proj = identity , indirect_strict_weak_order < projected < iterator_t < R > , Proj >> Comp = ranges :: less > constexpr borrowed_iterator_t < R > ranges :: is_heap_until ( R && r , Comp comp = {}, Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_strict_weak_order < projected < I , Proj >> Comp = ranges :: less > I ranges :: is_heap_until ( ExecutionPolicy && exec , I first , S last , Comp comp = {}, Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_strict_weak_order < projected < iterator_t < R > , Proj >> Comp = ranges :: less > requires sized_range < R > borrowed_iterator_t < R > ranges :: is_heap_until ( ExecutionPolicy && exec , R && r , Comp comp = {}, Proj proj = {});
8.47. Modify min
, max
, minmax
in [alg.min.max]
template < input_range R , class Proj = identity , indirect_strict_weak_order < projected < iterator_t < R > , Proj >> Comp = ranges :: less > requires indirectly_copyable_storable < iterator_t < R > , range_value_t < R >*> constexpr range_value_t < R > ranges :: min ( R && r , Comp comp = {}, Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_strict_weak_order < projected < iterator_t < R > , Proj >> Comp = ranges :: less > requires sized_range < R > && indirectly_copyable_storable < iterator_t < R > , range_value_t < R >*> range_value_t < R > ranges :: min ( ExecutionPolicy && exec , R && r , Comp comp = {}, Proj proj = {});
template < input_range R , class Proj = identity , indirect_strict_weak_order < projected < iterator_t < R > , Proj >> Comp = ranges :: less > requires indirectly_copyable_storable < iterator_t < R > , range_value_t < R >*> constexpr range_value_t < R > ranges :: max ( R && r , Comp comp = {}, Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_strict_weak_order < projected < iterator_t < R > , Proj >> Comp = ranges :: less > requires sized_range < R > && indirectly_copyable_storable < iterator_t < R > , range_value_t < R >*> range_value_t < R > ranges :: max ( ExecutionPolicy && exec , R && r , Comp comp = {}, Proj proj = {});
template < input_range R , class Proj = identity , indirect_strict_weak_order < projected < iterator_t < R > , Proj >> Comp = ranges :: less > requires indirectly_copyable_storable < iterator_t < R > , range_value_t < R >*> constexpr ranges :: minmax_result < range_value_t < R >> ranges :: minmax ( R && r , Comp comp = {}, Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_strict_weak_order < projected < iterator_t < R > , Proj >> Comp = ranges :: less > requires indirectly_copyable_storable < iterator_t < R > , range_value_t < R >*> && sized_range < R > ranges :: minmax_result < range_value_t < R >> ranges :: minmax ( ExecutionPolicy && exec , R && r , Comp comp = {}, Proj proj = {});
template < forward_iterator I , sentinel_for < I > S , class Proj = identity , indirect_strict_weak_order < projected < I , Proj >> Comp = ranges :: less > constexpr I ranges :: min_element ( I first , S last , Comp comp = {}, Proj proj = {}); template < forward_range R , class Proj = identity , indirect_strict_weak_order < projected < iterator_t < R > , Proj >> Comp = ranges :: less > constexpr borrowed_iterator_t < R > ranges :: min_element ( R && r , Comp comp = {}, Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_strict_weak_order < projected < I , Proj >> Comp = ranges :: less > I ranges :: min_element ( ExecutionPolicy && exec , I first , S last , Comp comp = {}, Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_strict_weak_order < projected < iterator_t < R > , Proj >> Comp = ranges :: less > requires sized_range < R > borrowed_iterator_t < R > ranges :: min_element ( ExecutionPolicy && exec , R && r , Comp comp = {}, Proj proj = {});
template < forward_iterator I , sentinel_for < I > S , class Proj = identity , indirect_strict_weak_order < projected < I , Proj >> Comp = ranges :: less > constexpr I ranges :: max_element ( I first , S last , Comp comp = {}, Proj proj = {}); template < forward_range R , class Proj = identity , indirect_strict_weak_order < projected < iterator_t < R > , Proj >> Comp = ranges :: less > constexpr borrowed_iterator_t < R > ranges :: max_element ( R && r , Comp comp = {}, Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_strict_weak_order < projected < I , Proj >> Comp = ranges :: less > I ranges :: max_element ( ExecutionPolicy && exec , I first , S last , Comp comp = {}, Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_strict_weak_order < projected < iterator_t < R > , Proj >> Comp = ranges :: less > requires sized_range < R > borrowed_iterator_t < R > ranges :: max_element ( ExecutionPolicy && exec , R && r , Comp comp = {}, Proj proj = {});
template < forward_iterator I , sentinel_for < I > S , class Proj = identity , indirect_strict_weak_order < projected < I , Proj >> Comp = ranges :: less > constexpr ranges :: minmax_element_result < I > ranges :: minmax_element ( I first , S last , Comp comp = {}, Proj proj = {}); template < forward_range R , class Proj = identity , indirect_strict_weak_order < projected < iterator_t < R > , Proj >> Comp = ranges :: less > constexpr ranges :: minmax_element_result < borrowed_iterator_t < R >> ranges :: minmax_element ( R && r , Comp comp = {}, Proj proj = {});
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S , class Proj = identity , indirect_strict_weak_order < projected < I , Proj >> Comp = ranges :: less > ranges :: minmax_element_result < I > ranges :: minmax_element ( ExecutionPolicy && exec , I first , S last , Comp comp = {}, Proj proj = {}); template < execution - policy ExecutionPolicy , random_access_range R , class Proj = identity , indirect_strict_weak_order < projected < iterator_t < R > , Proj >> Comp = ranges :: less > requires sized_range < R > ranges :: minmax_element_result < borrowed_iterator_t < R >> ranges :: minmax_element ( ExecutionPolicy && exec , R && r , Comp comp = {}, Proj proj = {});
8.48. Modify lexicographical_compare
in [alg.lex.comparison]
template < input_iterator I1 , sentinel_for < I1 > S1 , input_iterator I2 , sentinel_for < I2 > S2 , class Proj1 = identity , class Proj2 = identity , indirect_strict_weak_order < projected < I1 , Proj1 > , projected < I2 , Proj2 >> Comp = ranges :: less > constexpr bool ranges :: lexicographical_compare ( I1 first1 , S1 last1 , I2 first2 , S2 last2 , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < input_range R1 , input_range R2 , class Proj1 = identity , class Proj2 = identity , indirect_strict_weak_order < projected < iterator_t < R1 > , Proj1 > , projected < iterator_t < R2 > , Proj2 >> Comp = ranges :: less > constexpr bool ranges :: lexicographical_compare ( R1 && r1 , R2 && r2 , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template < execution - policy ExecutionPolicy , random_access_iterator I1 , sized_sentinel_for < I1 > S1 , random_access_iterator I2 , sized_sentinel_for < I2 > S2 , class Proj1 = identity , class Proj2 = identity , indirect_strict_weak_order < projected < I1 , Proj1 > , projected < I2 , Proj2 >> Comp = ranges :: less > bool ranges :: lexicographical_compare ( ExecutionPolicy && exec , I1 first1 , S1 last1 , I2 first2 , S2 last2 , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); template < execution - policy ExecutionPolicy , random_access_range R1 , random_access_range R2 , class Proj1 = identity , class Proj2 = identity , indirect_strict_weak_order < projected < iterator_t < R1 > , Proj1 > , projected < iterator_t < R2 > , Proj2 >> Comp = ranges :: less > requires sized_range < R1 > && sized_range < R2 > bool ranges :: lexicographical_compare ( ExecutionPolicy && exec , R1 && r1 , R2 && r2 , Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
8.49. Modify [memory.syn]
// [specialized.algorithms], specialized algorithms // [special.mem.concepts], special memory concepts template < class I > concept nothrow - input - iterator = see below ; // exposition only template < class I > concept nothrow - forward - iterator = see below ; // exposition only template < class I > concept nothrow - bidirectional - iterator = see below ; // exposition only template < class I > concept nothrow - random - access - iterator = see below ; // exposition only template < class S , class I > concept nothrow - sentinel - for = see below ; // exposition only template < class S , class I > concept nothrow - sized - sentinel - for = see below ; // exposition only template < class R > concept nothrow - input - range = see below ; // exposition only template < class R > concept nothrow - forward - range = see below ; // exposition only template < class I > concept nothrow - bidirectional - range = see below ; // exposition only template < class I > concept nothrow - random - access - range = see below ; // exposition only
template < nothrow - forward - iterator I , nothrow - sentinel - for < I > S > requires default_initializable < iter_value_t < I >> I uninitialized_default_construct ( I first , S last ); // freestanding template < nothrow - forward - range R > requires default_initializable < range_value_t < R >> borrowed_iterator_t < R > uninitialized_default_construct ( R && r ); // freestanding template < nothrow - forward - iterator I > requires default_initializable < iter_value_t < I >> I uninitialized_default_construct_n ( I first , iter_difference_t < I > n ); // freestanding
template < execution - policy ExecutionPolicy , nothrow - random - access - iterator I , nothrow - sized - sentinel - for < I > S > requires default_initializable < iter_value_t < I >> I uninitialized_default_construct ( ExecutionPolicy && exec , I first , S last ); // see [algorithms.parallel.overloads] template < execution - policy ExecutionPolicy , nothrow - random - access - range R > requires default_initializable < range_value_t < R >> && sized_range < R > borrowed_iterator_t < R > uninitialized_default_construct ( ExecutionPolicy && exec , R && r ); // see [algorithms.parallel.overloads] template < execution - policy ExecutionPolicy , nothrow - random - access - iterator I > requires default_initializable < iter_value_t < I >> I uninitialized_default_construct_n ( ExecutionPolicy && exec , I first , iter_difference_t < I > n ); // see [algorithms.parallel.overloads]
template < nothrow - forward - iterator I , nothrow - sentinel - for < I > S > requires default_initializable < iter_value_t < I >> I uninitialized_value_construct ( I first , S last ); // freestanding template < nothrow - forward - range R > requires default_initializable < range_value_t < R >> borrowed_iterator_t < R > uninitialized_value_construct ( R && r ); // freestanding template < nothrow - forward - iterator I > requires default_initializable < iter_value_t < I >> I uninitialized_value_construct_n ( I first , iter_difference_t < I > n ); // freestanding
template < execution - policy ExecutionPolicy , nothrow - random - access - iterator I , nothrow - sized - sentinel - for < I > S > requires default_initializable < iter_value_t < I >> I uninitialized_value_construct ( ExecutionPolicy && exec , I first , S last ); // see [algorithms.parallel.overloads] template < execution - policy ExecutionPolicy , nothrow - random - access - range R > requires default_initializable < range_value_t < R >> && sized_range < R > borrowed_iterator_t < R > uninitialized_value_construct ( ExecutionPolicy && exec , R && r ); // see [algorithms.parallel.overloads] template < execution - policy ExecutionPolicy , nothrow - random - access - iterator I > requires default_initializable < iter_value_t < I >> I uninitialized_value_construct_n ( ExecutionPolicy && exec , I first , iter_difference_t < I > n ); // see [algorithms.parallel.overloads]
template < input_iterator I , sentinel_for < I > S1 , nothrow - forward - iterator O , nothrow - sentinel - for < O > S2 > requires constructible_from < iter_value_t < O > , iter_reference_t < I >> uninitialized_copy_result < I , O > uninitialized_copy ( I ifirst , S1 ilast , O ofirst , S2 olast ); // freestanding template < input_range IR , nothrow - forward - range OR > requires constructible_from < range_value_t < OR > , range_reference_t < IR >> uninitialized_copy_result < borrowed_iterator_t < IR > , borrowed_iterator_t < OR >> uninitialized_copy ( IR && in_range , OR && out_range ); // freestanding template < class I , class O > using uninitialized_copy_n_result = in_out_result < I , O > ; // freestanding template < input_iterator I , nothrow - forward - iterator O , nothrow - sentinel - for < O > S > requires constructible_from < iter_value_t < O > , iter_reference_t < I >> uninitialized_copy_n_result < I , O > uninitialized_copy_n ( I ifirst , iter_difference_t < I > n , // freestanding O ofirst , S olast );
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S1 , nothrow - random - access - iterator O , nothrow - sized - sentinel - for < O > S2 > requires constructible_from < iter_value_t < O > , iter_reference_t < I >> uninitialized_copy_result < I , O > uninitialized_copy ( ExecutionPolicy && exec , I ifirst , S1 ilast , O ofirst , S2 olast ); // see [algorithms.parallel.overloads] template < execution - policy ExecutionPolicy , random_access_range IR , nothrow - random - access - range OR > requires constructible_from < range_value_t < OR > , range_reference_t < IR >> && sized_range < IR > && sized_range < OR > uninitialized_copy_result < borrowed_iterator_t < IR > , borrowed_iterator_t < OR >> uninitialized_copy ( ExecutionPolicy && exec , IR && in_range , OR && out_range ); // see [algorithms.parallel.overloads] template < execution - policy ExecutionPolicy , random_access_iterator I , nothrow - random - access - iterator O , nothrow - sized - sentinel - for < O > S > requires constructible_from < iter_value_t < O > , iter_reference_t < I >> uninitialized_copy_n_result < I , O > uninitialized_copy_n ( ExecutionPolicy && exec , I ifirst , iter_difference_t < I > n , // see [algorithms.parallel.overloads] O ofirst , S olast );
template < input_iterator I , sentinel_for < I > S1 , nothrow - forward - iterator O , nothrow - sentinel - for < O > S2 > requires constructible_from < iter_value_t < O > , iter_rvalue_reference_t < I >> uninitialized_move_result < I , O > uninitialized_move ( I ifirst , S1 ilast , O ofirst , S2 olast ); // freestanding template < input_range IR , nothrow - forward - range OR > requires constructible_from < range_value_t < OR > , range_rvalue_reference_t < IR >> uninitialized_move_result < borrowed_iterator_t < IR > , borrowed_iterator_t < OR >> uninitialized_move ( IR && in_range , OR && out_range ); // freestanding template < input_iterator I , nothrow - forward - iterator O , nothrow - sentinel - for < O > S > requires constructible_from < iter_value_t < O > , iter_rvalue_reference_t < I >> uninitialized_move_n_result < I , O > uninitialized_move_n ( I ifirst , iter_difference_t < I > n , // freestanding O ofirst , S olast );
template < execution - policy ExecutionPolicy , random_access_iterator I , sized_sentinel_for < I > S1 , nothrow - random - access - iterator O , nothrow - sized - sentinel - for < O > S2 > requires constructible_from < iter_value_t < O > , iter_rvalue_reference_t < I >> uninitialized_move_result < I , O > uninitialized_move ( ExecutionPolicy && exec , I ifirst , S1 ilast , O ofirst , S2 olast ); // see [algorithms.parallel.overloads] template < execution - policy ExecutionPolicy , random_access_range IR , nothrow - random - access - range OR > requires constructible_from < range_value_t < OR > , range_rvalue_reference_t < IR >> && sized_range < IR > && sized_range < OR > uninitialized_move_result < borrowed_iterator_t < IR > , borrowed_iterator_t < OR >> uninitialized_move ( ExecutionPolicy && exec , IR && in_range , OR && out_range ); // see [algorithms.parallel.overloads] template < execution - policy ExecutionPolicy , random_access_iterator I , nothrow - random - access - iterator O , nothrow - sized - sentinel - for < O > S > requires constructible_from < iter_value_t < O > , iter_rvalue_reference_t < I >> uninitialized_move_n_result < I , O > uninitialized_move_n ( ExecutionPolicy && exec , I ifirst , iter_difference_t < I > n , // see [algorithms.parallel.overloads] O ofirst , S olast );
template < nothrow - forward - iterator I , nothrow - sentinel - for < I > S , class T > requires constructible_from < iter_value_t < I > , const T &> I uninitialized_fill ( I first , S last , const T & x ); // freestanding template < nothrow - forward - range R , class T > requires constructible_from < range_value_t < R > , const T &> borrowed_iterator_t < R > uninitialized_fill ( R && r , const T & x ); // freestanding template < nothrow - forward - iterator I , class T > requires constructible_from < iter_value_t < I > , const T &> I uninitialized_fill_n ( I first , iter_difference_t < I > n , const T & x ); // freestanding
template < execution - policy ExecutionPolicy , nothrow - random - access - iterator I , nothrow - sized - sentinel - for < I > S , class T > requires constructible_from < iter_value_t < I > , const T &> I uninitialized_fill ( ExecutionPolicy && exec , I first , S last , const T & x ); // see [algorithms.parallel.overloads] template < execution - policy ExecutionPolicy , nothrow - random - access - range R , class T > requires constructible_from < range_value_t < R > , const T &> && sized_range < R > borrowed_iterator_t < R > uninitialized_fill ( ExecutionPolicy && exec , R && r , const T & x ); // see [algorithms.parallel.overloads] template < execution - policy ExecutionPolicy , nothrow - random - access - iterator I , class T > requires constructible_from < iter_value_t < I > , const T &> I uninitialized_fill_n ( ExecutionPolicy && exec , I first , iter_difference_t < I > n , const T & x ); // see [algorithms.parallel.overloads]
template < nothrow - input - iterator I , nothrow - sentinel - for < I > S > requires destructible < iter_value_t < I >> constexpr I destroy ( I first , S last ) noexcept ; // freestanding template < nothrow - input - range R > requires destructible < range_value_t < R >> constexpr borrowed_iterator_t < R > destroy ( R && r ) noexcept ; // freestanding template < nothrow - input - iterator I > requires destructible < iter_value_t < I >> constexpr I destroy_n ( I first , iter_difference_t < I > n ) noexcept ; // freestanding
template < execution - policy ExecutionPolicy , nothrow - random - access - iterator I , nothrow - sized - sentinel - for < I > S > requires destructible < iter_value_t < I >> I destroy ( ExecutionPolicy && exec , I first , S last ) noexcept ; // see [algorithms.parallel.overloads] template < execution - policy ExecutionPolicy , nothrow - random - access - range R > requires destructible < range_value_t < R >> && sized_range < R > borrowed_iterator_t < R > destroy ( ExecutionPolicy && exec , R && r ) noexcept ; // see [algorithms.parallel.overloads] template < execution - policy ExecutionPolicy , nothrow - random - access - iterator I > requires destructible < iter_value_t < I >> I destroy_n ( ExecutionPolicy && exec , I first , iter_difference_t < I > n ) noexcept ; // see [algorithms.parallel.overloads]
8.50. Add exposition only concepts to [special.mem.concepts]
template < class S , class I > concept nothrow - sentinel - for = sentinel_for < S , I > ; // exposition only
Types
and
model
only if no exceptions are thrown from copy construction,
move construction, copy assignment, move assignment, or comparisons between valid values of type
and
.
[Note X: This concept allows some
([iterator.concept.sentinel]) operations to throw exceptions. — end note]
template < class S , class I > concept nothrow - sized - sentinel - for = // exposition only nothrow - sentinel - for < S , I > && sized_sentinel_for < S , I > ;
Types
and
model
only if no exceptions are thrown from the
operator
for valid values of type
and
.
[Note X: This concept allows some
([iterator.concept.sizedsentinel]) operations to throw exceptions. — end note]
template < class I > concept nothrow - forward - iterator = // exposition only nothrow - input - iterator < I > && forward_iterator < I > && nothrow - sentinel - for < I , I > ;
[Note X: This concept allows some
([iterator.concept.forward]) operations to throw exceptions. — end note]
template < class R > concept nothrow - forward - range = // exposition only nothrow - input - range < R > && nothrow - forward - iterator < iterator_t < R >> ;
template < class I > concept nothrow - bidirectional - iterator = // exposition only nothrow - forward - iterator < I > && bidirectional_iterator < I > ;
A type
models
only if no exceptions are thrown from decrementing valid iterators.
[Note X: This concept allows some
([iterator.concept.bidir]) operations to throw exceptions. — end note]
template < class R > concept nothrow - bidirectional - range = // exposition only nothrow - forward - range < R > && nothrow - bidirectional - iterator < iterator_t < R >> ;
template < class I > concept nothrow - random - access - iterator = // exposition only nothrow - bidirectional - iterator < I > && random_access_iterator < I > && nothrow - sized - sentinel - for < I , I > ;
A type
models
only if no exceptions are thrown from advancement
with
,
,
, and
, comparisons, or applying the
subscript operator to valid iterators.
[Note X: This concept allows some
([iterator.concept.random.access]) operations to throw exceptions. — end note]
template < class R > concept nothrow - random - access - range = // exposition only nothrow - bidirectional - range < R > && nothrow - random - access - iterator < iterator_t < R >> ;
9. Revision history
9.1. R3 => R4
-
Revert back to range-as-the-output design aspect, change the formal wording accordingly
-
Revert back to requiring all ranges to be sized (
instead of&&
)|| -
Clarify which execution policies are supported
-
Clarify that new APIs extend algorithm function objects in
std :: ranges -
Add the feature test macro
-
Add implementation experience and thoughts on implementability
-
Fix known bugs in the signatures wording
-
Address other feedback from SG1 and SG9 and fix known bugs (see § 7.1 Issues to address):
-
Decide on constraining the execution policy template parameter
-
List all the algorithms that are being given execution policy overloads
-
List range algorithms that are being excluded
-
9.2. R2 => R3
-
Use
as an outputiterator -
Add wording
9.3. R1 => R2
-
Summarize proposed differences from the serial range algorithms and from the non-range parallel algorithms
-
Allow all but one input sequences to be unbounded
-
List existing algorithms that take ranges for output
-
Update arguments and mitigation for using ranges for output
-
Add more arguments in support of random access ranges
-
Fix the signatures of
to match the proposed designfor_each
9.4. R0 => R1
-
Address the feedback from SG1 and SG9 review
-
Add more information about iterator constraints
-
Propose
as an output for the algorithmsrange -
Require ranges to be bounded
10. Polls
10.1. SG9, Wroclaw, 2024
Poll 1: Change
and
to require
for both inputs ("
instead of
").
SF | F | N | A | SA |
---|---|---|---|---|
4 | 3 | 1 | 0 | 0 |
Poll 2: Change
to require
for both inputs ("
instead of
"),
with the plan to relax these constraints once we have a way to statically detect infinite ranges.
SF | F | N | A | SA |
---|---|---|---|---|
3 | 3 | 0 | 1 | 1 |
Poll 3: We want to remove the "legacy" overload that includes only an iterator as output for convenience, because we know it’s unsafe.
SF | F | N | A | SA |
---|---|---|---|---|
4 | 4 | 0 | 0 | 0 |
Poll 4 Forward P3179R3 with the changes in P3490R0 (as updated above) to LEWG for inclusion in C++26 with these changes polled above.
SF | F | N | A | SA |
---|---|---|---|---|
4 | 5 | 0 | 0 | 0 |
10.2. SG1, Wroclaw, 2024
Forward P3179R3 to LEWG with the following notes:
-
The intention is that algorithms call
/begin
only once, in serial code (we do not think any new words are needed)end -
The intention is that
,mismatch
andtransform
assume the unsized range is at least as large as the sized one (UB / precondition) or require && sizedequal
SF | F | N | A | SA |
---|---|---|---|---|
4 | 8 | 0 | 0 | 0 |
10.3. Joint SG1 + SG9, St. Louis, 2024
Poll: Continue work on P3179R2 for IS’26 with these notes:
-
RandomAccess for inputs and outputs
-
Iterators for outputs
-
We believe the overloads are worth it
SF | F | N | A | SA |
---|---|---|---|---|
7 | 4 | 2 | 1 | 0 |
10.4. SG9, Tokyo, 2024
Poll 1:
shouldn’t return the callable
SF | F | N | A | SA |
---|---|---|---|---|
2 | 4 | 2 | 0 | 0 |
Poll 2: Parallel
algos should return the same type as serial
algos
Unanimous consent. |
Poll 3: Parallel ranges algos should require
, not
SF | F | N | A | SA |
---|---|---|---|---|
3 | 2 | 3 | 1 | 1 |
Poll 4: Range-based parallel algos should require const operator()
SF | F | N | A | SA |
---|---|---|---|---|
0 | 7 | 2 | 0 | 0 |