diff options
author | Louis Dionne <ldionne.2@gmail.com> | 2023-07-06 10:27:54 -0400 |
---|---|---|
committer | Louis Dionne <ldionne.2@gmail.com> | 2023-07-10 11:50:09 -0400 |
commit | 6f36ead577dfa20397549b7034330180da0945f0 (patch) | |
tree | fcefb2f1cd37e600b2fc3f6dd2541265b0a1edd2 /libcxx/test/std/algorithms/alg.modifying.operations | |
parent | b454e7aa7ceb35a0070406ebd7ffdf1ed85f5ef8 (diff) | |
download | llvm-6f36ead577dfa20397549b7034330180da0945f0.zip llvm-6f36ead577dfa20397549b7034330180da0945f0.tar.gz llvm-6f36ead577dfa20397549b7034330180da0945f0.tar.bz2 |
[libc++] Fix std::move algorithm with trivial move-only types
As reported in https://reviews.llvm.org/D151953#4472195, the std::move
algorithm (and various other functions that relied on it) stopped working
after starting to use `__constexpr_memmove` in its implementation. This
patch fixes the underlying issue in `__constexpr_memmove` and adds tests
for various related algorithms and functions that were not exercising
trivial move-only types.
Differential Revision: https://reviews.llvm.org/D154613
Diffstat (limited to 'libcxx/test/std/algorithms/alg.modifying.operations')
4 files changed, 91 insertions, 4 deletions
diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp index 3795314..ce5cf05 100644 --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move.pass.cpp @@ -18,10 +18,12 @@ #include <algorithm> #include <cassert> +#include <iterator> #include <memory> -#include "test_macros.h" +#include "MoveOnly.h" #include "test_iterators.h" +#include "test_macros.h" class PaddedBase { public: @@ -111,11 +113,32 @@ TEST_CONSTEXPR_CXX20 bool test() { assert(std::equal(a, a + 10, expected)); } + // Make sure that the algorithm works with move-only types + { + // When non-trivial + { + MoveOnly from[3] = {1, 2, 3}; + MoveOnly to[3] = {}; + std::move(std::begin(from), std::end(from), std::begin(to)); + assert(to[0] == MoveOnly(1)); + assert(to[1] == MoveOnly(2)); + assert(to[2] == MoveOnly(3)); + } + // When trivial + { + TrivialMoveOnly from[3] = {1, 2, 3}; + TrivialMoveOnly to[3] = {}; + std::move(std::begin(from), std::end(from), std::begin(to)); + assert(to[0] == TrivialMoveOnly(1)); + assert(to[1] == TrivialMoveOnly(2)); + assert(to[2] == TrivialMoveOnly(3)); + } + } + return true; } -int main(int, char**) -{ +int main(int, char**) { test(); #if TEST_STD_VER >= 20 static_assert(test()); diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move_backward.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move_backward.pass.cpp index 04ecd48..2ed4d37 100644 --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move_backward.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/move_backward.pass.cpp @@ -17,10 +17,12 @@ #include <algorithm> #include <cassert> +#include <iterator> #include <memory> -#include "test_macros.h" +#include "MoveOnly.h" #include "test_iterators.h" +#include "test_macros.h" class PaddedBase { public: @@ -110,6 +112,28 @@ TEST_CONSTEXPR_CXX20 bool test() { assert(std::equal(a, a + 10, expected)); } + // Make sure that the algorithm works with move-only types + { + // When non-trivial + { + MoveOnly from[3] = {1, 2, 3}; + MoveOnly to[3] = {}; + std::move_backward(std::begin(from), std::end(from), std::end(to)); + assert(to[0] == MoveOnly(1)); + assert(to[1] == MoveOnly(2)); + assert(to[2] == MoveOnly(3)); + } + // When trivial + { + TrivialMoveOnly from[3] = {1, 2, 3}; + TrivialMoveOnly to[3] = {}; + std::move_backward(std::begin(from), std::end(from), std::end(to)); + assert(to[0] == TrivialMoveOnly(1)); + assert(to[1] == TrivialMoveOnly(2)); + assert(to[2] == TrivialMoveOnly(3)); + } + } + return true; } diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move.pass.cpp index d98c319..aeff581 100644 --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move.pass.cpp @@ -24,6 +24,7 @@ #include <array> #include <cassert> #include <deque> +#include <iterator> #include <ranges> #include <vector> @@ -203,6 +204,7 @@ constexpr bool test() { test_proxy_in_iterators<ProxyIterator>(); { // check that a move-only type works + // When non-trivial { MoveOnly a[] = {1, 2, 3}; MoveOnly b[3]; @@ -219,6 +221,24 @@ constexpr bool test() { assert(b[1].get() == 2); assert(b[2].get() == 3); } + + // When trivial + { + TrivialMoveOnly a[] = {1, 2, 3}; + TrivialMoveOnly b[3]; + std::ranges::move(a, std::begin(b)); + assert(b[0].get() == 1); + assert(b[1].get() == 2); + assert(b[2].get() == 3); + } + { + TrivialMoveOnly a[] = {1, 2, 3}; + TrivialMoveOnly b[3]; + std::ranges::move(std::begin(a), std::end(a), std::begin(b)); + assert(b[0].get() == 1); + assert(b[1].get() == 2); + assert(b[2].get() == 3); + } } { // check that a move-only type works for ProxyIterator diff --git a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.pass.cpp b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.pass.cpp index f6ca42b..9219cbb 100644 --- a/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.pass.cpp +++ b/libcxx/test/std/algorithms/alg.modifying.operations/alg.move/ranges.move_backward.pass.cpp @@ -24,6 +24,7 @@ #include <array> #include <cassert> #include <deque> +#include <iterator> #include <ranges> #include <vector> @@ -189,6 +190,7 @@ constexpr bool test() { test_proxy_in_iterators<ProxyIterator>(); { // check that a move-only type works + // When non-trivial { MoveOnly a[] = {1, 2, 3}; MoveOnly b[3]; @@ -205,6 +207,24 @@ constexpr bool test() { assert(b[1].get() == 2); assert(b[2].get() == 3); } + + // When trivial + { + TrivialMoveOnly a[] = {1, 2, 3}; + TrivialMoveOnly b[3]; + std::ranges::move_backward(a, std::end(b)); + assert(b[0].get() == 1); + assert(b[1].get() == 2); + assert(b[2].get() == 3); + } + { + TrivialMoveOnly a[] = {1, 2, 3}; + TrivialMoveOnly b[3]; + std::ranges::move_backward(std::begin(a), std::end(a), std::end(b)); + assert(b[0].get() == 1); + assert(b[1].get() == 2); + assert(b[2].get() == 3); + } } { // check that a move-only type works for ProxyIterator |