Constrained algorithms and algorithms on ranges(C++20) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Constrained algorithms, e.g.ranges::copy,ranges::sort, ... | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Execution policies(C++17) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Numeric operations | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Operations on uninitialized memory | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
std::ranges
Non-modifying sequence operations | |||||||||||||||||||||||||||||||||
Modifying sequence operations | |||||||||||||||||||||||||||||||||
Partitioning operations | |||||||||||||||||||||||||||||||||
Sorting operations | |||||||||||||||||||||||||||||||||
Binary search operations (on sorted ranges) | |||||||||||||||||||||||||||||||||
Set operations (on sorted ranges) | |||||||||||||||||||||||||||||||||
Heap operations | |||||||||||||||||||||||||||||||||
Minimum/maximum operations | |||||||||||||||||||||||||||||||||
Permutation operations | |||||||||||||||||||||||||||||||||
Fold operations | |||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||
Operations on uninitialized storage | |||||||||||||||||||||||||||||||||
Return types | |||||||||||||||||||||||||||||||||
Defined in header <algorithm> | ||
Call signature | ||
template<std::input_iterator I1,std::sentinel_for<I1> S1, std::input_iterator I2,std::sentinel_for<I2> S2, | (1) | (since C++20) |
template<ranges::input_range R1,ranges::input_range R2, std::weakly_incrementable O,class Comp=ranges::less, | (2) | (since C++20) |
Helper types | ||
template<class I1,class I2,class O> using merge_result=ranges::in_in_out_result<I1, I2, O>; | (3) | (since C++20) |
Merges twosorted ranges[
[first1,
last1)
and[
first2,
last2)
into onesorted range beginning atresult.
A sequence is said to besorted with respect to the comparatorcomp if for any iteratorit
pointing to the sequence and any non-negative integern
such thatit + n
is a valid iterator pointing to an element of the sequence,std::invoke(comp,std::invoke(proj2,*(it+ n)),std::invoke(proj1,*it))) evaluates tofalse.
The behavior is undefined if the destination range overlaps either of the input ranges (the input ranges may overlap each other).
This merge function isstable, which means that for equivalent elements in the original two ranges, the elements from the first range (preserving their original order) precede the elements from the second range (preserving their original order).
The function-like entities described on this page arealgorithm function objects (informally known asniebloids), that is:
Contents |
first1, last1 | - | the iterator-sentinel pair defining the first input sortedrange of elements to merge |
first2, last2 | - | the iterator-sentinel pair defining the second input sortedrange of elements to merge |
result | - | the beginning of the output range |
comp | - | comparison to apply to the projected elements |
proj1 | - | projection to apply to the elements in the first range |
proj2 | - | projection to apply to the elements in the second range |
{last1, last2, result_last}, whereresult_last is the end of the constructed range.
At mostN −1 comparisons and applications of each projection, whereN=ranges::distance(first1, last1)+ranges::distance(first2, last12).
This algorithm performs a similar task asranges::set_union does. Both consume two sorted input ranges and produce a sorted output with elements from both inputs. The difference between these two algorithms is with handling values from both input ranges which compare equivalent (see notes onLessThanComparable). If any equivalent values appearedn times in the first range andm times in the second,ranges::merge would output alln+ m occurrences whereasranges::set_union would outputmax(n, m) ones only. Soranges::merge outputs exactlyN values andranges::set_union may produce fewer.
struct merge_fn{template<std::input_iterator I1,std::sentinel_for<I1> S1,std::input_iterator I2,std::sentinel_for<I2> S2,std::weakly_incrementable O,class Comp=ranges::less,class Proj1=std::identity,class Proj2=std::identity> requiresstd::mergeable<I1, I2, O, Comp, Proj1, Proj2>constexpr ranges::merge_result<I1, I2, O> operator()(I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp={}, Proj1 proj1={}, Proj2 proj2={})const{for(;!(first1== last1 or first2== last2);++result){if(std::invoke(comp,std::invoke(proj2,*first2),std::invoke(proj1,*first1)))*result=*first2,++first2;else*result=*first1,++first1;}auto ret1{ranges::copy(std::move(first1), std::move(last1), std::move(result))};auto ret2{ranges::copy(std::move(first2), std::move(last2), std::move(ret1.out))};return{std::move(ret1.in), std::move(ret2.in), std::move(ret2.out)};} template<ranges::input_range R1,ranges::input_range R2,std::weakly_incrementable O,class Comp=ranges::less,class Proj1=std::identity,class Proj2=std::identity> requiresstd::mergeable<ranges::iterator_t<R1>,ranges::iterator_t<R2>, O, Comp, Proj1, Proj2>constexpr ranges::merge_result<ranges::borrowed_iterator_t<R1>,ranges::borrowed_iterator_t<R2>, O> operator()(R1&& r1, R2&& r2, O result, Comp comp={}, Proj1 proj1={}, Proj2 proj2={})const{return(*this)(ranges::begin(r1),ranges::end(r1),ranges::begin(r2),ranges::end(r2), std::move(result), std::move(comp), std::move(proj1), std::move(proj2));}}; inlineconstexpr merge_fn merge{}; |
#include <algorithm>#include <iostream>#include <iterator>#include <vector> void print(constauto& in1,constauto& in2,auto first,auto last){std::cout<<"{ ";for(constauto& e: in1)std::cout<< e<<' ';std::cout<<"} +\n{ ";for(constauto& e: in2)std::cout<< e<<' ';std::cout<<"} =\n{ ";while(!(first== last))std::cout<<*first++<<' ';std::cout<<"}\n\n";} int main(){std::vector<int> in1, in2, out; in1={1,2,3,4,5}; in2={3,4,5,6,7}; out.resize(in1.size()+ in2.size());constauto ret= std::ranges::merge(in1, in2, out.begin()); print(in1, in2, out.begin(), ret.out); in1={1,2,3,4,5,5,5}; in2={3,4,5,6,7}; out.clear(); out.reserve(in1.size()+ in2.size()); std::ranges::merge(in1, in2,std::back_inserter(out)); print(in1, in2, out.cbegin(), out.cend());}
Output:
{ 1 2 3 4 5 } +{ 3 4 5 6 7 } ={ 1 2 3 3 4 4 5 5 6 7 } { 1 2 3 4 5 5 5 } +{ 3 4 5 6 7 } ={ 1 2 3 3 4 4 5 5 5 5 6 7 }
(C++20) | merges two ordered ranges in-place (algorithm function object)[edit] |
(C++20) | checks whether a range is sorted into ascending order (algorithm function object)[edit] |
(C++20) | computes the union of two sets (algorithm function object)[edit] |
(C++20) | sorts a range into ascending order (algorithm function object)[edit] |
(C++20) | sorts a range of elements while preserving order between equal elements (algorithm function object)[edit] |
merges two sorted ranges (function template)[edit] |