diff --git a/source/algorithms.tex b/source/algorithms.tex index c6f00f2971..9f791a1c32 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -641,6 +641,9 @@ template struct in_found_result; + + template + struct out_value_result; } // \ref{alg.nonmodifying}, non-modifying sequence operations @@ -1815,6 +1818,15 @@ shift_left(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} ForwardIterator first, ForwardIterator last, typename iterator_traits::difference_type n); + + namespace ranges { + template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@ S> + constexpr subrange shift_left(I first, S last, iter_difference_t n); + template<@\libconcept{forward_range}@ R> + requires @\libconcept{permutable}@> + constexpr borrowed_subrange_t shift_left(R&& r, range_difference_t n); + } + template constexpr ForwardIterator shift_right(ForwardIterator first, ForwardIterator last, @@ -1825,6 +1837,14 @@ ForwardIterator first, ForwardIterator last, typename iterator_traits::difference_type n); + namespace ranges { + template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@ S> + constexpr subrange shift_right(I first, S last, iter_difference_t n); + template<@\libconcept{forward_range}@ R> + requires @\libconcept{permutable}@> + constexpr borrowed_subrange_t shift_right(R&& r, range_difference_t n); + } + // \ref{alg.sorting}, sorting and related operations // \ref{alg.sort}, sorting template @@ -2741,7 +2761,7 @@ ForwardIterator first, ForwardIterator last, Compare comp); - namespace ranges { + namespace ranges { template<@\libconcept{forward_iterator}@ I, @\libconcept{sentinel_for}@ S, class Proj = identity, @\libconcept{indirect_strict_weak_order}@> Comp = ranges::less> constexpr I max_element(I first, S last, Comp comp = {}, Proj proj = {}); @@ -3037,6 +3057,24 @@ return {std::move(in), found}; } }; + + template + struct out_value_result { + [[no_unique_address]] O out; + [[no_unique_address]] T value; + + template + requires @\libconcept{convertible_to}@ && @\libconcept{convertible_to}@ + constexpr operator out_value_result() const & { + return {out, value}; + } + + template + requires @\libconcept{convertible_to}@ && @\libconcept{convertible_to}@ + constexpr operator out_value_result() && { + return {std::move(out), std::move(value)}; + } + }; } \end{codeblock} @@ -6003,14 +6041,20 @@ ForwardIterator shift_left(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, typename iterator_traits::difference_type n); + +template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@ S> + constexpr subrange ranges::shift_left(I first, S last, iter_difference_t n); +template<@\libconcept{forward_range}@ R> + requires @\libconcept{permutable}@> + constexpr borrowed_subrange_t ranges::shift_left(R&& r, range_difference_t 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 @@ -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 @@ -6043,15 +6095,21 @@ ForwardIterator shift_right(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, typename iterator_traits::difference_type n); + +template<@\libconcept{permutable}@ I, @\libconcept{sentinel_for}@ S> + constexpr subrange ranges::shift_right(I first, S last, iter_difference_t n); +template<@\libconcept{forward_range}@ R> + requires @\libconcept{permutable}@> + constexpr borrowed_subrange_t ranges::shift_right(R&& r, range_difference_t 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. @@ -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 @@ -9104,6 +9175,18 @@ template constexpr void iota(ForwardIterator first, ForwardIterator last, T value); + namespace ranges { + template + using iota_result = out_value_result; + + template<@\libconcept{input_or_output_iterator}@ O, @\libconcept{sentinel_for}@ S, @\libconcept{weakly_incrementable}@ T> + requires @\libconcept{indirectly_writable}@ + constexpr iota_result iota(O first, S last, T value); + + template<@\libconcept{weakly_incrementable}@ T, @\libconcept{output_range}@ R> + constexpr iota_result, T> iota(R&& r, T value); + } + // \ref{numeric.ops.gcd}, greatest common divisor template constexpr common_type_t gcd(M m, N n); @@ -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}@ S, @\libconcept{weakly_incrementable}@ T> + requires @\libconcept{indirectly_writable}@ + constexpr ranges::iota_result ranges::iota(O first, S last, T value); +template<@\libconcept{weakly_incrementable}@ T, @\libconcept{output_range}@ R> + constexpr ranges::iota_result, 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}% diff --git a/source/support.tex b/source/support.tex index 35cbe37ccc..aee6b78e5c 100644 --- a/source/support.tex +++ b/source/support.tex @@ -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} @@ -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}