2020-03-04 Patrick Palka <ppalka@redhat.com>
+ LWG 3355 The memory algorithms should support move-only input iterators
+ introduced by P1207
+ * include/bits/ranges_uninitialized.h
+ (__uninitialized_copy_fn::operator()): Use std::move to avoid attempting
+ to copy __ifirst, which could be a move-only input iterator. Use
+ operator- instead of ranges::distance to compute distance from a sized
+ sentinel.
+ (__uninitialized_copy_n_fn::operator()): Likewise.
+ (__uninitialized_move_fn::operator()): Likewise.
+ (__uninitialized_move_n_fn::operator()): Likewise.
+ (__uninitialized_destroy_fn::operator()): Use std::move to avoid
+ attempting to copy __first.
+ (__uninitialized_destroy_n_fn::operator()): Likewise.
+ * testsuite/20_util/specialized_algorithms/destroy/constrained.cc:
+ Augment test.
+ * .../specialized_algorithms/uninitialized_copy/constrained.cc:
+ Likewise.
+ * .../specialized_algorithms/uninitialized_move/constrained.cc:
+ Likewise.
+
* testsuite/util/testsuite_iterators.h (test_range::get_iterator): Make
protected instead of private.
(test_sized_range_sized_sent): New.
&& is_nothrow_assignable_v<_OutType&,
iter_reference_t<_Iter>>)
{
- auto __d1 = ranges::distance(__ifirst, __ilast);
- auto __d2 = ranges::distance(__ofirst, __olast);
- return ranges::copy_n(__ifirst, std::min(__d1, __d2), __ofirst);
+ auto __d1 = __ilast - __ifirst;
+ auto __d2 = __olast - __ofirst;
+ return ranges::copy_n(std::move(__ifirst), std::min(__d1, __d2),
+ __ofirst);
}
else
{
++__ofirst, (void)++__ifirst)
::new (__detail::__voidify(*__ofirst)) _OutType(*__ifirst);
__guard.release();
- return {__ifirst, __ofirst};
+ return {std::move(__ifirst), __ofirst};
}
}
&& is_nothrow_assignable_v<_OutType&,
iter_reference_t<_Iter>>)
{
- auto __d = ranges::distance(__ofirst, __olast);
- return ranges::copy_n(__ifirst, std::min(__n, __d), __ofirst);
+ auto __d = __olast - __ofirst;
+ return ranges::copy_n(std::move(__ifirst), std::min(__n, __d),
+ __ofirst);
}
else
{
++__ofirst, (void)++__ifirst, (void)--__n)
::new (__detail::__voidify(*__ofirst)) _OutType(*__ifirst);
__guard.release();
- return {__ifirst, __ofirst};
+ return {std::move(__ifirst), __ofirst};
}
}
};
&& is_nothrow_assignable_v<_OutType&,
iter_rvalue_reference_t<_Iter>>)
{
- auto __d1 = ranges::distance(__ifirst, __ilast);
- auto __d2 = ranges::distance(__ofirst, __olast);
+ auto __d1 = __ilast - __ifirst;
+ auto __d2 = __olast - __ofirst;
auto [__in, __out]
- = ranges::copy_n(std::make_move_iterator(__ifirst),
+ = ranges::copy_n(std::make_move_iterator(std::move(__ifirst)),
std::min(__d1, __d2), __ofirst);
return {std::move(__in).base(), __out};
}
::new (__detail::__voidify(*__ofirst))
_OutType(ranges::iter_move(__ifirst));
__guard.release();
- return {__ifirst, __ofirst};
+ return {std::move(__ifirst), __ofirst};
}
}
&& is_nothrow_assignable_v<_OutType&,
iter_rvalue_reference_t<_Iter>>)
{
- auto __d = ranges::distance(__ofirst, __olast);
+ auto __d = __olast - __ofirst;
auto [__in, __out]
- = ranges::copy_n(std::make_move_iterator(__ifirst),
+ = ranges::copy_n(std::make_move_iterator(std::move(__ifirst)),
std::min(__n, __d), __ofirst);
return {std::move(__in).base(), __out};
}
::new (__detail::__voidify(*__ofirst))
_OutType(ranges::iter_move(__ifirst));
__guard.release();
- return {__ifirst, __ofirst};
+ return {std::move(__ifirst), __ofirst};
}
}
};
__destroy_fn::operator()(_Iter __first, _Sent __last) const noexcept
{
if constexpr (is_trivially_destructible_v<iter_value_t<_Iter>>)
- return ranges::next(__first, __last);
+ return ranges::next(std::move(__first), __last);
else
{
for (; __first != __last; ++__first)
operator()(_Iter __first, iter_difference_t<_Iter> __n) const noexcept
{
if constexpr (is_trivially_destructible_v<iter_value_t<_Iter>>)
- return ranges::next(__first, __n);
+ return ranges::next(std::move(__first), __n);
else
{
for (; __n > 0; ++__first, (void)--__n)