copy_n
should require non-overlapping rangesSection: 26.7.1 [alg.copy] Status: New Submitter: Marshall Clow Opened: 2018-03-21 Last modified: 2022-11-06
Priority: 3
View other active issues in [alg.copy].
View all other issues in [alg.copy].
View all issues with New status.
Discussion:
All the copy algorithms have some kind of prohibition on having the input and output ranges overlap.
The serial version ofcopy
says:
Requires:
result
shall not be in the range[first, last)
.
The parallel version of copy
says:
Requires: The ranges
[first, last)
and[result, result + (last - first))
shall not overlap.
copy_if
says:
Requires: The ranges
[first, last)
and[result, result + (last - first))
shall not overlap.
copy_backwards
says:
Requires:
result
shall not be in the range[first, last)
.
But copy_n
has no such requirement.
What formulation do we want here? Is it sufficient to say "... shall not be in the range ..." or should we use the stronger "... shall not overlap ..."? Some copy
variants use one, some use the other. Should we be consistent? Issue 3085 is a similar issue for char_traits::copy
.
[2018-06-18 after reflector discussion]
Priority set to 3
Previous resolution [SUPERSEDED]:
This wording is relative to N4727.
Edit 26.7.1 [alg.copy] as indicated:
[Drafting note: I'm using the permission in 26.2 [algorithms.requirements]/10 to do random-access arithmetic on (possibly) input iterators.]
template<class InputIterator, class Size, class OutputIterator> constexpr OutputIterator copy_n(InputIterator first, Size n, OutputIterator result); template<class ExecutionPolicy, class ForwardIterator1, class Size, class ForwardIterator2> ForwardIterator2 copy_n(ExecutionPolicy&& exec, ForwardIterator1 first, Size n, ForwardIterator2 result);-?- Requires:
-9- Effects: For each non-negative integerresult
shall not be in the range[first, first + n)
.i < n
, performs*(result + i) = *(first + i)
. -10- Returns:result + n
. -11- Complexity: Exactlyn
assignments.
[2022-11-06; Daniel syncs wording with recent working draft]
Proposed resolution:
This wording is relative to N4917.
Edit 26.7.1 [alg.copy] as indicated:
[Drafting note: I'm using the permission in 26.2 [algorithms.requirements]/10 to do random-access arithmetic on (possibly) input iterators.]
template<class InputIterator, class Size, class OutputIterator> constexpr OutputIterator copy_n(InputIterator first, Size n, OutputIterator result); template<class ExecutionPolicy, class ForwardIterator1, class Size, class ForwardIterator2> ForwardIterator2 copy_n(ExecutionPolicy&& exec, ForwardIterator1 first, Size n, ForwardIterator2 result); template<input_iterator I, weakly_incrementable O> requires indirectly_copyable<I, O> constexpr ranges::copy_n_result<I, O> ranges::copy_n(I first, iter_difference_t<I> n, O result);-10- Let
-11- Mandates: The typeN
be max(0, n)
.Size
is convertible to an integral type (7.3.9, 11.4.8). -?- Preconditions:result
is not in the range[first, first + n)
. -12- Effects: For each non-negative integeri < N
, performs*(result + i) = *(first + i)
. -13- Returns:
(13.1) —
result + N
for the overloads in namespacestd
.(13.2) —
{first + N, result + N}
for the overload in namespaceranges
.-14- Complexity: Exactly
N
assignments.