Skip to content

Commit

Permalink
Update libcxx/vector
Browse files Browse the repository at this point in the history
  • Loading branch information
morzhovets committed Oct 29, 2024
1 parent 1c89ad8 commit 9ae0ebf
Show file tree
Hide file tree
Showing 6 changed files with 349 additions and 0 deletions.
20 changes: 20 additions & 0 deletions test/sources/libcxx/VectorTests.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ LIBCXX_TEST_BEGIN(cons_construct_default)
#include "vector/vector.cons/construct_default.pass.cpp"
LIBCXX_TEST_END

LIBCXX_TEST_BEGIN(cons_construct_from_range)
#include "vector/vector.cons/construct_from_range.pass.cpp"
LIBCXX_TEST_END

LIBCXX_TEST_BEGIN(cons_construct_iter_iter)
#include "vector/vector.cons/construct_iter_iter.pass.cpp"
LIBCXX_TEST_END
Expand Down Expand Up @@ -280,14 +284,26 @@ LIBCXX_TEST_BEGIN(erasure_erase_if)
#include "vector/vector.erasure/erase_if.pass.cpp"
LIBCXX_TEST_END

LIBCXX_TEST_BEGIN(modifiers_append_range)
#include "vector/vector.modifiers/append_range.pass.cpp"
LIBCXX_TEST_END

LIBCXX_TEST_BEGIN(modifiers_assert_push_back_invalidation)
#include "vector/vector.modifiers/assert.push_back.invalidation.pass.cpp"
LIBCXX_TEST_END

LIBCXX_TEST_BEGIN(modifiers_assign_range)
#include "vector/vector.modifiers/assign_range.pass.cpp"
LIBCXX_TEST_END

LIBCXX_TEST_BEGIN(modifiers_clear)
#include "vector/vector.modifiers/clear.pass.cpp"
LIBCXX_TEST_END

LIBCXX_TEST_BEGIN(modifiers_destroy_elements)
#include "vector/vector.modifiers/destroy_elements.pass.cpp"
LIBCXX_TEST_END

LIBCXX_TEST_BEGIN(modifiers_emplace)
#include "vector/vector.modifiers/emplace.pass.cpp"
LIBCXX_TEST_END
Expand Down Expand Up @@ -328,6 +344,10 @@ LIBCXX_TEST_BEGIN(modifiers_insert_iter_size_value)
#include "vector/vector.modifiers/insert_iter_size_value.pass.cpp"
LIBCXX_TEST_END

LIBCXX_TEST_BEGIN(modifiers_insert_range)
#include "vector/vector.modifiers/insert_range.pass.cpp"
LIBCXX_TEST_END

LIBCXX_TEST_BEGIN(modifiers_pop_back)
#include "vector/vector.modifiers/pop_back.pass.cpp"
LIBCXX_TEST_END
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Modified for https://github.com/morzhovets/momo project.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20

// template<container-compatible-range<T> R>
// vector(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23

constexpr bool test() {
for_all_iterators_and_allocators<int>([]<class Iter, class Sent, class Alloc>() {
test_sequence_container<std::vector, int, Iter, Sent, Alloc>([]([[maybe_unused]] const auto& c) {
LIBCPP_ASSERT(c.__invariants());
LIBCPP_ASSERT(is_contiguous_container_asan_correct(c));
});
});
test_sequence_container_move_only<std::vector>();

return true;
}

int main(int, char**) {
static_assert(test_constraints<std::vector, int, double>());
test();

//static_assert(test());

test_exception_safety_throwing_copy<std::vector>();
test_exception_safety_throwing_allocator<std::vector, int>();

return 0;
}
71 changes: 71 additions & 0 deletions test/sources/libcxx/vector/vector.modifiers/append_range.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Modified for https://github.com/morzhovets/momo project.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=2000000

// template<container-compatible-range<T> R>
// constexpr void append_range(R&& rg); // C++23

// Tested cases:
// - different kinds of insertions (appending an {empty/one-element/mid-sized/long range} into an
// {empty/one-element/full} container);
// - appending move-only elements;
// - an exception is thrown when copying the elements or when allocating new elements.
/*constexpr*/ bool test() {
static_assert(test_constraints_append_range<std::vector, int, double>());

for_all_iterators_and_allocators<int, const int*>([]<class Iter, class Sent, class Alloc>() {
test_sequence_append_range<std::vector<int, Alloc>, Iter, Sent>([]([[maybe_unused]] auto&& c) {
LIBCPP_ASSERT(c.__invariants());
LIBCPP_ASSERT(is_contiguous_container_asan_correct(c));
});
});
test_sequence_append_range_move_only<std::vector>();

{ // Vector may or may not need to reallocate because of the insertion -- make sure to test both cases.
{ // Ensure reallocation happens.
int in[] = {-1, -2, -3, -4, -5, -6, -7, -8, -9, -10};
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8};
v.shrink_to_fit();
assert(v.capacity() < v.size() + 3 * std::ranges::size(in));

v.append_range(in);
v.append_range(in);
v.append_range(in);
assert(std::ranges::equal(v, std::array{1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10,
-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10}));
}

{ // Ensure no reallocation happens.
int in[] = {-1, -2, -3, -4, -5, -6, -7, -8, -9, -10};
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8};
v.reserve(v.size() + std::ranges::size(in));
assert(v.capacity() >= v.size() + std::ranges::size(in));

v.append_range(in);
assert(std::ranges::equal(v, std::array{1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10}));
}
}

return true;
}

int main(int, char**) {
test();
//static_assert(test());

test_append_range_exception_safety_throwing_copy<std::vector>();
test_append_range_exception_safety_throwing_allocator<std::vector, int>();

return 0;
}
78 changes: 78 additions & 0 deletions test/sources/libcxx/vector/vector.modifiers/assign_range.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Modified for https://github.com/morzhovets/momo project.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=2000000

// template<container-compatible-range<T> R>
// constexpr void assign_range(R&& rg); // C++23

// Tested cases:
// - different kinds of assignments (assigning an {empty/one-element/mid-sized/long range} to an
// {empty/one-element/full} container);
// - assigning move-only elements;
// - an exception is thrown when copying the elements or when allocating new elements.
/*constexpr*/ bool test() {
static_assert(test_constraints_assign_range<std::vector, int, double>());

for_all_iterators_and_allocators<int, const int*>([]<class Iter, class Sent, class Alloc>() {
test_sequence_assign_range<std::vector<int, Alloc>, Iter, Sent>([]([[maybe_unused]] auto&& c) {
LIBCPP_ASSERT(c.__invariants());
LIBCPP_ASSERT(is_contiguous_container_asan_correct(c));
});
});
test_sequence_assign_range_move_only<std::vector>();

{ // Vector may or may not need to reallocate because of the assignment -- make sure to test both cases.
{ // Ensure reallocation happens.
int in[] = {-1, -2, -3, -4, -5, -6, -7, -8, -9, -10};
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8};
v.shrink_to_fit();
#ifndef LIBCXX_TEST_SEGMENTED_ARRAY
assert(v.capacity() < std::ranges::size(in));
#endif

v.assign_range(in);
assert(std::ranges::equal(v, in));
}

{ // Ensure no reallocation happens -- the input range is shorter than the vector.
int in[] = {-1, -2, -3, -4, -5};
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8};

v.assign_range(in);
assert(std::ranges::equal(v, in));
}

{ // Ensure no reallocation happens -- the input range is longer than the vector but within capacity.
int in[] = {-1, -2, -3, -4, -5, -6, -7, -8};
std::vector<int> v = {1, 2, 3, 4, 5};
v.reserve(std::ranges::size(in));
assert(v.capacity() >= std::ranges::size(in));

v.assign_range(in);
assert(std::ranges::equal(v, in));
}
}

return true;
}

int main(int, char**) {
test();
//static_assert(test());

test_assign_range_exception_safety_throwing_copy<std::vector>();
test_assign_range_exception_safety_throwing_allocator<std::vector, int>();

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Modified for https://github.com/morzhovets/momo project.
//
//===----------------------------------------------------------------------===//

// Ensure that all the elements in the vector are destroyed, especially when reallocating the internal buffer

// UNSUPPORTED: c++03

struct DestroyTracker {
TEST_CONSTEXPR_CXX20 DestroyTracker(std::vector<bool>& vec) : vec_(&vec), index_(vec.size()) { vec.push_back(false); }

TEST_CONSTEXPR_CXX20 DestroyTracker(const DestroyTracker& other) : vec_(other.vec_), index_(vec_->size()) {
vec_->push_back(false);
}

TEST_CONSTEXPR_CXX20 DestroyTracker& operator=(const DestroyTracker&) { return *this; }
TEST_CONSTEXPR_CXX20 ~DestroyTracker() { (*vec_)[index_] = true; }

std::vector<bool>* vec_;
size_t index_;
};

template <class Operation>
TEST_CONSTEXPR_CXX20 void test(Operation operation) {
std::vector<bool> all_destroyed;

{
std::vector<DestroyTracker> v;
for (size_t i = 0; i != 100; ++i)
operation(v, all_destroyed);
}

assert(std::all_of(all_destroyed.begin(), all_destroyed.end(), [](bool b) { return b; }));
}

TEST_CONSTEXPR_CXX20 bool test() {
test([](std::vector<DestroyTracker>& vec, std::vector<bool>& tracker) { vec.emplace_back(tracker); });
test([](std::vector<DestroyTracker>& vec, std::vector<bool>& tracker) { vec.push_back(tracker); });
test([](std::vector<DestroyTracker>& vec, std::vector<bool>& tracker) { vec.emplace(vec.begin(), tracker); });
test([](std::vector<DestroyTracker>& vec, std::vector<bool>& tracker) { vec.insert(vec.begin(), tracker); });
test([](std::vector<DestroyTracker>& vec, std::vector<bool>& tracker) { vec.resize(vec.size() + 1, tracker); });
#if TEST_STD_VER >= 23
test([](std::vector<DestroyTracker>& vec, std::vector<bool>& tracker) {
vec.insert_range(vec.begin(), std::array<DestroyTracker, 2>{tracker, tracker});
});

test([](std::vector<DestroyTracker>& vec, std::vector<bool>& tracker) {
vec.append_range(std::array<DestroyTracker, 2>{tracker, tracker});
});
#endif

return true;
}

void main() {
test();
#if TEST_STD_VER >= 20
//static_assert(test());
#endif
}
72 changes: 72 additions & 0 deletions test/sources/libcxx/vector/vector.modifiers/insert_range.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Modified for https://github.com/morzhovets/momo project.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=2000000

// template<container-compatible-range<T> R>
// constexpr iterator insert_range(const_iterator position, R&& rg); // C++23

// Tested cases:
// - different kinds of insertions (inserting an {empty/one-element/mid-sized/long range} into an
// {empty/one-element/full} container at the {beginning/middle/end});
// - inserting move-only elements;
// - an exception is thrown when copying the elements or when allocating new elements.

/*constexpr*/ bool test() {
for_all_iterators_and_allocators<int, const int*>([]<class Iter, class Sent, class Alloc>() {
test_sequence_insert_range<std::vector<int, Alloc>, Iter, Sent>([]([[maybe_unused]] auto&& c) {
LIBCPP_ASSERT(c.__invariants());
LIBCPP_ASSERT(is_contiguous_container_asan_correct(c));
});
});
test_sequence_insert_range_move_only<std::vector>();

{ // Vector may or may not need to reallocate because of the insertion -- make sure to test both cases.
{ // Ensure reallocation happens.
int in[] = {-1, -2, -3, -4, -5, -6, -7, -8, -9, -10};
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8};
v.shrink_to_fit();
assert(v.capacity() < v.size() + 3 * std::ranges::size(in));

v.insert_range(v.end(), in);
v.insert_range(v.end() - std::ranges::size(in), in);
v.insert_range(v.end() - std::ranges::size(in), in);
assert(std::ranges::equal(v, std::array{1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10,
-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10}));
}

{ // Ensure no reallocation happens.
int in[] = {-1, -2, -3, -4, -5, -6, -7, -8, -9, -10};
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8};
v.reserve(v.size() + std::ranges::size(in));
assert(v.capacity() >= v.size() + std::ranges::size(in));

v.insert_range(v.end(), in);
assert(std::ranges::equal(v, std::array{1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10}));
}
}

return true;
}

int main(int, char**) {
test();
//static_assert(test());

static_assert(test_constraints_insert_range<std::vector, int, double>());

test_insert_range_exception_safety_throwing_copy<std::vector>();
test_insert_range_exception_safety_throwing_allocator<std::vector, int>();

return 0;
}

0 comments on commit 9ae0ebf

Please sign in to comment.