diff --git a/libcxx/test/std/containers/sequences/vector.bool/assign_iter_iter.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/assign_iter_iter.pass.cpp new file mode 100644 index 0000000000000..91788b3707592 --- /dev/null +++ b/libcxx/test/std/containers/sequences/vector.bool/assign_iter_iter.pass.cpp @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template +// constexpr void assign(InputIt first, InputIt last); + +#include +#include +#include "test_macros.h" +#include "test_iterators.h" + +TEST_CONSTEXPR_CXX20 bool tests() { + { // Test with various cases where assign may or may not trigger reallocations for forward_iterator + { // Reallocation happens + std::vector in(128, true); + std::vector v(5, false); + assert(v.capacity() < in.size()); + using It = forward_iterator::iterator>; + v.assign(It(in.begin()), It(in.end())); + assert(v == in); + } + { // No reallocation: fit within current size + bool in[] = {false, true, false, true, true}; + std::size_t N = sizeof(in) / sizeof(in[0]); + std::vector v(2 * N, false); + using It = forward_iterator; + v.assign(It(in), It(in + N)); + assert(v.size() == N); + for (std::size_t i = 0; i < N; ++i) + assert(v[i] == in[i]); + } + { // No reallocation: fit within spare space + bool in[] = {false, true, false, true, true}; + std::size_t N = sizeof(in) / sizeof(in[0]); + std::vector v(N / 2, false); + v.reserve(N * 2); + using It = forward_iterator; + v.assign(It(in), It(in + N)); + assert(v.size() == N); + for (std::size_t i = 0; i < N; ++i) + assert(v[i] == in[i]); + } + } + + { // Test with various cases where assign may or may not trigger reallocations for input_iterator + { // Reallocation happens + std::vector in(128, true); + std::vector v(5, false); + assert(v.capacity() < in.size()); + using It = cpp17_input_iterator::iterator>; + v.assign(It(in.begin()), It(in.end())); + assert(v == in); + } + { // No reallocation: fit within current size + bool in[] = {false, true, false, true, true}; + std::size_t N = sizeof(in) / sizeof(in[0]); + std::vector v(2 * N, false); + using It = cpp17_input_iterator; + v.assign(It(in), It(in + N)); + assert(v.size() == N); + for (std::size_t i = 0; i < N; ++i) + assert(v[i] == in[i]); + } + { // No reallocation: fit within spare space + bool in[] = {false, true, false, true, true}; + std::size_t N = sizeof(in) / sizeof(in[0]); + std::vector v(N / 2, false); + v.reserve(N * 2); + using It = cpp17_input_iterator; + v.assign(It(in), It(in + N)); + assert(v.size() == N); + for (std::size_t i = 0; i < N; ++i) + assert(v[i] == in[i]); + } + } + + return true; +} + +int main(int, char**) { + tests(); +#if TEST_STD_VER > 17 + static_assert(tests()); +#endif + return 0; +} diff --git a/libcxx/test/std/containers/sequences/vector.bool/assign_size_value.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/assign_size_value.pass.cpp new file mode 100644 index 0000000000000..d2513bb84c806 --- /dev/null +++ b/libcxx/test/std/containers/sequences/vector.bool/assign_size_value.pass.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// void assign(size_type n, const value_type& x); + +#include +#include +#include "test_macros.h" +#include "test_iterators.h" + +TEST_CONSTEXPR_CXX20 bool tests() { + { // Test with various cases where assign may or may not trigger reallocations + { // Reallocation happens + std::size_t N = 128; + std::vector v(5, false); + assert(v.capacity() < N); + v.assign(N, true); + assert(v.size() == N); + for (std::size_t i = 0; i < N; ++i) + assert(v[i] == true); + } + { // No reallocation: fit within current size + std::size_t N = 5; + std::vector v(2 * N, false); + v.assign(N, true); + assert(v.size() == N); + for (std::size_t i = 0; i < N; ++i) + assert(v[i] == true); + } + { // No reallocation: fit within spare space + std::size_t N = 5; + std::vector v(N / 2, false); + v.reserve(N * 2); + v.assign(N, true); + assert(v.size() == N); + for (std::size_t i = 0; i < N; ++i) + assert(v[i] == true); + } + } + + return true; +} + +int main(int, char**) { + tests(); +#if TEST_STD_VER > 17 + static_assert(tests()); +#endif + return 0; +} diff --git a/libcxx/test/std/containers/sequences/vector/vector.cons/assign_iter_iter.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.cons/assign_iter_iter.pass.cpp index b6aeba4e4eef3..91060679cd7f9 100644 --- a/libcxx/test/std/containers/sequences/vector/vector.cons/assign_iter_iter.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector/vector.cons/assign_iter_iter.pass.cpp @@ -19,17 +19,16 @@ #include "asan_testing.h" #include "test_iterators.h" #if TEST_STD_VER >= 11 -#include "emplace_constructible.h" -#include "container_test_types.h" +# include "emplace_constructible.h" +# include "container_test_types.h" #endif - TEST_CONSTEXPR_CXX20 bool test() { #if TEST_STD_VER >= 11 int arr1[] = {42}; int arr2[] = {1, 101, 42}; - { - using T = EmplaceConstructibleMoveableAndAssignable; + { // Test with new_size > capacity() == 0 for forward_iterator, resulting in reallocation during assign + using T = EmplaceConstructibleMoveableAndAssignable; using It = forward_iterator; { std::vector v; @@ -44,8 +43,8 @@ TEST_CONSTEXPR_CXX20 bool test() { assert(v[2].value == 42); } } - { - using T = EmplaceConstructibleMoveableAndAssignable; + { // Test with new_size > capacity() == 0 for input_iterator, resulting in reallocation during assign + using T = EmplaceConstructibleMoveableAndAssignable; using It = cpp17_input_iterator; { std::vector v; @@ -64,6 +63,100 @@ TEST_CONSTEXPR_CXX20 bool test() { assert(v[2].value == 42); } } + + { // Test with new_size < size() for forward_iterator, resulting in destruction at end during assign + using T = EmplaceConstructibleMoveableAndAssignable; + using It = forward_iterator; + { + std::vector v; + v.reserve(5); + for (std::size_t i = 0; i < v.capacity(); ++i) + v.emplace_back(99); + v.assign(It(arr1), It(std::end(arr1))); + assert(v.size() == 1); + assert(v[0].value == 42); + } + { + std::vector v; + v.reserve(5); + for (std::size_t i = 0; i < v.capacity(); ++i) + v.emplace_back(99); + v.assign(It(arr2), It(std::end(arr2))); + assert(v.size() == 3); + assert(v[0].value == 1); + assert(v[1].value == 101); + assert(v[2].value == 42); + } + } + { // Test with new_size < size() for input_iterator, resulting in destruction at end during assign + using T = EmplaceConstructibleMoveableAndAssignable; + using It = cpp17_input_iterator; + { + std::vector v; + v.reserve(5); + for (std::size_t i = 0; i < v.capacity(); ++i) + v.emplace_back(99); + v.assign(It(arr1), It(std::end(arr1))); + assert(v.size() == 1); + assert(v[0].value == 42); + } + { + std::vector v; + v.reserve(5); + for (std::size_t i = 0; i < v.capacity(); ++i) + v.emplace_back(99); + v.assign(It(arr2), It(std::end(arr2))); + assert(v.size() == 3); + assert(v[0].value == 1); + assert(v[1].value == 101); + assert(v[2].value == 42); + } + } + + { // Test with size() < new_size < capacity() for forward_iterator, resulting in construction at end during assign + using T = EmplaceConstructibleMoveableAndAssignable; + using It = forward_iterator; + { + std::vector v; + v.reserve(5); + v.assign(It(arr1), It(std::end(arr1))); + assert(v.size() == 1); + assert(v[0].value == 42); + } + { + std::vector v; + v.reserve(5); + for (std::size_t i = 0; i < 2; ++i) + v.emplace_back(99); + v.assign(It(arr2), It(std::end(arr2))); + assert(v.size() == 3); + assert(v[0].value == 1); + assert(v[1].value == 101); + assert(v[2].value == 42); + } + } + { // Test with size() < new_size < capacity() for input_iterator, resulting in construction at end during assign + using T = EmplaceConstructibleMoveableAndAssignable; + using It = cpp17_input_iterator; + { + std::vector v; + v.reserve(5); + v.assign(It(arr1), It(std::end(arr1))); + assert(v.size() == 1); + assert(v[0].value == 42); + } + { + std::vector v; + v.reserve(5); + for (std::size_t i = 0; i < 2; ++i) + v.emplace_back(99); + v.assign(It(arr2), It(std::end(arr2))); + assert(v.size() == 3); + assert(v[0].value == 1); + assert(v[1].value == 101); + assert(v[2].value == 42); + } + } #endif // Test with a number of elements in the source range that is greater than capacity