Skip to content

Commit 5329e82

Browse files
committed
P2440R1 ranges::iota, ranges::shift_left, and ranges::shift_right
1 parent 4b1a735 commit 5329e82

File tree

2 files changed

+118
-14
lines changed

2 files changed

+118
-14
lines changed

source/algorithms.tex

Lines changed: 116 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,9 @@
641641

642642
template<class I>
643643
struct in_found_result;
644+
645+
template<class O, class T>
646+
struct out_value_result;
644647
}
645648

646649
// \ref{alg.nonmodifying}, non-modifying sequence operations
@@ -1815,6 +1818,13 @@
18151818
shift_left(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads}
18161819
ForwardIterator first, ForwardIterator last,
18171820
typename iterator_traits<ForwardIterator>::difference_type n);
1821+
namespace ranges {
1822+
template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@<I> S>
1823+
constexpr subrange<I> shift_left(I first, S last, iter_difference_t<I> n);
1824+
template<@\libconcept{forward_range}@ R>
1825+
requires @\libconcept{permutable}@<iterator_t<R>>
1826+
constexpr borrowed_subrange_t<R> shift_left(R&& r, range_difference_t<R> n);
1827+
}
18181828
template<class ForwardIterator>
18191829
constexpr ForwardIterator
18201830
shift_right(ForwardIterator first, ForwardIterator last,
@@ -1824,6 +1834,13 @@
18241834
shift_right(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads}
18251835
ForwardIterator first, ForwardIterator last,
18261836
typename iterator_traits<ForwardIterator>::difference_type n);
1837+
namespace ranges {
1838+
template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@<I> S>
1839+
constexpr subrange<I> shift_right(I first, S last, iter_difference_t<I> n);
1840+
template<@\libconcept{forward_range}@ R>
1841+
requires @\libconcept{permutable}@<iterator_t<R>>
1842+
constexpr borrowed_subrange_t<R> shift_right(R&& r, range_difference_t<R> n);
1843+
}
18271844

18281845
// \ref{alg.sorting}, sorting and related operations
18291846
// \ref{alg.sort}, sorting
@@ -3037,6 +3054,24 @@
30373054
return {std::move(in), found};
30383055
}
30393056
};
3057+
3058+
template<class O, class T>
3059+
struct out_value_result {
3060+
[[no_unique_address]] O out;
3061+
[[no_unique_address]] T value;
3062+
3063+
template<class O2, class T2>
3064+
requires @\libconcept{convertible_to}@<const O&, O2> && @\libconcept{convertible_to}@<const T&, T2>
3065+
constexpr operator out_value_result<O2, T2>() const & {
3066+
return {out, value};
3067+
}
3068+
3069+
template<class O2, class T2>
3070+
requires @\libconcept{convertible_to}@<O, O2> && @\libconcept{convertible_to}@<T, T2>
3071+
constexpr operator out_value_result<O2, T2>() && {
3072+
return {std::move(out), std::move(value)};
3073+
}
3074+
};
30403075
}
30413076
\end{codeblock}
30423077

@@ -6003,14 +6038,20 @@
60036038
ForwardIterator
60046039
shift_left(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last,
60056040
typename iterator_traits<ForwardIterator>::difference_type n);
6041+
6042+
template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@<I> S>
6043+
constexpr subrange<I> ranges::shift_left(I first, S last, iter_difference_t<I> n);
6044+
template<@\libconcept{forward_range}@ R>
6045+
requires @\libconcept{permutable}@<iterator_t<R>>
6046+
constexpr borrowed_subrange_t<R> ranges::shift_left(R&& r, range_difference_t<R> n)
60066047
\end{itemdecl}
60076048

60086049
\begin{itemdescr}
60096050
\pnum
60106051
\expects
60116052
\tcode{n >= 0} is \tcode{true}.
6012-
The type of \tcode{*first} meets
6013-
the \oldconcept{MoveAssignable} requirements.
6053+
For the overloads in namespace \tcode{std},
6054+
the type of \tcode{*first} meets the \oldconcept{MoveAssignable} requirements.
60146055

60156056
\pnum
60166057
\effects
@@ -6019,14 +6060,22 @@
60196060
from position \tcode{first + n + i}
60206061
into position \tcode{first + i}
60216062
for each non-negative integer \tcode{i < (last - first) - n}.
6022-
In the first overload case, does so in order starting
6063+
For the overloads without an \tcode{ExecutionPolicy} template parameter,
6064+
does so in order starting
60236065
from \tcode{i = 0} and proceeding to \tcode{i = (last - first) - n - 1}.
60246066

60256067
\pnum
60266068
\returns
6027-
\tcode{first + (last - first - n)}
6069+
Let \exposid{NEW_LAST} be \tcode{first + (last - first - n)}
60286070
if \tcode{n < last - first},
60296071
otherwise \tcode{first}.
6072+
\begin{itemize}
6073+
\item
6074+
\exposid{NEW_LAST} for the overloads in namespace \tcode{std}.
6075+
\item
6076+
\tcode{\{first, \exposid{NEW_LAST}\}}
6077+
for the overloads in namespace \tcode{ranges}.
6078+
\end{itemize}
60306079

60316080
\pnum
60326081
\complexity
@@ -6043,15 +6092,21 @@
60436092
ForwardIterator
60446093
shift_right(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last,
60456094
typename iterator_traits<ForwardIterator>::difference_type n);
6095+
6096+
template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@<I> S>
6097+
constexpr subrange<I> ranges::shift_right(I first, S last, iter_difference_t<I> n);
6098+
template<@\libconcept{forward_range}@ R>
6099+
requires permutable<iterator_t<R>>
6100+
constexpr borrowed_subrange_t<R> ranges::shift_right(R&& r, range_difference_t<R> n);
60466101
\end{itemdecl}
60476102

60486103
\begin{itemdescr}
60496104
\pnum
60506105
\expects
60516106
\tcode{n >= 0} is \tcode{true}.
6052-
The type of \tcode{*first} meets
6053-
the \oldconcept{MoveAssignable} requirements.
6054-
\tcode{ForwardIterator} meets
6107+
For the overloads in namespace \tcode{std},
6108+
the type of \tcode{*first} meets the \oldconcept{MoveAssignable} requirements
6109+
and \tcode{ForwardIterator} meets
60556110
the \oldconcept{BidirectionalIterator} requirements\iref{bidirectional.iterators} or
60566111
the \oldconcept{ValueSwap\-pable} requirements.
60576112

@@ -6061,16 +6116,29 @@
60616116
Otherwise, moves the element
60626117
from position \tcode{first + i} into position \tcode{first + n + i}
60636118
for each non-negative integer \tcode{i < (last - first) - n}.
6064-
In the first overload case, if \tcode{ForwardIterator} meets
6065-
the \oldconcept{BidirectionalIterator} requirements,
6066-
does so in order starting
6067-
from \tcode{i = (last - first) - n - 1} and proceeding to \tcode{i = 0}.
6119+
Does so in order starting
6120+
from \tcode{i = (last - first) - n - 1} and proceeding to \tcode{i = 0} if:
6121+
\begin{itemize}
6122+
\item
6123+
for the overload in namespace \tcode{std}
6124+
without an \tcode{ExecutionPolicy} template parameter,
6125+
\tcode{Forward\-Iterator} meets the \oldconcept{BidirectionalIterator} requirements,
6126+
\item
6127+
for the overloads in namespace \tcode{ranges},
6128+
\tcode{I} models \libconcept{bidirectional_iterator}.
6129+
\end{itemize}
60686130

60696131
\pnum
60706132
\returns
6071-
\tcode{first + n}
6072-
if \tcode{n < last - first},
6133+
Let \exposid{NEW_FIRST} be \tcode{first + n} if \tcode{n < last - first},
60736134
otherwise \tcode{last}.
6135+
\begin{itemize}
6136+
\item
6137+
\exposid{NEW_FIRST} for the overloads in namespace \tcode{std}.
6138+
\item
6139+
\tcode{\{\exposid{NEW_FIRST}, last\}}
6140+
for the overloads in namespace \tcode{ranges}.
6141+
\end{itemize}
60746142

60756143
\pnum
60766144
\complexity
@@ -9104,6 +9172,18 @@
91049172
template<class ForwardIterator, class T>
91059173
constexpr void iota(ForwardIterator first, ForwardIterator last, T value);
91069174

9175+
namespace ranges {
9176+
template<class O, class T>
9177+
using iota_result = out_value_result<O, T>;
9178+
9179+
template<@\libconcept{input_or_output_iterator}@ O, @\libconcept{sentinel_fo}@r<O> S, @\libconcept{weakly_incrementable}@ T>
9180+
requires @\libconcept{indirectly_writable}@<O, const T&>
9181+
constexpr iota_result<O, T> iota(O first, S last, T value);
9182+
9183+
template<@\libconcept{weakly_incrementable}@ T, @\libconcept{output_range}@<const T&> R>
9184+
constexpr iota_result<borrowed_iterator_t<R>, T> iota(R&& r, T value);
9185+
}
9186+
91079187
// \ref{numeric.ops.gcd}, greatest common divisor
91089188
template<class M, class N>
91099189
constexpr common_type_t<M, N> gcd(M m, N n);
@@ -10105,6 +10185,29 @@
1010510185
Exactly \tcode{last - first} increments and assignments.
1010610186
\end{itemdescr}
1010710187

10188+
\indexlibraryglobal{iota}%
10189+
\begin{itemdecl}
10190+
template<@\libconcept{input_or_output_iterator}@ O, @\libconcept{sentinel_for}@<O> S, @\libconcept{weakly_incrementable}@ T>
10191+
requires @\libconcept{indirectly_writable}@<O, const T&>
10192+
constexpr ranges::iota_result<O, T> ranges::iota(O first, S last, T value);
10193+
template<@\libconcept{weakly_incrementable}@ T, @\libconcept{output_range}@<const T&> R>
10194+
constexpr ranges::iota_result<borrowed_iterator_t<R>, T> ranges::iota(R&& r, T value);
10195+
\end{itemdecl}
10196+
10197+
\begin{itemdescr}
10198+
\pnum
10199+
\effects
10200+
Equivalent to:
10201+
\begin{codeblock}
10202+
while (first != last) {
10203+
*first = as_const(value);
10204+
++first;
10205+
++value;
10206+
}
10207+
return {std::move(first), std::move(value)};
10208+
\end{codeblock}
10209+
\end{itemdescr}
10210+
1010810211
\rSec2[numeric.ops.gcd]{Greatest common divisor}
1010910212

1011010213
\indexlibraryglobal{gcd}%

source/support.tex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,7 @@
666666
#define @\defnlibxname{cpp_lib_quoted_string_io}@ 201304L // also in \libheader{iomanip}
667667
#define @\defnlibxname{cpp_lib_ranges}@ 202110L
668668
// also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges}
669+
#define @\defnlibxname{cpp_lib_ranges_iota}@ 202202L // also in \libheader{numeric}
669670
#define @\defnlibxname{cpp_lib_ranges_starts_ends_with}@ 202106L // also in \libheader{algorithm}
670671
#define @\defnlibxname{cpp_lib_ranges_zip}@ 202110L // also in \libheader{ranges}, \libheader{tuple}, \libheader{utility}
671672
#define @\defnlibxname{cpp_lib_raw_memory_algorithms}@ 201606L // also in \libheader{memory}
@@ -679,7 +680,7 @@
679680
#define @\defnlibxname{cpp_lib_shared_ptr_arrays}@ 201707L // also in \libheader{memory}
680681
#define @\defnlibxname{cpp_lib_shared_ptr_weak_type}@ 201606L // also in \libheader{memory}
681682
#define @\defnlibxname{cpp_lib_shared_timed_mutex}@ 201402L // also in \libheader{shared_mutex}
682-
#define @\defnlibxname{cpp_lib_shift}@ 201806L // also in \libheader{algorithm}
683+
#define @\defnlibxname{cpp_lib_shift}@ 202202L // also in \libheader{algorithm}
683684
#define @\defnlibxname{cpp_lib_smart_ptr_for_overwrite}@ 202002L // also in \libheader{memory}
684685
#define @\defnlibxname{cpp_lib_source_location}@ 201907L // also in \libheader{source_location}
685686
#define @\defnlibxname{cpp_lib_span}@ 202002L // also in \libheader{span}

0 commit comments

Comments
 (0)