From ba10fb435e4f0e462b7c9a9ace1278bd4c5950b3 Mon Sep 17 00:00:00 2001 From: Peng Liu Date: Fri, 14 Mar 2025 14:50:23 -0400 Subject: [PATCH] Enhance tests for copy/move-assignment operators --- .../vector.bool/assign_copy.pass.cpp | 64 ++++++++--- .../vector.bool/assign_move.pass.cpp | 103 +++++++++++------- 2 files changed, 108 insertions(+), 59 deletions(-) diff --git a/libcxx/test/std/containers/sequences/vector.bool/assign_copy.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/assign_copy.pass.cpp index 2144478601897..7bf8bdb9c6993 100644 --- a/libcxx/test/std/containers/sequences/vector.bool/assign_copy.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/assign_copy.pass.cpp @@ -7,39 +7,69 @@ //===----------------------------------------------------------------------===// // +// vector // vector& operator=(const vector& c); -#include #include -#include "test_macros.h" -#include "test_allocator.h" +#include + #include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" -TEST_CONSTEXPR_CXX20 bool tests() { - { - std::vector > l(3, true, test_allocator(5)); - std::vector > l2(l, test_allocator(3)); +TEST_CONSTEXPR_CXX20 void test_copy_assignment(unsigned N) { + // + // Test with insufficient space where reallocation occurs during assignment + // + { // POCCA = true_type, thus copy-assign the allocator + std::vector > l(N, true, other_allocator(5)); + std::vector > l2(other_allocator(3)); l2 = l; assert(l2 == l); - assert(l2.get_allocator() == test_allocator(3)); + assert(l2.get_allocator() == other_allocator(5)); } - { - std::vector > l(3, true, other_allocator(5)); - std::vector > l2(l, other_allocator(3)); + { // POCCA = false_type, thus allocator is unchanged + std::vector > l(N + 64, true, test_allocator(5)); + std::vector > l2(10, false, test_allocator(3)); l2 = l; assert(l2 == l); - assert(l2.get_allocator() == other_allocator(5)); + assert(l2.get_allocator() == test_allocator(3)); } -#if TEST_STD_VER >= 11 - { - std::vector > l(3, true, min_allocator()); - std::vector > l2(l, min_allocator()); + { // Stateless allocator + std::vector > l(N + 64, true, min_allocator()); + std::vector > l2(N / 2, false, min_allocator()); l2 = l; assert(l2 == l); assert(l2.get_allocator() == min_allocator()); } -#endif + + // + // Test with sufficient size where no reallocation occurs during assignment + // + { // POCCA = false_type, thus allocator is unchanged + std::vector > l(N, true, test_allocator(5)); + std::vector > l2(N + 64, false, test_allocator(3)); + l2 = l; + assert(l2 == l); + assert(l2.get_allocator() == test_allocator(3)); + } + { // POCCA = true_type, thus copy-assign the allocator + std::vector > l(N, true, other_allocator(5)); + std::vector > l2(N * 2, false, other_allocator(3)); + l2.reserve(5); + l2 = l; + assert(l2 == l); + assert(l2.get_allocator() == other_allocator(5)); + } +} + +TEST_CONSTEXPR_CXX20 bool tests() { + test_copy_assignment(3); + test_copy_assignment(18); + test_copy_assignment(33); + test_copy_assignment(65); + test_copy_assignment(299); return true; } diff --git a/libcxx/test/std/containers/sequences/vector.bool/assign_move.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/assign_move.pass.cpp index 48ef5e3a8c262..8791380b134c7 100644 --- a/libcxx/test/std/containers/sequences/vector.bool/assign_move.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/assign_move.pass.cpp @@ -9,68 +9,87 @@ // UNSUPPORTED: c++03 // +// vector // vector& operator=(vector&& c); -#include #include -#include "test_macros.h" -#include "test_allocator.h" +#include + #include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" -TEST_CONSTEXPR_CXX20 bool tests() { - { - std::vector > l(test_allocator(5)); - std::vector > lo(test_allocator(5)); - for (int i = 1; i <= 3; ++i) { - l.push_back(i); - lo.push_back(i); - } - std::vector > l2(test_allocator(5)); +TEST_CONSTEXPR_CXX20 void test_move_assignment(unsigned N) { + // + // Testing for container move where either POCMA = true_type or the allocators compare equal + // + { // Test with POCMA = true_type + std::vector > l(N, true, other_allocator(5)); + std::vector > lo(N, true, other_allocator(5)); + std::vector > l2(N + 10, false, other_allocator(42)); l2 = std::move(l); assert(l2 == lo); - LIBCPP_ASSERT(l.empty()); + LIBCPP_ASSERT(l.empty()); // After move, source vector is in a vliad but unspecified state. libc++ leaves it empty. assert(l2.get_allocator() == lo.get_allocator()); } - { - std::vector > l(test_allocator(5)); - std::vector > lo(test_allocator(5)); - for (int i = 1; i <= 3; ++i) { - l.push_back(i); - lo.push_back(i); - } - std::vector > l2(test_allocator(6)); + { // Test with POCMA = false_type and allocators compare equal + std::vector > l(N, true, test_allocator(5)); + std::vector > lo(N, true, test_allocator(5)); + std::vector > l2(N + 10, false, test_allocator(5)); l2 = std::move(l); assert(l2 == lo); - assert(!l.empty()); - assert(l2.get_allocator() == test_allocator(6)); + LIBCPP_ASSERT(l.empty()); + assert(l2.get_allocator() == lo.get_allocator()); } - { - std::vector > l(other_allocator(5)); - std::vector > lo(other_allocator(5)); - for (int i = 1; i <= 3; ++i) { - l.push_back(i); - lo.push_back(i); - } - std::vector > l2(other_allocator(6)); + { // Test with POCMA = false_type and allocators compare equal + std::vector > l(N, true, min_allocator{}); + std::vector > lo(N, true, min_allocator{}); + std::vector > l2(N + 10, false, min_allocator{}); l2 = std::move(l); assert(l2 == lo); - assert(l.empty()); + LIBCPP_ASSERT(l.empty()); assert(l2.get_allocator() == lo.get_allocator()); } - { - std::vector > l(min_allocator{}); - std::vector > lo(min_allocator{}); - for (int i = 1; i <= 3; ++i) { - l.push_back(i); - lo.push_back(i); - } - std::vector > l2(min_allocator{}); + + // + // Testing for element-wise move where POCMA = false_type and allocators compare unequal + // + { // Test with reallocation during the element-wise move due to empty destination vector. + std::vector > l(N, true, test_allocator(5)); + std::vector > lo(N, true, test_allocator(5)); + std::vector > l2(test_allocator(42)); l2 = std::move(l); assert(l2 == lo); - assert(l.empty()); - assert(l2.get_allocator() == lo.get_allocator()); + LIBCPP_ASSERT(!l.empty()); + assert(l2.get_allocator() == test_allocator(42)); + } + { // Test with reallocation occurs during the element-wise move due to insufficient destination space. + std::vector > l(N + 64, true, test_allocator(5)); + std::vector > lo(N + 64, true, test_allocator(5)); + std::vector > l2(10, false, test_allocator(42)); + l2 = std::move(l); + assert(l2 == lo); + LIBCPP_ASSERT(!l.empty()); + assert(l2.get_allocator() == test_allocator(42)); } + { // Test without reallocation where source vector elements fit within destination size. + std::vector > l(N, true, test_allocator(5)); + std::vector > lo(N, true, test_allocator(5)); + std::vector > l2(N * 2, false, test_allocator(42)); + l2 = std::move(l); + assert(l2 == lo); + LIBCPP_ASSERT(!l.empty()); + assert(l2.get_allocator() == test_allocator(42)); + } +} + +TEST_CONSTEXPR_CXX20 bool tests() { + test_move_assignment(3); + test_move_assignment(18); + test_move_assignment(33); + test_move_assignment(65); + test_move_assignment(299); return true; }