Section: 26.11.5 [uninitialized.copy], 26.11.6 [uninitialized.move] Status: C++20 Submitter: Corentin Jabot Opened: 2019-11-12 Last modified: 2021-02-25
Priority: 2
View all other issues in [uninitialized.copy].
View all issues with C++20 status.
Discussion:
P1207 introduced move-only input iterators but did not modify the specialized memory algorithms to support them.
[2020-01 Priority set to 2 after review on the reflector.]
[2020-02 Status to Immediate on Friday morning in Prague.]
Proposed resolution:
This wording is relative to N4842.
Modify 26.11.5 [uninitialized.copy] as indicated:
namespace ranges { template<input_iterator I, sentinel_for<I> S1, no-throw-forward-iterator O, no-throw-sentinel<O> S2> requires constructible_from<iter_value_t<O>, iter_reference_t<I>> uninitialized_copy_result<I, O> uninitialized_copy(I ifirst, S1 ilast, O ofirst, S2 olast); template<input_range IR, no-throw-forward-range OR> requires constructible_from<range_value_t<OR>, range_reference_t<IR>> uninitialized_copy_result<safe_iterator_t<IR>, safe_iterator_t<OR>> uninitialized_copy(IR&& in_range, OR&& out_range); }[…]-4- Preconditions:
-5- Effects: Equivalent to:[ofirst, olast)
shall not overlap with[ifirst, ilast)
.for (; ifirst != ilast && ofirst != olast; ++ofirst, (void)++ifirst) { ::new (voidify(*ofirst)) remove_reference_t<iter_reference_t<O>>(*ifirst); } return {std::move(ifirst), ofirst};namespace ranges { template<input_iterator I, no-throw-forward-iterator O, no-throw-sentinel<O> S> requires constructible_from<iter_value_t<O>, iter_reference_t<I>> uninitialized_copy_n_result<I, O> uninitialized_copy_n(I ifirst, iter_difference_t<I> n, O ofirst, S olast); }-9- Preconditions:
-10- Effects: Equivalent to:[ofirst, olast)
shall not overlap with[ifirst, n)
.auto t = uninitialized_copy(counted_iterator(ifirst, n), default_sentinel, ofirst, olast); return {std::move(t.in).base(), t.out};
Modify 26.11.6 [uninitialized.move] as indicated:
namespace ranges { template<input_iterator I, sentinel_for<I> S1, no-throw-forward-iterator O, no-throw-sentinel<O> S2> requires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>> uninitialized_move_result<I, O> uninitialized_move(I ifirst, S1 ilast, O ofirst, S2 olast); template<input_range IR, no-throw-forward-range OR> requires constructible_from<range_value_t<OR>, range_rvalue_reference_t<IR>> uninitialized_move_result<safe_iterator_t<IR>, safe_iterator_t<OR>> uninitialized_move(IR&& in_range, OR&& out_range); }[…]-3- Preconditions:
-4- Effects: Equivalent to:[ofirst, olast)
shall not overlap with[ifirst, ilast)
.for (; ifirst != ilast && ofirst != olast; ++ofirst, (void)++ifirst) { ::new (voidify(*ofirst)) remove_reference_t<iter_reference_t<O>>(ranges::iter_move(*ifirst)); } return {std::move(ifirst), ofirst};namespace ranges { template<input_iterator I, no-throw-forward-iterator O, no-throw-sentinel<O> S> requires constructible_from<iter_value_t<O>, iter_rvalue_reference_t<I>> uninitialized_move_n_result<I, O> uninitialized_move_n(I ifirst, iter_difference_t<I> n, O ofirst, S olast); }-8- Preconditions:
-9- Effects: Equivalent to:[ofirst, olast)
shall not overlap with[ifirst, n)
.auto t = uninitialized_move(counted_iterator(ifirst, n), default_sentinel, ofirst, olast); return {std::move(t.in).base(), t.out};