diff --git a/libcxx/test/std/containers/sequences/vector.bool/copy.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/copy.pass.cpp index 15b26e8054df8..ba957471927c3 100644 --- a/libcxx/test/std/containers/sequences/vector.bool/copy.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/copy.pass.cpp @@ -11,12 +11,13 @@ // vector(const vector& v); -#include +#include #include +#include -#include "test_macros.h" -#include "test_allocator.h" #include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" template TEST_CONSTEXPR_CXX20 void test(const C& x) { @@ -25,39 +26,56 @@ TEST_CONSTEXPR_CXX20 void test(const C& x) { LIBCPP_ASSERT(c.__invariants()); assert(c.size() == s); assert(c == x); +#if TEST_STD_VER >= 11 + assert(c.get_allocator() == + std::allocator_traits::select_on_container_copy_construction(x.get_allocator())); +#endif } TEST_CONSTEXPR_CXX20 bool tests() { - { - bool a[] = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0}; - bool* an = a + sizeof(a) / sizeof(a[0]); - test(std::vector(a, an)); - } - { - std::vector > v(3, true, test_allocator(5)); - std::vector > v2 = v; - assert(v2 == v); - assert(v2.get_allocator() == v.get_allocator()); + std::array a1 = {1, 0, 1, 0, 1}; + std::array a2 = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0}; + std::array a3 = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0}; + std::array a4 = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0}; + std::array a5 = {}; + for (unsigned i = 0; i < a5.size(); i += 2) + a5[i] = 1; + + // Tests for vector copy constructor with word size up to 5 (i.e., bit size > 256 on a 64-bit system) + { // Test with default std::allocator + test(std::vector(a1.begin(), a1.end())); + test(std::vector(a2.begin(), a2.end())); + test(std::vector(a3.begin(), a3.end())); + test(std::vector(a4.begin(), a4.end())); + test(std::vector(a5.begin(), a5.end())); } -#if TEST_STD_VER >= 11 - { - std::vector > v(3, true, other_allocator(5)); - std::vector > v2 = v; - assert(v2 == v); - assert(v2.get_allocator() == other_allocator(-2)); + { // Test with test_allocator + using A = test_allocator; + using C = std::vector; + test(C(a1.begin(), a1.end())); + test(C(a2.begin(), a2.end())); + test(C(a3.begin(), a3.end())); + test(C(a4.begin(), a4.end())); + test(C(a5.begin(), a5.end())); } - { - bool a[] = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0}; - bool* an = a + sizeof(a) / sizeof(a[0]); - test(std::vector>(a, an)); + { // Test with other_allocator + using A = other_allocator; + using C = std::vector; + test(C(a1.begin(), a1.end())); + test(C(a2.begin(), a2.end())); + test(C(a3.begin(), a3.end())); + test(C(a4.begin(), a4.end())); + test(C(a5.begin(), a5.end())); } - { - std::vector > v(3, true, min_allocator()); - std::vector > v2 = v; - assert(v2 == v); - assert(v2.get_allocator() == v.get_allocator()); + { // Test with min_allocator + using A = min_allocator; + using C = std::vector; + test(C(a1.begin(), a1.end())); + test(C(a2.begin(), a2.end())); + test(C(a3.begin(), a3.end())); + test(C(a4.begin(), a4.end())); + test(C(a5.begin(), a5.end())); } -#endif return true; } diff --git a/libcxx/test/std/containers/sequences/vector.bool/copy_alloc.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/copy_alloc.pass.cpp index d22b7c5d58447..17967ff2713cd 100644 --- a/libcxx/test/std/containers/sequences/vector.bool/copy_alloc.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/copy_alloc.pass.cpp @@ -7,15 +7,17 @@ //===----------------------------------------------------------------------===// // +// vector // vector(const vector& v, const allocator_type& a); -#include +#include #include +#include -#include "test_macros.h" -#include "test_allocator.h" #include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" template TEST_CONSTEXPR_CXX20 void test(const C& x, const typename C::allocator_type& a) { @@ -24,39 +26,53 @@ TEST_CONSTEXPR_CXX20 void test(const C& x, const typename C::allocator_type& a) LIBCPP_ASSERT(c.__invariants()); assert(c.size() == s); assert(c == x); + assert(c.get_allocator() == a); } TEST_CONSTEXPR_CXX20 bool tests() { - { - bool a[] = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0}; - bool* an = a + sizeof(a) / sizeof(a[0]); - test(std::vector(a, an), std::allocator()); - } - { - std::vector > l(3, true, test_allocator(5)); - std::vector > l2(l, test_allocator(3)); - assert(l2 == l); - assert(l2.get_allocator() == test_allocator(3)); + std::array a1 = {1, 0, 1, 0, 1}; + std::array a2 = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0}; + std::array a3 = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0}; + std::array a4 = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0}; + std::array a5 = {}; + for (unsigned i = 0; i < a5.size(); i += 2) + a5[i] = 1; + + // Tests for allocator-extended copy constructor with word size up to 5 (i.e., bit size > 256 on a 64-bit system) + { // Test with the default std::allocator + test(std::vector(a1.begin(), a1.end()), std::allocator()); + test(std::vector(a2.begin(), a2.end()), std::allocator()); + test(std::vector(a3.begin(), a3.end()), std::allocator()); + test(std::vector(a4.begin(), a4.end()), std::allocator()); + test(std::vector(a5.begin(), a5.end()), std::allocator()); } - { - std::vector > l(3, true, other_allocator(5)); - std::vector > l2(l, other_allocator(3)); - assert(l2 == l); - assert(l2.get_allocator() == other_allocator(3)); + { // Test with test_allocator + using A = test_allocator; + using C = std::vector; + test(C(a1.begin(), a1.end(), A(5)), A(3)); + test(C(a2.begin(), a2.end(), A(5)), A(3)); + test(C(a3.begin(), a3.end(), A(5)), A(3)); + test(C(a4.begin(), a4.end(), A(5)), A(3)); + test(C(a5.begin(), a5.end(), A(5)), A(3)); } -#if TEST_STD_VER >= 11 - { - bool a[] = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0}; - bool* an = a + sizeof(a) / sizeof(a[0]); - test(std::vector>(a, an), min_allocator()); + { // Test with other_allocator + using A = other_allocator; + using C = std::vector; + test(C(a1.begin(), a1.end(), A(5)), A(3)); + test(C(a2.begin(), a2.end(), A(5)), A(3)); + test(C(a3.begin(), a3.end(), A(5)), A(3)); + test(C(a4.begin(), a4.end(), A(5)), A(3)); + test(C(a5.begin(), a5.end(), A(5)), A(3)); } - { - std::vector > l(3, true, min_allocator()); - std::vector > l2(l, min_allocator()); - assert(l2 == l); - assert(l2.get_allocator() == min_allocator()); + { // Test with min_allocator + using A = min_allocator; + using C = std::vector; + test(C(a1.begin(), a1.end(), A()), A()); + test(C(a2.begin(), a2.end(), A()), A()); + test(C(a3.begin(), a3.end(), A()), A()); + test(C(a4.begin(), a4.end(), A()), A()); + test(C(a5.begin(), a5.end(), A()), A()); } -#endif return true; } diff --git a/libcxx/test/std/containers/sequences/vector.bool/move.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/move.pass.cpp index a69f0b5738986..d1217ddbca89d 100644 --- a/libcxx/test/std/containers/sequences/vector.bool/move.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/move.pass.cpp @@ -9,54 +9,70 @@ // UNSUPPORTED: c++03 // +// vector // vector(vector&& c); -#include +#include #include -#include "test_macros.h" -#include "test_allocator.h" +#include + #include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" + +template +TEST_CONSTEXPR_CXX20 void test(const A& a) { + std::vector v(N, false, a); + std::vector original(N, false, a); + for (unsigned i = 1; i < N; i += 2) { + v[i] = true; + original[i] = true; + } + std::vector v2 = std::move(v); + assert(v2 == original); + assert(v.empty()); // The moved-from vector is guaranteed to be empty after move-construction + assert(v2.get_allocator() == original.get_allocator()); +} TEST_CONSTEXPR_CXX20 bool tests() { test_allocator_statistics alloc_stats; + + // Tests for move constructor with word size up to 5 (i.e., bit size > 256 for 64-bit system) { - std::vector > l(test_allocator(5, &alloc_stats)); - std::vector > lo(test_allocator(5, &alloc_stats)); - for (int i = 1; i <= 3; ++i) { - l.push_back(true); - lo.push_back(true); - } - std::vector > l2 = std::move(l); - assert(l2 == lo); - assert(l.empty()); - assert(l2.get_allocator() == lo.get_allocator()); + using A = std::allocator; + test<5>(A()); + test<18>(A()); + test<33>(A()); + test<65>(A()); + test<299>(A()); } { - std::vector > l(other_allocator(5)); - std::vector > lo(other_allocator(5)); - for (int i = 1; i <= 3; ++i) { - l.push_back(true); - lo.push_back(true); - } - std::vector > l2 = std::move(l); - assert(l2 == lo); - assert(l.empty()); - assert(l2.get_allocator() == lo.get_allocator()); + using A = other_allocator; + test<5>(A(5)); + test<18>(A(5)); + test<33>(A(5)); + test<65>(A(5)); + test<299>(A(5)); } { - std::vector > l(min_allocator{}); - std::vector > lo(min_allocator{}); - for (int i = 1; i <= 3; ++i) { - l.push_back(true); - lo.push_back(true); - } - std::vector > l2 = std::move(l); - assert(l2 == lo); - assert(l.empty()); - assert(l2.get_allocator() == lo.get_allocator()); + using A = min_allocator; + test<5>(A()); + test<18>(A()); + test<33>(A()); + test<65>(A()); + test<299>(A()); } { + using A = test_allocator; + test<5>(A(5, &alloc_stats)); + test<18>(A(5, &alloc_stats)); + test<33>(A(5, &alloc_stats)); + test<65>(A(5, &alloc_stats)); + test<299>(A(5, &alloc_stats)); + } + + { // Tests to verify the allocator statistics after move alloc_stats.clear(); using Vect = std::vector >; using AllocT = Vect::allocator_type; @@ -83,7 +99,6 @@ TEST_CONSTEXPR_CXX20 bool tests() { const AllocT& a2 = v2.get_allocator(); assert(a2.get_id() == 101); assert(a2.get_data() == 42); - assert(a1 == a2); } } diff --git a/libcxx/test/std/containers/sequences/vector.bool/move_alloc.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/move_alloc.pass.cpp index 01e7410040686..a6f28eb2f9f35 100644 --- a/libcxx/test/std/containers/sequences/vector.bool/move_alloc.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/move_alloc.pass.cpp @@ -9,63 +9,79 @@ // UNSUPPORTED: c++03 // +// vector // vector(vector&& c, const allocator_type& a); -#include +#include #include -#include "test_macros.h" -#include "test_allocator.h" +#include + #include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" + +template +TEST_CONSTEXPR_CXX20 void test(const A& a, const A& a0) { + std::vector v(N, false, a); + std::vector original(N, false, a0); + for (unsigned i = 1; i < N; i += 2) { + v[i] = true; + original[i] = true; + } + std::vector v2(std::move(v), a0); + assert(v2 == original); + assert(v2.get_allocator() == a0); + if (a == a0) + assert(v.empty()); // After container-move, the vector is guaranteed to be empty + else + LIBCPP_ASSERT(!v.empty()); // After element-wise move, the RHS vector is not necessarily empty +} 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(std::move(l), test_allocator(6)); - assert(l2 == lo); - assert(!l.empty()); - assert(l2.get_allocator() == test_allocator(6)); + { // Test with default allocator: compatible allocators + using A = std::allocator; + test<5>(A(), A()); + test<17>(A(), A()); + test<65>(A(), A()); + test<299>(A(), A()); } - { - 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(std::move(l), test_allocator(5)); - assert(l2 == lo); - assert(l.empty()); - assert(l2.get_allocator() == test_allocator(5)); + { // Test with test_allocator: compatible and incompatible allocators + using A = test_allocator; + + // Compatible allocators + test<5>(A(5), A(5)); + test<17>(A(5), A(5)); + test<65>(A(5), A(5)); + test<299>(A(5), A(5)); + + // Incompatible allocators + test<5>(A(5), A(6)); + test<17>(A(5), A(6)); + test<65>(A(5), A(6)); + test<299>(A(5), A(6)); } - { - 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(std::move(l), other_allocator(4)); - assert(l2 == lo); - assert(!l.empty()); - assert(l2.get_allocator() == other_allocator(4)); + { // Test with other_allocator: compatible and incompatible allocators + using A = other_allocator; + + // Compatible allocators + test<5>(A(5), A(5)); + test<17>(A(5), A(5)); + test<65>(A(5), A(5)); + test<299>(A(5), A(5)); + + // Incompatible allocators + test<5>(A(5), A(3)); + test<17>(A(5), A(3)); + test<65>(A(5), A(3)); + test<299>(A(5), A(3)); } - { - 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(std::move(l), min_allocator()); - assert(l2 == lo); - assert(l.empty()); - assert(l2.get_allocator() == min_allocator()); + { // Test with min_allocator: compatible allocators + using A = min_allocator; + test<5>(A(), A()); + test<17>(A(), A()); + test<65>(A(), A()); + test<299>(A(), A()); } return true;