std::ranges::shift_left, std::ranges::shift_right - cppreference.com

Defined in header

<algorithm>

Call signature

template<std::permutableI,std::sentinel_for<I>S>constexprranges::subrange<I>shift_left(Ifirst,Slast,std::iter_difference_t<I>count); (1) (since C++23)template<ranges::forward_rangeR>requiresstd::permutable<ranges::iterator_t<R>>constexprranges::borrowed_subrange_t<R>shift_left(R&&r,ranges::range_difference_t<R>count); (2) (since C++23)template<std::permutableI,std::sentinel_for<I>S>constexprranges::subrange<I>shift_right(Ifirst,Slast,std::iter_difference_t<I>count); (3) (since C++23)template<ranges::forward_rangeR>requiresstd::permutable<ranges::iterator_t<R>>constexprranges::borrowed_subrange_t<R>shift_right(R&&r,ranges::range_difference_t<R>count); (4) (since C++23)template</*execution-policy*/Ep,std::random_access_iteratorI,std::sized_sentinel_for<I>S>requiresstd::permutable<I>ranges::subrange<I>shift_left(Ep&&policy,Ifirst,Slast,std::iter_difference_t<I>count); (5) (since C++26)template</*execution-policy*/Ep,/*sized-random-access-range*/R>requiresstd::permutable<ranges::iterator_t<R>>ranges::borrowed_subrange_t<R>shift_left(Ep&&policy,R&&r,ranges::range_difference_t<R>count); (6) (since C++26)template</*execution-policy*/Ep,std::random_access_iteratorI,std::sized_sentinel_for<I>S>requiresstd::permutable<I>ranges::subrange<I>shift_right(Ep&&policy,Ifirst,Slast,std::iter_difference_t<I>count); (7) (since C++26)template</*execution-policy*/Ep,/*sized-random-access-range*/R>requiresstd::permutable<ranges::iterator_t<R>>ranges::borrowed_subrange_t<R>shift_right(Ep&&policy,R&&r,ranges::range_difference_t<R>count); (8) (since C++26)For the definition of /*execution-policy*/, see

this page

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

this page

.

Shifts the elements in the target range [first, last) or r by count positions. If count is not less than ranges::distance(first,last) or ranges::distance(r), does nothing.

1,2)shift_left shifts the elements towards the beginning of the target range.

For every integer i starting from 0 to ranges::distance(first,last)-count-1, moves the element originally at position ranges::next(first,count+i) to position ranges::next(first,i).

3,4)shift_right shifts the elements towards the end of the target range.

For every integer i starting from ranges::distance(first,last)-count-1 to 0, moves the element originally at position ranges::next(first,i) to position ranges::next(first,count+i).

If I or ranges::iterator_t<R> does not model

bidirectional_iterator

, the shifting process is performed by swapping elements instead, the swap order is unspecified.

5-8) Same as (1-4), but the move order is determined by policy.

If count>=0 is not true, 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

first, last - the iterator-sentinel pair defining the target

range

r - the target range count - the shift offset policy - the

execution policy

to use Return value

A subrange containing all elements that are not shifted away from the target range, or an empty range if count is not less than ranges::distance(first,last) or ranges::distance(r).

Complexity

Given N as ranges::distance(first,last) or ranges::distance(r):

1,2,5,6) At most max(N-count,0) assignments.

3,4,7,8) At most max(N-count,0) assignment or swaps.

Exceptions

5-8) 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

ranges::shift_left / ranges::shift_right has better efficiency on common implementations if I or ranges::iterator_t<R> models

bidirectional_iterator

or (better)

random_access_iterator

.

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.

Feature-test

macroValueStdFeature

__cpp_lib_shift

202202L

(C++23)

std::ranges::shift_left

and

std::ranges::shift_right

Example

Run this code

importstd;structS{intvalue{0};boolspecified_state{true};S(intv=0):value{v}{}S(constS&rhs)=default;S(S&&rhs){*this=std::move(rhs);}S&operator=(constS&rhs)=default;S&operator=(S&&rhs){if(this!=&rhs){value=rhs.value;specified_state=rhs.specified_state;rhs.specified_state=false;}return*this;}};template<typenameT>std::ostream&operator<<(std::ostream&os,conststd::vector<T>&v){for(constauto&s:v){ifconstexpr(std::is_same_v<T,S>)s.specified_state?os<<s.value<<' ':os<<". ";elseifconstexpr(std::is_same_v<T,std::string>)os<<(s.empty()?".":s)<<' ';elseos<<s<<' ';}returnos;}template<intwidth=16>voidprintln(auto&&...s){std::cout<<std::left;std::stringstreamxm;((xm.str(""),xm<<s,std::cout<<std::setw(width)<<xm.str()),...);std::cout<<'\n';}intmain(){std::vector<S>a{1,2,3,4,5,6,7};std::vector<int>b{1,2,3,4,5,6,7};std::vector<std::string>c{"α","β","γ","δ","ε","ζ","η"};println("vector<S>","vector<int>","vector<string>");println(a,b,c);std::ranges::shift_left(a,3);std::ranges::shift_left(b,3);std::ranges::shift_left(c,3);println(a,b,c);std::ranges::shift_right(a,2);std::ranges::shift_right(b,2);std::ranges::shift_right(c,2);println(a,b,c);std::ranges::shift_left(a,8);// has no effect: n >= last - firststd::ranges::shift_left(b,8);// dittostd::ranges::shift_left(c,8);// dittoprintln(a,b,c);// std::ranges::shift_left(a, -3); // UB}Possible output:

vector<S> vector<int> vector<string> 1 2 3 4 5 6 7 1 2 3 4 5 6 7 α β γ δ ε ζ η 4 5 6 7 . . . 4 5 6 7 5 6 7 δ ε ζ η . . . . . 4 5 6 7 . 4 5 4 5 6 7 5 . . δ ε ζ η . . . 4 5 6 7 . 4 5 4 5 6 7 5 . . δ ε ζ η . See also