Skip to content

P2440R1 ranges::iota, ranges::shift_left, and ranges::shift_right #5286

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 120 additions & 14 deletions source/algorithms.tex
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,9 @@

template<class I>
struct in_found_result;

template<class O, class T>
struct out_value_result;
}

// \ref{alg.nonmodifying}, non-modifying sequence operations
Expand Down Expand Up @@ -1815,6 +1818,15 @@
shift_left(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads}
ForwardIterator first, ForwardIterator last,
typename iterator_traits<ForwardIterator>::difference_type n);

namespace ranges {
template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@<I> S>
constexpr subrange<I> shift_left(I first, S last, iter_difference_t<I> n);
template<@\libconcept{forward_range}@ R>
requires @\libconcept{permutable}@<iterator_t<R>>
constexpr borrowed_subrange_t<R> shift_left(R&& r, range_difference_t<R> n);
}

template<class ForwardIterator>
constexpr ForwardIterator
shift_right(ForwardIterator first, ForwardIterator last,
Expand All @@ -1825,6 +1837,14 @@
ForwardIterator first, ForwardIterator last,
typename iterator_traits<ForwardIterator>::difference_type n);

namespace ranges {
template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@<I> S>
constexpr subrange<I> shift_right(I first, S last, iter_difference_t<I> n);
template<@\libconcept{forward_range}@ R>
requires @\libconcept{permutable}@<iterator_t<R>>
constexpr borrowed_subrange_t<R> shift_right(R&& r, range_difference_t<R> n);
}

// \ref{alg.sorting}, sorting and related operations
// \ref{alg.sort}, sorting
template<class RandomAccessIterator>
Expand Down Expand Up @@ -2741,7 +2761,7 @@
ForwardIterator first, ForwardIterator last,
Compare comp);

namespace ranges {
namespace ranges {
template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@<I> S, class Proj = identity,
@\libconcept{indirect_strict_weak_order}@<projected<I, Proj>> Comp = ranges::less>
constexpr I max_element(I first, S last, Comp comp = {}, Proj proj = {});
Expand Down Expand Up @@ -3037,6 +3057,24 @@
return {std::move(in), found};
}
};

template<class O, class T>
struct out_value_result {
[[no_unique_address]] O out;
[[no_unique_address]] T value;

template<class O2, class T2>
requires @\libconcept{convertible_to}@<const O&, O2> && @\libconcept{convertible_to}@<const T&, T2>
constexpr operator out_value_result<O2, T2>() const & {
return {out, value};
}

template<class O2, class T2>
requires @\libconcept{convertible_to}@<O, O2> && @\libconcept{convertible_to}@<T, T2>
constexpr operator out_value_result<O2, T2>() && {
return {std::move(out), std::move(value)};
}
};
}
\end{codeblock}

Expand Down Expand Up @@ -6003,14 +6041,20 @@
ForwardIterator
shift_left(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last,
typename iterator_traits<ForwardIterator>::difference_type n);

template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@<I> S>
constexpr subrange<I> ranges::shift_left(I first, S last, iter_difference_t<I> n);
template<@\libconcept{forward_range}@ R>
requires @\libconcept{permutable}@<iterator_t<R>>
constexpr borrowed_subrange_t<R> ranges::shift_left(R&& r, range_difference_t<R> n)
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{n >= 0} is \tcode{true}.
The type of \tcode{*first} meets
the \oldconcept{MoveAssignable} requirements.
For the overloads in namespace \tcode{std},
the type of \tcode{*first} meets the \oldconcept{MoveAssignable} requirements.

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

\pnum
\returns
\tcode{first + (last - first - n)}
Let \exposid{NEW_LAST} be \tcode{first + (last - first - n)}
if \tcode{n < last - first},
otherwise \tcode{first}.
\begin{itemize}
\item
\exposid{NEW_LAST} for the overloads in namespace \tcode{std}.
\item
\tcode{\{first, \exposid{NEW_LAST}\}}
for the overloads in namespace \tcode{ranges}.
\end{itemize}

\pnum
\complexity
Expand All @@ -6043,15 +6095,21 @@
ForwardIterator
shift_right(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last,
typename iterator_traits<ForwardIterator>::difference_type n);

template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@<I> S>
constexpr subrange<I> ranges::shift_right(I first, S last, iter_difference_t<I> n);
template<@\libconcept{forward_range}@ R>
requires @\libconcept{permutable}@<iterator_t<R>>
constexpr borrowed_subrange_t<R> ranges::shift_right(R&& r, range_difference_t<R> n);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{n >= 0} is \tcode{true}.
The type of \tcode{*first} meets
the \oldconcept{MoveAssignable} requirements.
\tcode{ForwardIterator} meets
For the overloads in namespace \tcode{std},
the type of \tcode{*first} meets the \oldconcept{MoveAssignable} requirements,
and \tcode{ForwardIterator} meets
the \oldconcept{BidirectionalIterator} requirements\iref{bidirectional.iterators} or
the \oldconcept{ValueSwap\-pable} requirements.

Expand All @@ -6061,16 +6119,29 @@
Otherwise, moves the element
from position \tcode{first + i} into position \tcode{first + n + i}
for each non-negative integer \tcode{i < (last - first) - n}.
In the first overload case, if \tcode{ForwardIterator} meets
the \oldconcept{BidirectionalIterator} requirements,
does so in order starting
from \tcode{i = (last - first) - n - 1} and proceeding to \tcode{i = 0}.
Does so in order starting
from \tcode{i = (last - first) - n - 1} and proceeding to \tcode{i = 0} if:
\begin{itemize}
\item
for the overload in namespace \tcode{std}
without an \tcode{ExecutionPolicy} template parameter,
\tcode{Forward\-Iterator} meets the \oldconcept{BidirectionalIterator} requirements,
\item
for the overloads in namespace \tcode{ranges},
\tcode{I} models \libconcept{bidirectional_iterator}.
\end{itemize}

\pnum
\returns
\tcode{first + n}
if \tcode{n < last - first},
Let \exposid{NEW_FIRST} be \tcode{first + n} if \tcode{n < last - first},
otherwise \tcode{last}.
\begin{itemize}
\item
\exposid{NEW_FIRST} for the overloads in namespace \tcode{std}.
\item
\tcode{\{\exposid{NEW_FIRST}, last\}}
for the overloads in namespace \tcode{ranges}.
\end{itemize}

\pnum
\complexity
Expand Down Expand Up @@ -9104,6 +9175,18 @@
template<class ForwardIterator, class T>
constexpr void iota(ForwardIterator first, ForwardIterator last, T value);

namespace ranges {
template<class O, class T>
using iota_result = out_value_result<O, T>;

template<@\libconcept{input_or_output_iterator}@ O, @\libconcept{sentinel_for}@<O> S, @\libconcept{weakly_incrementable}@ T>
requires @\libconcept{indirectly_writable}@<O, const T&>
constexpr iota_result<O, T> iota(O first, S last, T value);

template<@\libconcept{weakly_incrementable}@ T, @\libconcept{output_range}@<const T&> R>
constexpr iota_result<borrowed_iterator_t<R>, T> iota(R&& r, T value);
}

// \ref{numeric.ops.gcd}, greatest common divisor
template<class M, class N>
constexpr common_type_t<M, N> gcd(M m, N n);
Expand Down Expand Up @@ -10105,6 +10188,29 @@
Exactly \tcode{last - first} increments and assignments.
\end{itemdescr}

\indexlibraryglobal{iota}%
\begin{itemdecl}
template<@\libconcept{input_or_output_iterator}@ O, @\libconcept{sentinel_for}@<O> S, @\libconcept{weakly_incrementable}@ T>
requires @\libconcept{indirectly_writable}@<O, const T&>
constexpr ranges::iota_result<O, T> ranges::iota(O first, S last, T value);
template<@\libconcept{weakly_incrementable}@ T, @\libconcept{output_range}@<const T&> R>
constexpr ranges::iota_result<borrowed_iterator_t<R>, T> ranges::iota(R&& r, T value);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
while (first != last) {
*first = as_const(value);
++first;
++value;
}
return {std::move(first), std::move(value)};
\end{codeblock}
\end{itemdescr}

\rSec2[numeric.ops.gcd]{Greatest common divisor}

\indexlibraryglobal{gcd}%
Expand Down
3 changes: 2 additions & 1 deletion source/support.tex
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,7 @@
#define @\defnlibxname{cpp_lib_quoted_string_io}@ 201304L // also in \libheader{iomanip}
#define @\defnlibxname{cpp_lib_ranges}@ 202202L
// also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_iota}@ 202202L // also in \libheader{numeric}
#define @\defnlibxname{cpp_lib_ranges_starts_ends_with}@ 202106L // also in \libheader{algorithm}
#define @\defnlibxname{cpp_lib_ranges_to_container}@ 202202L // also in \libheader{ranges}
#define @\defnlibxname{cpp_lib_ranges_zip}@ 202110L // also in \libheader{ranges}, \libheader{tuple}, \libheader{utility}
Expand All @@ -686,7 +687,7 @@
#define @\defnlibxname{cpp_lib_shared_ptr_arrays}@ 201707L // also in \libheader{memory}
#define @\defnlibxname{cpp_lib_shared_ptr_weak_type}@ 201606L // also in \libheader{memory}
#define @\defnlibxname{cpp_lib_shared_timed_mutex}@ 201402L // also in \libheader{shared_mutex}
#define @\defnlibxname{cpp_lib_shift}@ 201806L // also in \libheader{algorithm}
#define @\defnlibxname{cpp_lib_shift}@ 202202L // also in \libheader{algorithm}
#define @\defnlibxname{cpp_lib_smart_ptr_for_overwrite}@ 202002L // also in \libheader{memory}
#define @\defnlibxname{cpp_lib_source_location}@ 201907L // also in \libheader{source_location}
#define @\defnlibxname{cpp_lib_span}@ 202002L // also in \libheader{span}
Expand Down