From dff3eba75cc379745e1ca5ea9b54648c677f7a7a Mon Sep 17 00:00:00 2001 From: Nikolas Klauser Date: Tue, 3 Jan 2023 21:51:31 +0100 Subject: [PATCH] [libc++] Fix ranges::uninitialized_move{, _n} for move-only types Fixes #59806 Reviewed By: ldionne, var-const, #libc Spies: libcxx-commits Differential Revision: https://reviews.llvm.org/D140920 --- .../include/__memory/ranges_uninitialized_algorithms.h | 6 +++--- .../ranges_uninitialized_move.pass.cpp | 18 ++++++++++++++++++ .../ranges_uninitialized_move_n.pass.cpp | 12 ++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/libcxx/include/__memory/ranges_uninitialized_algorithms.h b/libcxx/include/__memory/ranges_uninitialized_algorithms.h index 07abdc9..15c78e2 100644 --- a/libcxx/include/__memory/ranges_uninitialized_algorithms.h +++ b/libcxx/include/__memory/ranges_uninitialized_algorithms.h @@ -256,7 +256,7 @@ struct __fn { sentinel_for<_InputIterator> _Sentinel1, __nothrow_forward_iterator _OutputIterator, __nothrow_sentinel_for<_OutputIterator> _Sentinel2> - requires constructible_from, iter_reference_t<_InputIterator>> + requires constructible_from, iter_rvalue_reference_t<_InputIterator>> uninitialized_move_result<_InputIterator, _OutputIterator> operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const { using _ValueType = remove_reference_t>; @@ -267,7 +267,7 @@ struct __fn { } template - requires constructible_from, range_reference_t<_InputRange>> + requires constructible_from, range_rvalue_reference_t<_InputRange>> uninitialized_move_result, borrowed_iterator_t<_OutputRange>> operator()(_InputRange&& __in_range, _OutputRange&& __out_range) const { return (*this)(ranges::begin(__in_range), ranges::end(__in_range), @@ -292,7 +292,7 @@ struct __fn { template _Sentinel> - requires constructible_from, iter_reference_t<_InputIterator>> + requires constructible_from, iter_rvalue_reference_t<_InputIterator>> uninitialized_move_n_result<_InputIterator, _OutputIterator> operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n, _OutputIterator __ofirst, _Sentinel __olast) const { diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move.pass.cpp index aa53d1a..57be8c4 100644 --- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move.pass.cpp +++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move.pass.cpp @@ -17,6 +17,7 @@ #include +#include #include #include #include @@ -26,6 +27,7 @@ #include "../buffer.h" #include "../counted.h" +#include "MoveOnly.h" #include "test_macros.h" #include "test_iterators.h" @@ -417,5 +419,21 @@ int main(int, char**) { } } + // MoveOnly types are supported + { + { + MoveOnly a[] = {1, 2, 3, 4}; + Buffer out; + std::ranges::uninitialized_move(std::begin(a), std::end(a), std::begin(out), std::end(out)); + assert(std::ranges::equal(out, std::array{1, 2, 3, 4})); + } + { + MoveOnly a[] = {1, 2, 3, 4}; + Buffer out; + std::ranges::uninitialized_move(a, out); + assert(std::ranges::equal(out, std::array{1, 2, 3, 4})); + } + } + return 0; } diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move_n.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move_n.pass.cpp index 012136e..09bdcf4 100644 --- a/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move_n.pass.cpp +++ b/libcxx/test/std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move_n.pass.cpp @@ -15,6 +15,7 @@ // uninitialized_copy_n_result uninitialized_copy_n(I ifirst, iter_difference_t n, O ofirst, S olast); // since C++20 #include +#include #include #include #include @@ -23,6 +24,7 @@ #include "../buffer.h" #include "../counted.h" +#include "MoveOnly.h" #include "test_iterators.h" #include "test_macros.h" @@ -179,5 +181,15 @@ int main(int, char**) { std::ranges::uninitialized_move_n(std::move(in), N, out.begin(), out.end()); } + // MoveOnly types are supported + { + { + MoveOnly a[] = {1, 2, 3, 4}; + Buffer out; + std::ranges::uninitialized_move_n(std::begin(a), std::size(a), std::begin(out), std::end(out)); + assert(std::ranges::equal(out, std::array{1, 2, 3, 4})); + } + } + return 0; } -- 2.7.4