From da877ca211228a29e7b0adf38f7c1aa98264c9cc Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Wed, 19 Feb 2020 23:47:56 +0100 Subject: [PATCH 1/4] P1963R0 Fixing US 313 Also fixes NB US 313 (C++20 CD) and LWG3156. --- source/algorithms.tex | 715 +++++++++++++++++++++++++++++++++ source/utilities.tex | 903 ++++-------------------------------------- 2 files changed, 799 insertions(+), 819 deletions(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index b6175e94fb..d1c8e0d8bc 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -88,6 +88,14 @@ \tcode{Forward\-Iterator2}, the template argument shall meet the \oldconcept{ForwardIterator} requirements\iref{forward.iterators}. +\item + If an algorithm's template parameter is named + \tcode{NoThrowForwardIterator}, + the template argument shall meet the + \oldconcept{ForwardIterator} requirements\iref{forward.iterators}, and + is required to have the property that no exceptions are thrown + from increment, assignment, comparison, or + indirection through valid iterators. \item If an algorithm's template parameter is named \tcode{BidirectionalIterator}, @@ -9923,6 +9931,713 @@ where the result of the division is truncated towards zero. \end{itemdescr} +\rSec1[specialized.algorithms]{Specialized \tcode{} algorithms} + +\pnum +The contents specified in this subclause~\ref{specialized.algorithms} +are declared in the header \libheaderref{memory}. + +\pnum +Unless otherwise specified, +if an exception is thrown in the following algorithms, +objects constructed by a placement \grammarterm{new-expression}\iref{expr.new} +are destroyed in an unspecified order +before allowing the exception to propagate. + +\pnum +\begin{note} +When invoked on ranges of +potentially overlapping subobjects\iref{intro.object}, +the algorithms specified in this subclause \ref{specialized.algorithms} +result in undefined behavior. +\end{note} + +\pnum +Some algorithms specified in this clause make use of the exposition-only function +\tcode{\placeholdernc{voidify}}: +\begin{codeblock} +template + constexpr void* @\placeholdernc{voidify}@(T& obj) noexcept { + return const_cast(static_cast(addressof(obj))); + } +\end{codeblock} + +\rSec2[special.mem.concepts]{Special memory concepts} + +\pnum +Some algorithms in this subclause are constrained with the following +exposition-only concepts: + +\begin{itemdecl} +template +concept @\defexposconcept{no-throw-input-iterator}@ = // \expos + input_iterator && + is_lvalue_reference_v> && + same_as>, iter_value_t>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +A type \tcode{I} models \tcode{\placeholder{no-throw-input-iterator}} only if +no exceptions are thrown from increment, +copy construction, move construction, +copy assignment, move assignment, +or indirection through valid iterators. + +\pnum +\begin{note} +This concept allows some \libconcept{input_iterator}\iref{iterator.concept.input} +operations to throw exceptions. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +template +concept @\defexposconcept{no-throw-sentinel}@ = sentinel_for; // \expos +\end{itemdecl} + +\begin{itemdescr} +\pnum +Types \tcode{S} and \tcode{I} model \tcode{\placeholder{no-throw-sentinel}} +only if no exceptions are thrown from copy construction, move construction, +copy assignment, move assignment, or comparisons between +valid values of type \tcode{I} and \tcode{S}. + +\pnum +\begin{note} +This concept allows some \libconcept{sentinel_for}\iref{iterator.concept.sentinel} +operations to throw exceptions. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +template +concept @\defexposconcept{no-throw-input-range}@ = // \expos + range && + @\placeholder{no-throw-input-iterator}@> && + @\placeholdernc{no-throw-sentinel}@, iterator_t>; +\end{itemdecl} + +\begin{itemdescr} +\pnum +A type \tcode{R} models \tcode{\placeholder{no-throw-input-range}} only if +no exceptions are thrown from calls to \tcode{ranges::begin} and +\tcode{ranges::end} on an object of type \tcode{R}. +\end{itemdescr} + +\begin{itemdecl} +template +concept @\defexposconcept{no-throw-forward-iterator}@ = // \expos + @\placeholder{no-throw-input-iterator}@ && + forward_iterator && + @\placeholdernc{no-throw-sentinel}@; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\begin{note} +This concept allows some \libconcept{forward_iterator}\iref{iterator.concept.forward} +operations to throw exceptions. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +template +concept @\defexposconcept{no-throw-forward-range}@ = // \expos + @\placeholder{no-throw-input-range}@ && + @\placeholder{no-throw-forward-iterator}@>; +\end{itemdecl} + +\rSec2[uninitialized.construct.default]{\tcode{uninitialized_default_construct}} + +\indexlibraryglobal{uninitialized_default_construct}% +\begin{itemdecl} +template + void uninitialized_default_construct(NoThrowForwardIterator first, NoThrowForwardIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (; first != last; ++first) + ::new (@\placeholdernc{voidify}@(*first)) + typename iterator_traits::value_type; +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{uninitialized_default_construct}% +\begin{itemdecl} +namespace ranges { + template<@\placeholdernc{no-throw-forward-iterator}@ I, @\placeholdernc{no-throw-sentinel}@ S> + requires default_initializable> + I uninitialized_default_construct(I first, S last); + template<@\placeholdernc{no-throw-forward-range}@ R> + requires default_initializable> + borrowed_iterator_t uninitialized_default_construct(R&& r); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (; first != last; ++first) + ::new (@\placeholdernc{voidify}@(*first)) remove_reference_t>; +return first; +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{uninitialized_default_construct_n}% +\begin{itemdecl} +template + NoThrowForwardIterator uninitialized_default_construct_n(NoThrowForwardIterator first, Size n); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (; n > 0; (void)++first, --n) + ::new (@\placeholdernc{voidify}@(*first)) + typename iterator_traits::value_type; +return first; +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{uninitialized_default_construct_n}% +\begin{itemdecl} +namespace ranges { + template<@\placeholdernc{no-throw-forward-iterator}@ I> + requires default_initializable> + I uninitialized_default_construct_n(I first, iter_difference_t n); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return uninitialized_default_construct(counted_iterator(first, n), + default_sentinel).base(); +\end{codeblock} +\end{itemdescr} + +\rSec2[uninitialized.construct.value]{\tcode{uninitialized_value_construct}} + +\indexlibraryglobal{uninitialized_value_construct}% +\begin{itemdecl} +template + void uninitialized_value_construct(NoThrowForwardIterator first, NoThrowForwardIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (; first != last; ++first) + ::new (@\placeholdernc{voidify}@(*first)) + typename iterator_traits::value_type(); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{uninitialized_value_construct}% +\begin{itemdecl} +namespace ranges { + template<@\placeholdernc{no-throw-forward-iterator}@ I, @\placeholdernc{no-throw-sentinel}@ S> + requires default_initializable> + I uninitialized_value_construct(I first, S last); + template<@\placeholdernc{no-throw-forward-range}@ R> + requires default_initializable> + borrowed_iterator_t uninitialized_value_construct(R&& r); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (; first != last; ++first) + ::new (@\placeholdernc{voidify}@(*first)) remove_reference_t>(); +return first; +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{uninitialized_value_construct_n}% +\begin{itemdecl} +template + NoThrowForwardIterator uninitialized_value_construct_n(NoThrowForwardIterator first, Size n); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (; n > 0; (void)++first, --n) + ::new (@\placeholdernc{voidify}@(*first)) + typename iterator_traits::value_type(); +return first; +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{uninitialized_value_construct_n}% +\begin{itemdecl} +namespace ranges { + template<@\placeholdernc{no-throw-forward-iterator}@ I> + requires default_initializable> + I uninitialized_value_construct_n(I first, iter_difference_t n); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return uninitialized_value_construct(counted_iterator(first, n), + default_sentinel).base(); +\end{codeblock} +\end{itemdescr} + +\rSec2[uninitialized.copy]{\tcode{uninitialized_copy}} + +\indexlibraryglobal{uninitialized_copy}% +\begin{itemdecl} +template + NoThrowForwardIterator uninitialized_copy(InputIterator first, InputIterator last, + NoThrowForwardIterator result); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\range{result}{(last - first)} does not overlap with \range{first}{last}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (; first != last; ++result, (void) ++first) + ::new (@\placeholdernc{voidify}@(*result)) + typename iterator_traits::value_type(*first); +\end{codeblock} + +\pnum +\returns +\tcode{result}. +\end{itemdescr} + +\indexlibraryglobal{uninitialized_copy}% +\begin{itemdecl} +namespace ranges { + template S1, + @\placeholdernc{no-throw-forward-iterator}@ O, @\placeholdernc{no-throw-sentinel}@ S2> + requires constructible_from, iter_reference_t> + uninitialized_copy_result + uninitialized_copy(I ifirst, S1 ilast, O ofirst, S2 olast); + template + requires constructible_from, range_reference_t> + uninitialized_copy_result, borrowed_iterator_t> + uninitialized_copy(IR&& in_range, OR&& out_range); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\range{ofirst}{olast} does not overlap with \range{ifirst}{ilast}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (; ifirst != ilast && ofirst != olast; ++ofirst, (void)++ifirst) { + ::new (@\placeholdernc{voidify}@(*ofirst)) remove_reference_t>(*ifirst); +} +return {std::move(ifirst), ofirst}; +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{uninitialized_copy_n}% +\begin{itemdecl} +template + NoThrowForwardIterator uninitialized_copy_n(InputIterator first, Size n, + NoThrowForwardIterator result); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\range{result}{n} does not overlap with \range{first}{n}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +for ( ; n > 0; ++result, (void) ++first, --n) { + ::new (@\placeholdernc{voidify}@(*result)) + typename iterator_traits::value_type(*first); +} +\end{codeblock} + +\pnum +\returns +\tcode{result}. +\end{itemdescr} + +\indexlibraryglobal{uninitialized_copy_n}% +\begin{itemdecl} +namespace ranges { + template S> + requires constructible_from, iter_reference_t> + uninitialized_copy_n_result + uninitialized_copy_n(I ifirst, iter_difference_t n, O ofirst, S olast); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\range{ofirst}{olast} does not overlap with +\range{ifirst}{n}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto t = uninitialized_copy(counted_iterator(ifirst, n), + default_sentinel, ofirst, olast); +return {std::move(t.in).base(), t.out}; +\end{codeblock} +\end{itemdescr} + +\rSec2[uninitialized.move]{\tcode{uninitialized_move}} + +\indexlibraryglobal{uninitialized_move}% +\begin{itemdecl} +template + NoThrowForwardIterator uninitialized_move(InputIterator first, InputIterator last, + NoThrowForwardIterator result); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\range{result}{(last - first)} does not overlap with \range{first}{last}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (; first != last; (void)++result, ++first) + ::new (@\placeholdernc{voidify}@(*result)) + typename iterator_traits::value_type(std::move(*first)); +return result; +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{uninitialized_move}% +\begin{itemdecl} +namespace ranges { + template S1, + @\placeholdernc{no-throw-forward-iterator}@ O, @\placeholdernc{no-throw-sentinel}@ S2> + requires constructible_from, iter_rvalue_reference_t> + uninitialized_move_result + uninitialized_move(I ifirst, S1 ilast, O ofirst, S2 olast); + template + requires constructible_from, range_rvalue_reference_t> + uninitialized_move_result, borrowed_iterator_t> + uninitialized_move(IR&& in_range, OR&& out_range); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\range{ofirst}{olast} does not overlap with \range{ifirst}{ilast}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (; ifirst != ilast && ofirst != olast; ++ofirst, (void)++ifirst) { + ::new (@\placeholder{voidify}@(*ofirst)) + remove_reference_t>(ranges::iter_move(ifirst)); +} +return {std::move(ifirst), ofirst}; +\end{codeblock} + +\pnum +\begin{note} +If an exception is thrown, some objects in the range \range{first}{last} are +left in a valid, but unspecified state. +\end{note} +\end{itemdescr} + +\indexlibraryglobal{uninitialized_move_n}% +\begin{itemdecl} +template + pair + uninitialized_move_n(InputIterator first, Size n, NoThrowForwardIterator result); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\range{result}{n} does not overlap with \range{first}{n}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (; n > 0; ++result, (void) ++first, --n) + ::new (@\placeholdernc{voidify}@(*result)) + typename iterator_traits::value_type(std::move(*first)); +return {first,result}; +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{uninitialized_move_n}% +\begin{itemdecl} +namespace ranges { + template S> + requires constructible_from, iter_rvalue_reference_t> + uninitialized_move_n_result + uninitialized_move_n(I ifirst, iter_difference_t n, O ofirst, S olast); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\range{ofirst}{olast} does not overlap with \range{ifirst}{n}. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +auto t = uninitialized_move(counted_iterator(ifirst, n), + default_sentinel, ofirst, olast); +return {std::move(t.in).base(), t.out}; +\end{codeblock} + +\pnum +\begin{note} +If an exception is thrown, some objects in the range +\range{first}{n} +are left in a valid but unspecified state. +\end{note} +\end{itemdescr} + +\rSec2[uninitialized.fill]{\tcode{uninitialized_fill}} + +\indexlibraryglobal{uninitialized_fill}% +\begin{itemdecl} +template + void uninitialized_fill(NoThrowForwardIterator first, NoThrowForwardIterator last, const T& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (; first != last; ++first) + ::new (@\placeholdernc{voidify}@(*first)) + typename iterator_traits::value_type(x); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{uninitialized_fill}% +\begin{itemdecl} +namespace ranges { + template<@\placeholdernc{no-throw-forward-iterator}@ I, @\placeholdernc{no-throw-sentinel}@ S, class T> + requires constructible_from, const T&> + I uninitialized_fill(I first, S last, const T& x); + template<@\placeholdernc{no-throw-forward-range}@ R, class T> + requires constructible_from, const T&> + borrowed_iterator_t uninitialized_fill(R&& r, const T& x); +} +\end{itemdecl} + +\begin{itemdescr} +\effects +Equivalent to: +\begin{codeblock} +for (; first != last; ++first) { + ::new (@\placeholdernc{voidify}@(*first)) remove_reference_t>(x); +} +return first; +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{uninitialized_fill_n}% +\begin{itemdecl} +template + NoThrowForwardIterator uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (; n--; ++first) + ::new (@\placeholdernc{voidify}@(*first)) + typename iterator_traits::value_type(x); +return first; +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{uninitialized_fill_n}% +\begin{itemdecl} +namespace ranges { + template<@\placeholdernc{no-throw-forward-iterator}@ I, class T> + requires constructible_from, const T&> + I uninitialized_fill_n(I first, iter_difference_t n, const T& x); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return uninitialized_fill(counted_iterator(first, n), default_sentinel, x).base(); +\end{codeblock} +\end{itemdescr} + +\rSec2[specialized.construct]{\tcode{construct_at}} + +\indexlibraryglobal{construct_at} +\begin{itemdecl} +template + constexpr T* construct_at(T* location, Args&&... args); + +namespace ranges { + template + constexpr T* construct_at(T* location, Args&&... args); +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +The expression \tcode{::new (declval()) T(declval()...)} +is well-formed when treated as an unevaluated operand. + +\pnum +\effects +Equivalent to: +\begin{codeblock} +return ::new (@\placeholdernc{voidify}@(*location)) T(std::forward(args)...); +\end{codeblock} +\end{itemdescr} + +\rSec2[specialized.destroy]{\tcode{destroy}} + +\indexlibraryglobal{destroy_at}% +\begin{itemdecl} +template + constexpr void destroy_at(T* location); +namespace ranges { + template + constexpr void destroy_at(T* location) noexcept; +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +\begin{itemize} +\item If \tcode{T} is an array type, equivalent to + \tcode{destroy(begin(*location), end(*location))}. +\item Otherwise, equivalent to + \tcode{location->\~T()}. +\end{itemize} +\end{itemdescr} + +\indexlibraryglobal{destroy}% +\begin{itemdecl} +template + constexpr void destroy(NoThrowForwardIterator first, NoThrowForwardIterator last); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (; first != last; ++first) + destroy_at(addressof(*first)); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{destroy}% +\begin{itemdecl} +namespace ranges { + template<@\placeholdernc{no-throw-input-iterator}@ I, @\placeholdernc{no-throw-sentinel}@ S> + requires destructible> + constexpr I destroy(I first, S last) noexcept; + template<@\placeholdernc{no-throw-input-range}@ R> + requires destructible> + constexpr borrowed_iterator_t destroy(R&& r) noexcept; +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (; first != last; ++first) + destroy_at(addressof(*first)); +return first; +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{destroy_n}% +\begin{itemdecl} +template + constexpr NoThrowForwardIterator destroy_n(NoThrowForwardIterator first, Size n); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +for (; n > 0; (void)++first, --n) + destroy_at(addressof(*first)); +return first; +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{destroy_n}% +\begin{itemdecl} +namespace ranges { + template<@\placeholdernc{no-throw-input-iterator}@ I> + requires destructible> + constexpr I destroy_n(I first, iter_difference_t n) noexcept; +} +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +return destroy(counted_iterator(first, n), default_sentinel).base(); +\end{codeblock} +\end{itemdescr} + \rSec1[alg.c.library]{C library algorithms} \pnum diff --git a/source/utilities.tex b/source/utilities.tex index 06ba237cbb..58fe9c8f1b 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -6610,9 +6610,9 @@ The header \libheaderdef{memory} defines several types and function templates that describe properties of pointers and pointer-like types, manage memory for containers and other template types, destroy objects, and -construct multiple objects in +construct objects in uninitialized memory -buffers~(\ref{pointer.traits}--\ref{specialized.algorithms}). +buffers~(\ref{pointer.traits}--\ref{specialized.addressof} and \ref{specialized.algorithms}). The header also defines the templates \tcode{unique_ptr}, \tcode{shared_ptr}, \tcode{weak_ptr}, and various function templates that operate on objects of these types\iref{smartptr}. @@ -6689,6 +6689,12 @@ template constexpr bool operator==(const allocator&, const allocator&) noexcept; + // \ref{specialized.addressof}, addressof + template + constexpr T* addressof(T& r) noexcept; + template + const T* addressof(const T&&) = delete; + // \ref{specialized.algorithms}, specialized algorithms // \ref{special.mem.concepts}, special memory concepts template @@ -6702,20 +6708,20 @@ template concept @\exposconcept{no-throw-forward-range}@ = @\seebelow@; // \expos - template - constexpr T* addressof(T& r) noexcept; - template - const T* addressof(const T&&) = delete; - template - void uninitialized_default_construct(ForwardIterator first, ForwardIterator last); - template + template + void uninitialized_default_construct(NoThrowForwardIterator first, + NoThrowForwardIterator last); + template void uninitialized_default_construct(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last); - template - ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n); - template - ForwardIterator uninitialized_default_construct_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, Size n); + NoThrowForwardIterator first, + NoThrowForwardIterator last); + template + NoThrowForwardIterator + uninitialized_default_construct_n(NoThrowForwardIterator first, Size n); + template + NoThrowForwardIterator + uninitialized_default_construct_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + NoThrowForwardIterator first, Size n); namespace ranges { template<@\exposconcept{no-throw-forward-iterator}@ I, @\exposconcept{no-throw-sentinel}@ S> @@ -6730,16 +6736,20 @@ I uninitialized_default_construct_n(I first, iter_difference_t n); } - template - void uninitialized_value_construct(ForwardIterator first, ForwardIterator last); - template + template + void uninitialized_value_construct(NoThrowForwardIterator first, + NoThrowForwardIterator last); + template void uninitialized_value_construct(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last); - template - ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n); - template - ForwardIterator uninitialized_value_construct_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, Size n); + NoThrowForwardIterator first, + NoThrowForwardIterator last); + template + NoThrowForwardIterator + uninitialized_value_construct_n(NoThrowForwardIterator first, Size n); + template + NoThrowForwardIterator + uninitialized_value_construct_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + NoThrowForwardIterator first, Size n); namespace ranges { template<@\exposconcept{no-throw-forward-iterator}@ I, @\exposconcept{no-throw-sentinel}@ S> @@ -6754,20 +6764,20 @@ I uninitialized_value_construct_n(I first, iter_difference_t n); } - template - ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, - ForwardIterator result); - template - ForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, - ForwardIterator result); - template - ForwardIterator uninitialized_copy_n(InputIterator first, Size n, - ForwardIterator result); - template - ForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, Size n, - ForwardIterator result); + template + NoThrowForwardIterator uninitialized_copy(InputIterator first, InputIterator last, + NoThrowForwardIterator result); + template + NoThrowForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + InputIterator first, InputIterator last, + NoThrowForwardIterator result); + template + NoThrowForwardIterator uninitialized_copy_n(InputIterator first, Size n, + NoThrowForwardIterator result); + template + NoThrowForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + InputIterator first, Size n, + NoThrowForwardIterator result); namespace ranges { template @@ -6790,20 +6800,20 @@ uninitialized_copy_n(I ifirst, iter_difference_t n, O ofirst, S olast); } - template - ForwardIterator uninitialized_move(InputIterator first, InputIterator last, - ForwardIterator result); - template - ForwardIterator uninitialized_move(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, InputIterator last, - ForwardIterator result); - template - pair uninitialized_move_n(InputIterator first, Size n, - ForwardIterator result); - template - pair + template + NoThrowForwardIterator uninitialized_move(InputIterator first, InputIterator last, + NoThrowForwardIterator result); + template + NoThrowForwardIterator uninitialized_move(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + InputIterator first, InputIterator last, + NoThrowForwardIterator result); + template + pair + uninitialized_move_n(InputIterator first, Size n, NoThrowForwardIterator result); + template + pair uninitialized_move_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - InputIterator first, Size n, ForwardIterator result); + InputIterator first, Size n, NoThrowForwardIterator result); namespace ranges { template @@ -6827,16 +6837,20 @@ uninitialized_move_n(I ifirst, iter_difference_t n, O ofirst, S olast); } - template - void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x); - template + template + void uninitialized_fill(NoThrowForwardIterator first, NoThrowForwardIterator last, + const T& x); + template void uninitialized_fill(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last, const T& x); - template - ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x); - template - ForwardIterator uninitialized_fill_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, Size n, const T& x); + NoThrowForwardIterator first, NoThrowForwardIterator last, + const T& x); + template + NoThrowForwardIterator + uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x); + template + NoThrowForwardIterator + uninitialized_fill_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + NoThrowForwardIterator first, Size n, const T& x); namespace ranges { template<@\exposconcept{no-throw-forward-iterator}@ I, @\exposconcept{no-throw-sentinel}@ S, class T> @@ -6863,16 +6877,16 @@ // \ref{specialized.destroy}, \tcode{destroy} template constexpr void destroy_at(T* location); - template - constexpr void destroy(ForwardIterator first, ForwardIterator last); - template + template + constexpr void destroy(NoThrowForwardIterator first, NoThrowForwardIterator last); + template void destroy(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, ForwardIterator last); - template - constexpr ForwardIterator destroy_n(ForwardIterator first, Size n); - template - ForwardIterator destroy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} - ForwardIterator first, Size n); + NoThrowForwardIterator first, NoThrowForwardIterator last); + template + constexpr NoThrowForwardIterator destroy_n(NoThrowForwardIterator first, Size n); + template + NoThrowForwardIterator destroy_n(ExecutionPolicy&& exec, // see \ref{algorithms.parallel.overloads} + NoThrowForwardIterator first, Size n); namespace ranges { template @@ -8143,167 +8157,7 @@ \tcode{true}. \end{itemdescr} -\rSec2[specialized.algorithms]{Specialized algorithms} - -\pnum -Throughout this subclause, -the names of template parameters are used to express type requirements -for those algorithms defined directly in namespace \tcode{std}. -\begin{itemize} -\item -If an algorithm's template parameter is named \tcode{InputIterator}, -the template argument shall meet the -\oldconcept{InputIterator} requirements\iref{input.iterators}. -\item -If an algorithm's template parameter is named \tcode{ForwardIterator}, -the template argument shall meet the -\oldconcept{ForwardIterator} requirements\iref{forward.iterators}, and -is required to have the property that no exceptions are thrown -from increment, assignment, comparison, or indirection through valid iterators. -\end{itemize} - -\pnum -Unless otherwise specified, -if an exception is thrown in the following algorithms, -objects constructed by a placement \grammarterm{new-expression}\iref{expr.new} -are destroyed in an unspecified order -before allowing the exception to propagate. - -\pnum -In the description of the algorithms, operator \tcode{-} -is used for some of the iterator categories for which -it need not be defined. -In these cases, the value of the expression \tcode{b - a} -is the number of increments of \tcode{a} needed to make -\tcode{bool(a == b)} be \tcode{true}. - -\pnum -The following additional requirements apply for those algorithms -defined in namespace \tcode{std::ranges}: -\begin{itemize} -\item The entities defined in the \tcode{std::ranges} namespace - in this subclause are not found by argument-dependent - name lookup\iref{basic.lookup.argdep}. When found by - unqualified\iref{basic.lookup.unqual} name lookup for the - \grammarterm{postfix-expression} in a function call\iref{expr.call}, they - inhibit argument-dependent name lookup. -\item Overloads of algorithms that take \libconcept{range} arguments\iref{range.range} - behave as if they are implemented by calling \tcode{ranges::begin} - and \tcode{ranges::end} on the \libconcept{range}(s) and dispatching to the - overload that takes separate iterator and sentinel arguments. -\item The number and order of deducible template parameters for algorithm declarations - is unspecified, except where explicitly stated otherwise. - \begin{note} - Consequently, these algorithms may not be called with - explicitly-specified template argument lists. - \end{note} -\end{itemize} - -\pnum -\begin{note} -When invoked on ranges of -potentially overlapping subobjects\iref{intro.object}, -the algorithms specified in this subclause \ref{specialized.algorithms} -result in undefined behavior. -\end{note} - -\pnum -Some algorithms defined in this clause make use of the exposition-only function -\tcode{\placeholdernc{voidify}}: -\begin{codeblock} -template - constexpr void* @\placeholdernc{voidify}@(T& obj) noexcept { - return const_cast(static_cast(addressof(obj))); - } -\end{codeblock} - -\rSec3[special.mem.concepts]{Special memory concepts} - -\pnum -Some algorithms in this subclause are constrained with the following -exposition-only concepts: - -\begin{itemdecl} -template -concept @\defexposconcept{no-throw-input-iterator}@ = // \expos - input_iterator && - is_lvalue_reference_v> && - same_as>, iter_value_t>; -\end{itemdecl} - -\begin{itemdescr} -\pnum -A type \tcode{I} models \tcode{\placeholder{no-throw-input-iterator}} only if -no exceptions are thrown from increment, -copy construction, move construction, -copy assignment, move assignment, -or indirection through valid iterators. - -\pnum -\begin{note} -This concept allows some \libconcept{input_iterator}\iref{iterator.concept.input} -operations to throw exceptions. -\end{note} -\end{itemdescr} - -\begin{itemdecl} -template -concept @\defexposconcept{no-throw-sentinel}@ = sentinel_for; // \expos -\end{itemdecl} - -\begin{itemdescr} -\pnum -Types \tcode{S} and \tcode{I} model \tcode{\placeholder{no-throw-sentinel}} -only if no exceptions are thrown from copy construction, move construction, -copy assignment, move assignment, or comparisons between -valid values of type \tcode{I} and \tcode{S}. - -\pnum -\begin{note} -This concept allows some \libconcept{sentinel_for}\iref{iterator.concept.sentinel} -operations to throw exceptions. -\end{note} -\end{itemdescr} - -\begin{itemdecl} -template -concept @\defexposconcept{no-throw-input-range}@ = // \expos - range && - @\placeholder{no-throw-input-iterator}@> && - @\placeholdernc{no-throw-sentinel}@, iterator_t>; -\end{itemdecl} - -\begin{itemdescr} -\pnum -A type \tcode{R} models \tcode{\placeholder{no-throw-input-range}} only if -no exceptions are thrown from calls to \tcode{ranges::begin} and -\tcode{ranges::end} on an object of type \tcode{R}. -\end{itemdescr} - -\begin{itemdecl} -template -concept @\defexposconcept{no-throw-forward-iterator}@ = // \expos - @\placeholder{no-throw-input-iterator}@ && - forward_iterator && - @\placeholdernc{no-throw-sentinel}@; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\begin{note} -This concept allows some \libconcept{forward_iterator}\iref{iterator.concept.forward} -operations to throw exceptions. -\end{note} -\end{itemdescr} - -\begin{itemdecl} -template -concept @\defexposconcept{no-throw-forward-range}@ = // \expos - @\placeholder{no-throw-input-range}@ && - @\placeholder{no-throw-forward-iterator}@>; -\end{itemdecl} - -\rSec3[specialized.addressof]{\tcode{addressof}} +\rSec2[specialized.addressof]{\tcode{addressof}} \indexlibraryglobal{addressof}% \begin{itemdecl} @@ -8323,595 +8177,6 @@ if \tcode{E} is an lvalue constant subexpression. \end{itemdescr} -\rSec3[uninitialized.construct.default]{\tcode{uninitialized_default_construct}} - -\indexlibraryglobal{uninitialized_default_construct}% -\begin{itemdecl} -template - void uninitialized_default_construct(ForwardIterator first, ForwardIterator last); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -for (; first != last; ++first) - ::new (@\placeholdernc{voidify}@(*first)) - typename iterator_traits::value_type; -\end{codeblock} -\end{itemdescr} - -\indexlibraryglobal{uninitialized_default_construct}% -\begin{itemdecl} -namespace ranges { - template<@\placeholdernc{no-throw-forward-iterator}@ I, @\placeholdernc{no-throw-sentinel}@ S> - requires default_initializable> - I uninitialized_default_construct(I first, S last); - template<@\placeholdernc{no-throw-forward-range}@ R> - requires default_initializable> - borrowed_iterator_t uninitialized_default_construct(R&& r); -} -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -for (; first != last; ++first) - ::new (@\placeholdernc{voidify}@(*first)) remove_reference_t>; -return first; -\end{codeblock} -\end{itemdescr} - -\indexlibraryglobal{uninitialized_default_construct_n}% -\begin{itemdecl} -template - ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -for (; n > 0; (void)++first, --n) - ::new (@\placeholdernc{voidify}@(*first)) - typename iterator_traits::value_type; -return first; -\end{codeblock} -\end{itemdescr} - -\indexlibraryglobal{uninitialized_default_construct_n}% -\begin{itemdecl} -namespace ranges { - template<@\placeholdernc{no-throw-forward-iterator}@ I> - requires default_initializable> - I uninitialized_default_construct_n(I first, iter_difference_t n); -} -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -return uninitialized_default_construct(counted_iterator(first, n), - default_sentinel).base(); -\end{codeblock} -\end{itemdescr} - -\rSec3[uninitialized.construct.value]{\tcode{uninitialized_value_construct}} - -\indexlibraryglobal{uninitialized_value_construct}% -\begin{itemdecl} -template - void uninitialized_value_construct(ForwardIterator first, ForwardIterator last); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -for (; first != last; ++first) - ::new (@\placeholdernc{voidify}@(*first)) - typename iterator_traits::value_type(); -\end{codeblock} -\end{itemdescr} - -\indexlibraryglobal{uninitialized_value_construct}% -\begin{itemdecl} -namespace ranges { - template<@\placeholdernc{no-throw-forward-iterator}@ I, @\placeholdernc{no-throw-sentinel}@ S> - requires default_initializable> - I uninitialized_value_construct(I first, S last); - template<@\placeholdernc{no-throw-forward-range}@ R> - requires default_initializable> - borrowed_iterator_t uninitialized_value_construct(R&& r); -} -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -for (; first != last; ++first) - ::new (@\placeholdernc{voidify}@(*first)) remove_reference_t>(); -return first; -\end{codeblock} -\end{itemdescr} - -\indexlibraryglobal{uninitialized_value_construct_n}% -\begin{itemdecl} -template - ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -for (; n > 0; (void)++first, --n) - ::new (@\placeholdernc{voidify}@(*first)) - typename iterator_traits::value_type(); -return first; -\end{codeblock} -\end{itemdescr} - -\indexlibraryglobal{uninitialized_value_construct_n}% -\begin{itemdecl} -namespace ranges { - template<@\placeholdernc{no-throw-forward-iterator}@ I> - requires default_initializable> - I uninitialized_value_construct_n(I first, iter_difference_t n); -} -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -return uninitialized_value_construct(counted_iterator(first, n), - default_sentinel).base(); -\end{codeblock} -\end{itemdescr} - -\rSec3[uninitialized.copy]{\tcode{uninitialized_copy}} - -\indexlibraryglobal{uninitialized_copy}% -\begin{itemdecl} -template - ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, - ForwardIterator result); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\range{result}{(last - first)} does not overlap with \range{first}{last}. - -\pnum -\effects -Equivalent to: -\begin{codeblock} -for (; first != last; ++result, (void) ++first) - ::new (@\placeholdernc{voidify}@(*result)) - typename iterator_traits::value_type(*first); -\end{codeblock} - -\pnum -\returns -\tcode{result}. -\end{itemdescr} - -\indexlibraryglobal{uninitialized_copy}% -\begin{itemdecl} -namespace ranges { - template S1, - @\placeholdernc{no-throw-forward-iterator}@ O, @\placeholdernc{no-throw-sentinel}@ S2> - requires constructible_from, iter_reference_t> - uninitialized_copy_result - uninitialized_copy(I ifirst, S1 ilast, O ofirst, S2 olast); - template - requires constructible_from, range_reference_t> - uninitialized_copy_result, borrowed_iterator_t> - uninitialized_copy(IR&& in_range, OR&& out_range); -} -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\range{ofirst}{olast} does not overlap with \range{ifirst}{ilast}. - -\pnum -\effects -Equivalent to: -\begin{codeblock} -for (; ifirst != ilast && ofirst != olast; ++ofirst, (void)++ifirst) { - ::new (@\placeholdernc{voidify}@(*ofirst)) remove_reference_t>(*ifirst); -} -return {std::move(ifirst), ofirst}; -\end{codeblock} -\end{itemdescr} - -\indexlibraryglobal{uninitialized_copy_n}% -\begin{itemdecl} -template - ForwardIterator uninitialized_copy_n(InputIterator first, Size n, ForwardIterator result); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\range{result}{n} does not overlap with \range{first}{n}. - -\pnum -\effects -Equivalent to: -\begin{codeblock} -for ( ; n > 0; ++result, (void) ++first, --n) { - ::new (@\placeholdernc{voidify}@(*result)) - typename iterator_traits::value_type(*first); -} -\end{codeblock} - -\pnum -\returns -\tcode{result}. -\end{itemdescr} - -\indexlibraryglobal{uninitialized_copy_n}% -\begin{itemdecl} -namespace ranges { - template S> - requires constructible_from, iter_reference_t> - uninitialized_copy_n_result - uninitialized_copy_n(I ifirst, iter_difference_t n, O ofirst, S olast); -} -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\range{ofirst}{olast} does not overlap with -\range{ifirst}{n}. - -\pnum -\effects -Equivalent to: -\begin{codeblock} -auto t = uninitialized_copy(counted_iterator(ifirst, n), - default_sentinel, ofirst, olast); -return {std::move(t.in).base(), t.out}; -\end{codeblock} -\end{itemdescr} - -\rSec3[uninitialized.move]{\tcode{uninitialized_move}} - -\indexlibraryglobal{uninitialized_move}% -\begin{itemdecl} -template - ForwardIterator uninitialized_move(InputIterator first, InputIterator last, - ForwardIterator result); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\range{result}{(last - first)} does not overlap with \range{first}{last}. - -\pnum -\effects -Equivalent to: -\begin{codeblock} -for (; first != last; (void)++result, ++first) - ::new (@\placeholdernc{voidify}@(*result)) - typename iterator_traits::value_type(std::move(*first)); -return result; -\end{codeblock} -\end{itemdescr} - -\indexlibraryglobal{uninitialized_move}% -\begin{itemdecl} -namespace ranges { - template S1, - @\placeholdernc{no-throw-forward-iterator}@ O, @\placeholdernc{no-throw-sentinel}@ S2> - requires constructible_from, iter_rvalue_reference_t> - uninitialized_move_result - uninitialized_move(I ifirst, S1 ilast, O ofirst, S2 olast); - template - requires constructible_from, range_rvalue_reference_t> - uninitialized_move_result, borrowed_iterator_t> - uninitialized_move(IR&& in_range, OR&& out_range); -} -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\range{ofirst}{olast} does not overlap with \range{ifirst}{ilast}. - -\pnum -\effects -Equivalent to: -\begin{codeblock} -for (; ifirst != ilast && ofirst != olast; ++ofirst, (void)++ifirst) { - ::new (@\placeholder{voidify}@(*ofirst)) - remove_reference_t>(ranges::iter_move(ifirst)); -} -return {std::move(ifirst), ofirst}; -\end{codeblock} - -\pnum -\begin{note} -If an exception is thrown, some objects in the range \range{first}{last} are -left in a valid, but unspecified state. -\end{note} -\end{itemdescr} - -\indexlibraryglobal{uninitialized_move_n}% -\begin{itemdecl} -template - pair - uninitialized_move_n(InputIterator first, Size n, ForwardIterator result); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\range{result}{n} does not overlap with \range{first}{n}. - -\pnum -\effects -Equivalent to: -\begin{codeblock} -for (; n > 0; ++result, (void) ++first, --n) - ::new (@\placeholdernc{voidify}@(*result)) - typename iterator_traits::value_type(std::move(*first)); -return {first,result}; -\end{codeblock} -\end{itemdescr} - -\indexlibraryglobal{uninitialized_move_n}% -\begin{itemdecl} -namespace ranges { - template S> - requires constructible_from, iter_rvalue_reference_t> - uninitialized_move_n_result - uninitialized_move_n(I ifirst, iter_difference_t n, O ofirst, S olast); -} -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\range{ofirst}{olast} does not overlap with \range{ifirst}{n}. - -\pnum -\effects -Equivalent to: -\begin{codeblock} -auto t = uninitialized_move(counted_iterator(ifirst, n), - default_sentinel, ofirst, olast); -return {std::move(t.in).base(), t.out}; -\end{codeblock} - -\pnum -\begin{note} -If an exception is thrown, some objects in the range -\range{first}{n} -are left in a valid but unspecified state. -\end{note} -\end{itemdescr} - -\rSec3[uninitialized.fill]{\tcode{uninitialized_fill}} - -\indexlibraryglobal{uninitialized_fill}% -\begin{itemdecl} -template - void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -for (; first != last; ++first) - ::new (@\placeholdernc{voidify}@(*first)) - typename iterator_traits::value_type(x); -\end{codeblock} -\end{itemdescr} - -\indexlibraryglobal{uninitialized_fill}% -\begin{itemdecl} -namespace ranges { - template<@\placeholdernc{no-throw-forward-iterator}@ I, @\placeholdernc{no-throw-sentinel}@ S, class T> - requires constructible_from, const T&> - I uninitialized_fill(I first, S last, const T& x); - template<@\placeholdernc{no-throw-forward-range}@ R, class T> - requires constructible_from, const T&> - borrowed_iterator_t uninitialized_fill(R&& r, const T& x); -} -\end{itemdecl} - -\begin{itemdescr} -\effects -Equivalent to: -\begin{codeblock} -for (; first != last; ++first) { - ::new (@\placeholdernc{voidify}@(*first)) remove_reference_t>(x); -} -return first; -\end{codeblock} -\end{itemdescr} - -\indexlibraryglobal{uninitialized_fill_n}% -\begin{itemdecl} -template - ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -for (; n--; ++first) - ::new (@\placeholdernc{voidify}@(*first)) - typename iterator_traits::value_type(x); -return first; -\end{codeblock} -\end{itemdescr} - -\indexlibraryglobal{uninitialized_fill_n}% -\begin{itemdecl} -namespace ranges { - template<@\placeholdernc{no-throw-forward-iterator}@ I, class T> - requires constructible_from, const T&> - I uninitialized_fill_n(I first, iter_difference_t n, const T& x); -} -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -return uninitialized_fill(counted_iterator(first, n), default_sentinel, x).base(); -\end{codeblock} -\end{itemdescr} - -\rSec3[specialized.construct]{\tcode{construct_at}} - -\indexlibraryglobal{construct_at} -\begin{itemdecl} -template - constexpr T* construct_at(T* location, Args&&... args); - -namespace ranges { - template - constexpr T* construct_at(T* location, Args&&... args); -} -\end{itemdecl} - -\begin{itemdescr} -\pnum -\constraints -The expression \tcode{::new (declval()) T(declval()...)} -is well-formed when treated as an unevaluated operand. - -\pnum -\effects -Equivalent to: -\begin{codeblock} -return ::new (@\placeholdernc{voidify}@(*location)) T(std::forward(args)...); -\end{codeblock} -\end{itemdescr} - -\rSec3[specialized.destroy]{\tcode{destroy}} - -\indexlibraryglobal{destroy_at}% -\begin{itemdecl} -template - constexpr void destroy_at(T* location); -namespace ranges { - template - constexpr void destroy_at(T* location) noexcept; -} -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -\begin{itemize} -\item If \tcode{T} is an array type, equivalent to - \tcode{destroy(begin(*location), end(*location))}. -\item Otherwise, equivalent to - \tcode{location->\~T()}. -\end{itemize} -\end{itemdescr} - -\indexlibraryglobal{destroy}% -\begin{itemdecl} -template - constexpr void destroy(ForwardIterator first, ForwardIterator last); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -for (; first != last; ++first) - destroy_at(addressof(*first)); -\end{codeblock} -\end{itemdescr} - -\indexlibraryglobal{destroy}% -\begin{itemdecl} -namespace ranges { - template<@\placeholdernc{no-throw-input-iterator}@ I, @\placeholdernc{no-throw-sentinel}@ S> - requires destructible> - constexpr I destroy(I first, S last) noexcept; - template<@\placeholdernc{no-throw-input-range}@ R> - requires destructible> - constexpr borrowed_iterator_t destroy(R&& r) noexcept; -} -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -for (; first != last; ++first) - destroy_at(addressof(*first)); -return first; -\end{codeblock} -\end{itemdescr} - -\indexlibraryglobal{destroy_n}% -\begin{itemdecl} -template - constexpr ForwardIterator destroy_n(ForwardIterator first, Size n); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -for (; n > 0; (void)++first, --n) - destroy_at(addressof(*first)); -return first; -\end{codeblock} -\end{itemdescr} - -\indexlibraryglobal{destroy_n}% -\begin{itemdecl} -namespace ranges { - template<@\placeholdernc{no-throw-input-iterator}@ I> - requires destructible> - constexpr I destroy_n(I first, iter_difference_t n) noexcept; -} -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Equivalent to: -\begin{codeblock} -return destroy(counted_iterator(first, n), default_sentinel).base(); -\end{codeblock} -\end{itemdescr} - \rSec2[c.malloc]{C library memory allocation} \pnum From 193040646cc01368e8c20b4600452046e8eaf660 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Mon, 24 Feb 2020 07:54:11 +0100 Subject: [PATCH 2/4] [algorithms.requirements] Fix non-sensical English for NoThrowForwardIterator --- source/algorithms.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index d1c8e0d8bc..b21976bcdb 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -94,8 +94,8 @@ the template argument shall meet the \oldconcept{ForwardIterator} requirements\iref{forward.iterators}, and is required to have the property that no exceptions are thrown - from increment, assignment, comparison, or - indirection through valid iterators. + from increment, assignment, or comparison of, or + indirection through, valid iterators. \item If an algorithm's template parameter is named \tcode{BidirectionalIterator}, From 2eec680c4bfde4ec961041a71f5de95c59c8a4e8 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Wed, 26 Feb 2020 00:34:24 +0100 Subject: [PATCH 3/4] [uninitialized.move,uninitialized.copy] Use \countedrange where applicable. --- source/algorithms.tex | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index b21976bcdb..d76b9de7a7 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -10218,7 +10218,7 @@ \begin{itemdescr} \pnum \expects -\range{result}{(last - first)} does not overlap with \range{first}{last}. +\countedrange{result}{(last - first)} does not overlap with \range{first}{last}. \pnum \effects @@ -10275,7 +10275,7 @@ \begin{itemdescr} \pnum \expects -\range{result}{n} does not overlap with \range{first}{n}. +\countedrange{result}{n} does not overlap with \countedrange{first}{n}. \pnum \effects @@ -10306,7 +10306,7 @@ \pnum \expects \range{ofirst}{olast} does not overlap with -\range{ifirst}{n}. +\countedrange{ifirst}{n}. \pnum \effects @@ -10330,7 +10330,7 @@ \begin{itemdescr} \pnum \expects -\range{result}{(last - first)} does not overlap with \range{first}{last}. +\countedrange{result}{(last - first)} does not overlap with \range{first}{last}. \pnum \effects @@ -10391,7 +10391,7 @@ \begin{itemdescr} \pnum \expects -\range{result}{n} does not overlap with \range{first}{n}. +\countedrange{result}{n} does not overlap with \countedrange{first}{n}. \pnum \effects @@ -10417,7 +10417,7 @@ \begin{itemdescr} \pnum \expects -\range{ofirst}{olast} does not overlap with \range{ifirst}{n}. +\range{ofirst}{olast} does not overlap with \countedrange{ifirst}{n}. \pnum \effects @@ -10431,7 +10431,7 @@ \pnum \begin{note} If an exception is thrown, some objects in the range -\range{first}{n} +\countedrange{first}{n} are left in a valid but unspecified state. \end{note} \end{itemdescr} From 14fd38fd5ed2cfebe608b2ed2c7d1f00d88a9baf Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Wed, 26 Feb 2020 00:40:25 +0100 Subject: [PATCH 4/4] [specialized.algorithms] Whitespace and punctuation tweaks. - Hyphenate 'potentially-overlapping subobject'. - Add whitespace in range. --- source/algorithms.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/algorithms.tex b/source/algorithms.tex index d76b9de7a7..b43449d2d0 100644 --- a/source/algorithms.tex +++ b/source/algorithms.tex @@ -9947,7 +9947,7 @@ \pnum \begin{note} When invoked on ranges of -potentially overlapping subobjects\iref{intro.object}, +potentially-overlapping subobjects\iref{intro.object}, the algorithms specified in this subclause \ref{specialized.algorithms} result in undefined behavior. \end{note} @@ -10400,7 +10400,7 @@ for (; n > 0; ++result, (void) ++first, --n) ::new (@\placeholdernc{voidify}@(*result)) typename iterator_traits::value_type(std::move(*first)); -return {first,result}; +return {first, result}; \end{codeblock} \end{itemdescr}