**Section:** 27.7.1 [alg.copy] **Status:** New
**Submitter:** Marshall Clow **Opened:** 2018-03-21 **Last modified:** 2022-11-06 14:24:48 UTC

**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 of `copy` 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.

I think it should. I checked the minutes of the LWG discussion from 2008 when this was added, and there was no discussion of overlapping ranges.

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 27.7.1 [alg.copy] as indicated:

[

Drafting note:I'm using the permission in 27.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:resultshall not be in the range[first, first + n).-9-

Effects:For each non-negative integeri < 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 27.7.1 [alg.copy] as indicated:

[

*Drafting note:*I'm using the permission in 27.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

be max*N*`(0, n)`.-11-

*Mandates*: The type`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 integer, performs*i*< N`*(result +`.*i*) = *(first +*i*)-13-

*Returns*:(13.1) —

`result +`for the overloads in namespace*N*`std`.(13.2) —

`{first +`for the overload in namespace*N*, result +*N*}`ranges`.

-14-

*Complexity:*Exactlyassignments.*N*