Skip to content

[libc++][test] Improve tests for assign in std::vector and vector<bool> #119163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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
//
//===----------------------------------------------------------------------===//

// <vector>

// template <class InputIt>
// constexpr void assign(InputIt first, InputIt last);

#include <vector>
#include <cassert>
#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<bool> in(128, true);
std::vector<bool> v(5, false);
assert(v.capacity() < in.size());
using It = forward_iterator<std::vector<bool>::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<bool> v(2 * N, false);
using It = forward_iterator<bool*>;
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<bool> v(N / 2, false);
v.reserve(N * 2);
using It = forward_iterator<bool*>;
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<bool> in(128, true);
std::vector<bool> v(5, false);
assert(v.capacity() < in.size());
using It = cpp17_input_iterator<std::vector<bool>::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<bool> v(2 * N, false);
using It = cpp17_input_iterator<bool*>;
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<bool> v(N / 2, false);
v.reserve(N * 2);
using It = cpp17_input_iterator<bool*>;
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;
}
Original file line number Diff line number Diff line change
@@ -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
//
//===----------------------------------------------------------------------===//

// <vector>

// void assign(size_type n, const value_type& x);

#include <vector>
#include <cassert>
#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<bool> 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<bool> 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<bool> 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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<int>;
{ // Test with new_size > capacity() == 0 for forward_iterator, resulting in reallocation during assign
using T = EmplaceConstructibleMoveableAndAssignable<int>;
using It = forward_iterator<int*>;
{
std::vector<T> v;
Expand All @@ -44,8 +43,8 @@ TEST_CONSTEXPR_CXX20 bool test() {
assert(v[2].value == 42);
}
}
{
using T = EmplaceConstructibleMoveableAndAssignable<int>;
{ // Test with new_size > capacity() == 0 for input_iterator, resulting in reallocation during assign
using T = EmplaceConstructibleMoveableAndAssignable<int>;
using It = cpp17_input_iterator<int*>;
{
std::vector<T> v;
Expand All @@ -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<int>;
using It = forward_iterator<int*>;
{
std::vector<T> 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<T> 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<int>;
using It = cpp17_input_iterator<int*>;
{
std::vector<T> 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<T> 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<int>;
using It = forward_iterator<int*>;
{
std::vector<T> v;
v.reserve(5);
v.assign(It(arr1), It(std::end(arr1)));
assert(v.size() == 1);
assert(v[0].value == 42);
}
{
std::vector<T> 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<int>;
using It = cpp17_input_iterator<int*>;
{
std::vector<T> v;
v.reserve(5);
v.assign(It(arr1), It(std::end(arr1)));
assert(v.size() == 1);
assert(v[0].value == 42);
}
{
std::vector<T> 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
Expand Down
Loading