std::ranges::swap_ranges, std::ranges::swap_ranges_result - cppreference.com

From cppreference.com

Defined in header

<algorithm>

Call signature

template<std::input_iteratorI1,std::sentinel_for<I1>S1,std::input_iteratorI2,std::sentinel_for<I2>S2>requiresstd::indirectly_swappable<I1,I2>constexprranges::swap_ranges_result<I1,I2>swap_ranges(I1first1,S1last1,I2first2,S2last2); (1) (since C++20)template<ranges::input_rangeR1,ranges::input_rangeR2>requiresstd::indirectly_swappable<ranges::iterator_t<R1>,ranges::iterator_t<R2>>constexprranges::swap_ranges_result<ranges::borrowed_iterator_t<R1>,ranges::borrowed_iterator_t<R2>>swap_ranges(R1&&r1,R2&&r2); (2) (since C++20)template</*execution-policy*/Ep,std::random_access_iteratorI1,std::sized_sentinel_for<I1>S1,std::random_access_iteratorI2,std::sized_sentinel_for<I2>S2>requiresstd::indirectly_swappable<I1,I2>ranges::swap_ranges_result<I1,I2>swap_ranges(Ep&&policy,I1first1,S1last1,I2first2,S2last2); (3) (since C++26)template</*execution-policy*/Ep,/*sized-random-access-range*/R1,/*sized-random-access-range*/R2>requiresstd::indirectly_swappable<ranges::iterator_t<R1>,ranges::iterator_t<R2>>constexprranges::swap_ranges_result<ranges::borrowed_iterator_t<R1>,ranges::borrowed_iterator_t<R2>>swap_ranges(Ep&&policy,R1&&r1,R2&&r2); (4) (since C++26)Helper types

template<classI1,classI2>usingswap_ranges_result=ranges::in_in_result<I1,I2>; (5) (since C++20)For the definition of /*execution-policy*/, see

this page

; for the definition of /*sized-random-access-range*/, see

this page

.

Exchanges elements between two ranges.

1) The two ranges are [first1, last1) and [first2, last2).

2) The two ranges are r1 and r2.

3,4) Same as (1,2), but executed according to policy.

If the two ranges overlap, the behavior is undefined.

The function-like entities described on this page are

algorithm function objects

(informally known as niebloids), that is:

Explicit template argument lists cannot be specified when calling any of them.

None of them are visible to

argument-dependent lookup

.

When any of them are found by

normal unqualified lookup

as the name to the left of the function-call operator,

argument-dependent lookup

is inhibited.

Parameters

first1, last1 - the iterator-sentinel pair defining the first

range

first2, last2 - the iterator-sentinel pair defining the second

range

r1 - the first range r2 - the second range Return value

A ranges::swap_ranges_result object where:

The data member

in1

holds an iterator past the last swapped element in the first range, or an iterator to the beginning of the first range if no element is swapped.

The data member

in2

holds an iterator past the last swapped element in the second range, or an iterator to the beginning of the second range if no element is swapped.

Complexity

Given

N1 as ranges::distance(first1,last1) or ranges::distance(r1), and

N2 as ranges::distance(first2,last2) or ranges::distance(r2):

1-4) Exactly min(N1,N2) swaps.

Exceptions

3,4) During the execution process:

If the temporary memory resources required for parallelization are not available,

std::bad_alloc

is thrown.

If an uncaught exception is thrown while accessing objects via an algorithm argument, the behavior is determined by the execution policy (for

standard policies

,

std::terminate

is invoked).

Notes

Implementations (e.g.

MSVC STL

) may enable vectorization when the iterator type models

contiguous_iterator

and swapping its value type calls neither non-trivial special member function nor

ADL

-found swap.

Possible implementation

structswap_ranges_fn{template<std::input_iteratorI1,std::sentinel_for<I1>S1,std::input_iteratorI2,std::sentinel_for<I2>S2>requiresstd::indirectly_swappable<I1,I2>constexprranges::swap_ranges_result<I1,I2>operator()(I1first1,S1last1,I2first2,S2last2)const{for(;!(first1==last1orfirst2==last2);++first1,++first2)ranges::iter_swap(first1,first2);return{std::move(first1),std::move(first2)};}template<ranges::input_rangeR>constexprautoget_end(R&&r){returnranges::end(r);}template<ranges::forward_rangeR>constexprautoget_end(R&&r){returnranges::next(ranges::begin(r),ranges::end(r));}template<ranges::input_rangeR1,ranges::input_rangeR2>requiresstd::indirectly_swappable<ranges::iterator_t<R1>,ranges::iterator_t<R2>>constexprranges::swap_ranges_result<ranges::borrowed_iterator_t<R1>,ranges::borrowed_iterator_t<R2>>operator()(R1&&r1,R2&&r2)const{return(*this)(ranges::begin(r1),get_end(r1),ranges::begin(r2),get_end(r2));}};inlineconstexprswap_ranges_fnswap_ranges{};Example

Run this code

#include<algorithm>#include<list>#include<print>#include<vector>intmain(){std::vector<char>p{'A','B','C','D','E'};std::list<char>q{'1','2','3','4','5','6'};std::println("p: {::}\nq: {::}",p,q);std::println("swap p[0, 2) and q[1, 3):");std::ranges::swap_ranges(p.begin(),p.begin()+4,std::ranges::next(q.begin(),1),std::ranges::next(q.begin(),3));std::println("p: {::}\nq: {::}",p,q);std::println("swap p[0, 5) and q[0, 5):");std::ranges::swap_ranges(p,q);std::println("p: {::}\nq: {::}",p,q);}Output:

p: [A, B, C, D, E] q: [1, 2, 3, 4, 5, 6] swap p[0, 2) and q[1, 3): p: [2, 3, C, D, E] q: [1, A, B, 4, 5, 6] swap p[0, 5) and q[0, 5): p: [1, A, B, 4, 5] q: [2, 3, C, D, E, 6] See also

swaps two ranges of elements
(function template)

[edit]

swaps the elements pointed to by two iterators
(function template)

[edit]

swaps the values of two objects
(function template)

[edit]

(C++20)

swaps the values referenced by two dereferenceable objects
(customization point object)

[edit]

(C++20)

swaps the values of two objects
(customization point object)

[edit]