https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121026
--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Jonathan Wakely from comment #0) > Fourthly, I don't think this ranges::uninitialized_move optimization is > valid: > > auto [__in, __out] > = ranges::copy_n(std::make_move_iterator(std::move(__ifirst)), > __d, __ofirst); > > Not only does this fail to begin object lifetimes during constant evaluation > (as noted above), but std::move_iterator will move the values using > std::move. If the type has an overloaded iter_move findable via ADL then we > should be using that instead of std::move. > > I think we can only optimize ranges::uninitialized_move for arithmetic types > (and pointers to arithmetic types?). That would enable the use of memcpy for > those types, so still seems worthwhile. We could reuse the concept used by ranges::iter_move: if constexpr (!ranges::__imove::__adl_imove<iter_reference_t<_Iter>>) { auto [__in, __out] = ranges::uninitialized_copy(std::make_move_iterator(std::move(__ifirst)), __ilast, __ofirst, __olast); return {std::move(__in).base(), __out}; } else