Defined in header
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
; for the definition of /*sized-random-access-range*/, see
.
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
, 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
(informally known as niebloids), that is:
Explicit template argument lists cannot be specified when calling any of them.
None of them are visible to
.
When any of them are found by
as the name to the left of the function-call operator,
is inhibited.
Parameters
first, last - the iterator-sentinel pair defining the target
r - the target range count - the shift offset policy - the
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,
is thrown.
If an uncaught exception is thrown while accessing objects via an algorithm argument, the behavior is determined by the execution policy (for
,
is invoked).
Notes
ranges::shift_left / ranges::shift_right has better efficiency on common implementations if I or ranges::iterator_t<R> models
or (better)
.
Implementations (e.g.
) may enable vectorization when the iterator type models
and swapping its value type calls neither non-trivial special member function nor
-found swap.
macroValueStdFeature
(C++23)
and
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