This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of WP status.

### 3747. `ranges::uninitialized_copy_n`, `ranges::uninitialized_move_n`, and `ranges::destroy_n` should use `std::move`

Section: 27.11.5 [uninitialized.copy], 27.11.6 [uninitialized.move], 27.11.9 [specialized.destroy] Status: WP Submitter: Hewill Kang Opened: 2022-07-28 Last modified: 2022-11-17

Priority: Not Prioritized

View all other issues in [uninitialized.copy].

View all issues with WP status.

Discussion:

Currently, `ranges::uninitialized_copy_n` has the following equivalent Effects:

>     auto t = uninitialized_copy(counted_iterator(ifirst, n),
>                                 default_sentinel, ofirst, olast);
>     return {std::move(t.in).base(), t.out};

Given that `ifirst` is just an `input_iterator` which is not guaranteed to be `copyable`, we should move it into `counted_iterator`. The same goes for `ranges::uninitialized_move_n` and `ranges::destroy_n`.

[2022-08-23; Reflector poll]

Set status to Tentatively Ready after eight votes in favour during reflector poll.

[2022-11-12 Approved at November 2022 meeting in Kona. Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N4910.

1. Modify 27.11.5 [uninitialized.copy] as indicated:

   >     namespace ranges {
   >       template<input_iterator I, nothrow-forward-iterator O, nothrow-sentinel-for<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: [`ofirst, olast`) does not overlap with `ifirst +` [`0, n`) .

   > > -10- Effects: Equivalent to:

   > > >     auto t = uninitialized_copy(counted_iterator(std::move(ifirst), n),
   > > >                                 default_sentinel, ofirst, olast);
   > > >     return {std::move(t.in).base(), t.out};

2. Modify 27.11.6 [uninitialized.move] as indicated:

   >     namespace ranges {
   >       template<input_iterator I, nothrow-forward-iterator O, nothrow-sentinel-for<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: [`ofirst, olast`) does not overlap with `ifirst +` [`0, n`) .

   > > -9- Effects: Equivalent to:

   > > >     auto t = uninitialized_move(counted_iterator(std::move(ifirst), n),
   > > >                                 default_sentinel, ofirst, olast);
   > > >     return {std::move(t.in).base(), t.out};

3. Modify 27.11.9 [specialized.destroy] as indicated:

   >     namespace ranges {
   >       template<nothrow-input-iterator I>
   >         requires destructible<iter_value_t<I>>
   >         constexpr I destroy_n(I first, iter_difference_t<I> n) noexcept;
   >     }

   > > -5- Effects: Equivalent to:

   > > >     return destroy(counted_iterator(std::move(first), n), default_sentinel).base();