Skip to content

Commit 5194559

Browse files
authored
Merge 2022-02 LWG Motion 10
P2440R1 ranges::iota, ranges::shift_left, and ranges::shift_right
2 parents 1b6c68a + 812b81a commit 5194559

File tree

2 files changed

+122
-15
lines changed

2 files changed

+122
-15
lines changed

source/algorithms.tex

Lines changed: 120 additions & 14 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,15 @@
18151818
shift_left(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads}
18161819
ForwardIterator first, ForwardIterator last,
18171820
typename iterator_traits<ForwardIterator>::difference_type n);
1821+
1822+
namespace ranges {
1823+
template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@<I> S>
1824+
constexpr subrange<I> shift_left(I first, S last, iter_difference_t<I> n);
1825+
template<@\libconcept{forward_range}@ R>
1826+
requires @\libconcept{permutable}@<iterator_t<R>>
1827+
constexpr borrowed_subrange_t<R> shift_left(R&& r, range_difference_t<R> n);
1828+
}
1829+
18181830
template<class ForwardIterator>
18191831
constexpr ForwardIterator
18201832
shift_right(ForwardIterator first, ForwardIterator last,
@@ -1825,6 +1837,14 @@
18251837
ForwardIterator first, ForwardIterator last,
18261838
typename iterator_traits<ForwardIterator>::difference_type n);
18271839

1840+
namespace ranges {
1841+
template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@<I> S>
1842+
constexpr subrange<I> shift_right(I first, S last, iter_difference_t<I> n);
1843+
template<@\libconcept{forward_range}@ R>
1844+
requires @\libconcept{permutable}@<iterator_t<R>>
1845+
constexpr borrowed_subrange_t<R> shift_right(R&& r, range_difference_t<R> n);
1846+
}
1847+
18281848
// \ref{alg.sorting}, sorting and related operations
18291849
// \ref{alg.sort}, sorting
18301850
template<class RandomAccessIterator>
@@ -2741,7 +2761,7 @@
27412761
ForwardIterator first, ForwardIterator last,
27422762
Compare comp);
27432763

2744-
namespace ranges {
2764+
namespace ranges {
27452765
template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@<I> S, class Proj = identity,
27462766
@\libconcept{indirect_strict_weak_order}@<projected<I, Proj>> Comp = ranges::less>
27472767
constexpr I max_element(I first, S last, Comp comp = {}, Proj proj = {});
@@ -3037,6 +3057,24 @@
30373057
return {std::move(in), found};
30383058
}
30393059
};
3060+
3061+
template<class O, class T>
3062+
struct out_value_result {
3063+
[[no_unique_address]] O out;
3064+
[[no_unique_address]] T value;
3065+
3066+
template<class O2, class T2>
3067+
requires @\libconcept{convertible_to}@<const O&, O2> && @\libconcept{convertible_to}@<const T&, T2>
3068+
constexpr operator out_value_result<O2, T2>() const & {
3069+
return {out, value};
3070+
}
3071+
3072+
template<class O2, class T2>
3073+
requires @\libconcept{convertible_to}@<O, O2> && @\libconcept{convertible_to}@<T, T2>
3074+
constexpr operator out_value_result<O2, T2>() && {
3075+
return {std::move(out), std::move(value)};
3076+
}
3077+
};
30403078
}
30413079
\end{codeblock}
30423080

@@ -6003,14 +6041,20 @@
60036041
ForwardIterator
60046042
shift_left(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last,
60056043
typename iterator_traits<ForwardIterator>::difference_type n);
6044+
6045+
template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@<I> S>
6046+
constexpr subrange<I> ranges::shift_left(I first, S last, iter_difference_t<I> n);
6047+
template<@\libconcept{forward_range}@ R>
6048+
requires @\libconcept{permutable}@<iterator_t<R>>
6049+
constexpr borrowed_subrange_t<R> ranges::shift_left(R&& r, range_difference_t<R> n)
60066050
\end{itemdecl}
60076051

60086052
\begin{itemdescr}
60096053
\pnum
60106054
\expects
60116055
\tcode{n >= 0} is \tcode{true}.
6012-
The type of \tcode{*first} meets
6013-
the \oldconcept{MoveAssignable} requirements.
6056+
For the overloads in namespace \tcode{std},
6057+
the type of \tcode{*first} meets the \oldconcept{MoveAssignable} requirements.
60146058

60156059
\pnum
60166060
\effects
@@ -6019,14 +6063,22 @@
60196063
from position \tcode{first + n + i}
60206064
into position \tcode{first + i}
60216065
for each non-negative integer \tcode{i < (last - first) - n}.
6022-
In the first overload case, does so in order starting
6066+
For the overloads without an \tcode{ExecutionPolicy} template parameter,
6067+
does so in order starting
60236068
from \tcode{i = 0} and proceeding to \tcode{i = (last - first) - n - 1}.
60246069

60256070
\pnum
60266071
\returns
6027-
\tcode{first + (last - first - n)}
6072+
Let \exposid{NEW_LAST} be \tcode{first + (last - first - n)}
60286073
if \tcode{n < last - first},
60296074
otherwise \tcode{first}.
6075+
\begin{itemize}
6076+
\item
6077+
\exposid{NEW_LAST} for the overloads in namespace \tcode{std}.
6078+
\item
6079+
\tcode{\{first, \exposid{NEW_LAST}\}}
6080+
for the overloads in namespace \tcode{ranges}.
6081+
\end{itemize}
60306082

60316083
\pnum
60326084
\complexity
@@ -6043,15 +6095,21 @@
60436095
ForwardIterator
60446096
shift_right(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last,
60456097
typename iterator_traits<ForwardIterator>::difference_type n);
6098+
6099+
template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@<I> S>
6100+
constexpr subrange<I> ranges::shift_right(I first, S last, iter_difference_t<I> n);
6101+
template<@\libconcept{forward_range}@ R>
6102+
requires @\libconcept{permutable}@<iterator_t<R>>
6103+
constexpr borrowed_subrange_t<R> ranges::shift_right(R&& r, range_difference_t<R> n);
60466104
\end{itemdecl}
60476105

60486106
\begin{itemdescr}
60496107
\pnum
60506108
\expects
60516109
\tcode{n >= 0} is \tcode{true}.
6052-
The type of \tcode{*first} meets
6053-
the \oldconcept{MoveAssignable} requirements.
6054-
\tcode{ForwardIterator} meets
6110+
For the overloads in namespace \tcode{std},
6111+
the type of \tcode{*first} meets the \oldconcept{MoveAssignable} requirements,
6112+
and \tcode{ForwardIterator} meets
60556113
the \oldconcept{BidirectionalIterator} requirements\iref{bidirectional.iterators} or
60566114
the \oldconcept{ValueSwap\-pable} requirements.
60576115

@@ -6061,16 +6119,29 @@
60616119
Otherwise, moves the element
60626120
from position \tcode{first + i} into position \tcode{first + n + i}
60636121
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}.
6122+
Does so in order starting
6123+
from \tcode{i = (last - first) - n - 1} and proceeding to \tcode{i = 0} if:
6124+
\begin{itemize}
6125+
\item
6126+
for the overload in namespace \tcode{std}
6127+
without an \tcode{ExecutionPolicy} template parameter,
6128+
\tcode{Forward\-Iterator} meets the \oldconcept{BidirectionalIterator} requirements,
6129+
\item
6130+
for the overloads in namespace \tcode{ranges},
6131+
\tcode{I} models \libconcept{bidirectional_iterator}.
6132+
\end{itemize}
60686133

60696134
\pnum
60706135
\returns
6071-
\tcode{first + n}
6072-
if \tcode{n < last - first},
6136+
Let \exposid{NEW_FIRST} be \tcode{first + n} if \tcode{n < last - first},
60736137
otherwise \tcode{last}.
6138+
\begin{itemize}
6139+
\item
6140+
\exposid{NEW_FIRST} for the overloads in namespace \tcode{std}.
6141+
\item
6142+
\tcode{\{\exposid{NEW_FIRST}, last\}}
6143+
for the overloads in namespace \tcode{ranges}.
6144+
\end{itemize}
60746145

60756146
\pnum
60766147
\complexity
@@ -9104,6 +9175,18 @@
91049175
template<class ForwardIterator, class T>
91059176
constexpr void iota(ForwardIterator first, ForwardIterator last, T value);
91069177

9178+
namespace ranges {
9179+
template<class O, class T>
9180+
using iota_result = out_value_result<O, T>;
9181+
9182+
template<@\libconcept{input_or_output_iterator}@ O, @\libconcept{sentinel_for}@<O> S, @\libconcept{weakly_incrementable}@ T>
9183+
requires @\libconcept{indirectly_writable}@<O, const T&>
9184+
constexpr iota_result<O, T> iota(O first, S last, T value);
9185+
9186+
template<@\libconcept{weakly_incrementable}@ T, @\libconcept{output_range}@<const T&> R>
9187+
constexpr iota_result<borrowed_iterator_t<R>, T> iota(R&& r, T value);
9188+
}
9189+
91079190
// \ref{numeric.ops.gcd}, greatest common divisor
91089191
template<class M, class N>
91099192
constexpr common_type_t<M, N> gcd(M m, N n);
@@ -10105,6 +10188,29 @@
1010510188
Exactly \tcode{last - first} increments and assignments.
1010610189
\end{itemdescr}
1010710190

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

1011010216
\indexlibraryglobal{gcd}%

source/support.tex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,7 @@
671671
#define @\defnlibxname{cpp_lib_quoted_string_io}@ 201304L // also in \libheader{iomanip}
672672
#define @\defnlibxname{cpp_lib_ranges}@ 202202L
673673
// also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges}
674+
#define @\defnlibxname{cpp_lib_ranges_iota}@ 202202L // also in \libheader{numeric}
674675
#define @\defnlibxname{cpp_lib_ranges_starts_ends_with}@ 202106L // also in \libheader{algorithm}
675676
#define @\defnlibxname{cpp_lib_ranges_to_container}@ 202202L // also in \libheader{ranges}
676677
#define @\defnlibxname{cpp_lib_ranges_zip}@ 202110L // also in \libheader{ranges}, \libheader{tuple}, \libheader{utility}
@@ -686,7 +687,7 @@
686687
#define @\defnlibxname{cpp_lib_shared_ptr_arrays}@ 201707L // also in \libheader{memory}
687688
#define @\defnlibxname{cpp_lib_shared_ptr_weak_type}@ 201606L // also in \libheader{memory}
688689
#define @\defnlibxname{cpp_lib_shared_timed_mutex}@ 201402L // also in \libheader{shared_mutex}
689-
#define @\defnlibxname{cpp_lib_shift}@ 201806L // also in \libheader{algorithm}
690+
#define @\defnlibxname{cpp_lib_shift}@ 202202L // also in \libheader{algorithm}
690691
#define @\defnlibxname{cpp_lib_smart_ptr_for_overwrite}@ 202002L // also in \libheader{memory}
691692
#define @\defnlibxname{cpp_lib_source_location}@ 201907L // also in \libheader{source_location}
692693
#define @\defnlibxname{cpp_lib_span}@ 202002L // also in \libheader{span}

0 commit comments

Comments
 (0)