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:
resultshall 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:
resultshall 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 integerresultshall not be in the range[first, first + n).i < n, performs*(result + i) = *(first + i). -10- Returns:result + n. -11- Complexity: Exactlynassignments.
[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 typeNbe max(0, n).Sizeis convertible to an integral type (7.3.9, 11.4.8). -?- Preconditions:resultis 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 + Nfor the overloads in namespacestd.(13.2) —
{first + N, result + N}for the overload in namespaceranges.-14- Complexity: Exactly
Nassignments.