Revert "[libc] Use best-fit binary trie to make malloc logarithmic" (#117065)
[llvm-project.git] / libcxx / test / std / containers / sequences / vector / vector.modifiers / erase_iter.pass.cpp
blobf0157eb74b90f3378d5474299bb1fd728e3a1f02
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 // <vector>
11 // iterator erase(const_iterator position);
13 #include <vector>
14 #include <cassert>
15 #include <memory>
17 #include "asan_testing.h"
18 #include "common.h"
19 #include "min_allocator.h"
20 #include "MoveOnly.h"
21 #include "test_macros.h"
23 template <template <class> class Allocator, class T>
24 TEST_CONSTEXPR_CXX20 void tests() {
26 T arr[] = {T(1), T(2), T(3), T(4), T(5)};
27 using Vector = std::vector<T, Allocator<T> >;
28 using Iterator = typename Vector::iterator;
31 Vector v(arr, arr + 5);
32 Iterator it = v.erase(v.cbegin());
33 assert(v == Vector(arr + 1, arr + 5));
34 assert(it == v.begin());
35 assert(is_contiguous_container_asan_correct(v));
38 T expected[] = {T(1), T(3), T(4), T(5)};
39 Vector v(arr, arr + 5);
40 Iterator it = v.erase(v.cbegin() + 1);
41 assert(v == Vector(expected, expected + 4));
42 assert(it == v.begin() + 1);
43 assert(is_contiguous_container_asan_correct(v));
46 T expected[] = {T(1), T(2), T(3), T(4)};
47 Vector v(arr, arr + 5);
48 Iterator it = v.erase(v.cbegin() + 4);
49 assert(v == Vector(expected, expected + 4));
50 assert(it == v.end());
51 assert(is_contiguous_container_asan_correct(v));
55 // Make sure vector::erase works with move-only types
57 // When non-trivial
59 std::vector<MoveOnly, Allocator<MoveOnly> > v;
60 v.emplace_back(1);
61 v.emplace_back(2);
62 v.emplace_back(3);
63 v.erase(v.begin());
64 assert(v.size() == 2);
65 assert(v[0] == MoveOnly(2));
66 assert(v[1] == MoveOnly(3));
68 // When trivial
70 std::vector<TrivialMoveOnly, Allocator<TrivialMoveOnly> > v;
71 v.emplace_back(1);
72 v.emplace_back(2);
73 v.emplace_back(3);
74 v.erase(v.begin());
75 assert(v.size() == 2);
76 assert(v[0] == TrivialMoveOnly(2));
77 assert(v[1] == TrivialMoveOnly(3));
82 TEST_CONSTEXPR_CXX20 bool tests() {
83 tests<std::allocator, int>();
84 tests<std::allocator, NonTriviallyRelocatable>();
85 tests<min_allocator, int>();
86 tests<min_allocator, NonTriviallyRelocatable>();
87 return true;
90 int main(int, char**) {
91 tests();
92 #if TEST_STD_VER > 17
93 static_assert(tests());
94 #endif
96 #ifndef TEST_HAS_NO_EXCEPTIONS
97 // Test for LWG2853:
98 // Throws: Nothing unless an exception is thrown by the assignment operator or move assignment operator of T.
100 Throws arr[] = {1, 2, 3};
101 std::vector<Throws> v(arr, arr + 3);
102 Throws::sThrows = true;
103 v.erase(v.begin());
104 v.erase(--v.end());
105 v.erase(v.begin());
106 assert(v.size() == 0);
108 #endif
110 // Make sure we satisfy the complexity requirement in terms of the number of times the assignment
111 // operator is called.
113 // There is currently ambiguity as to whether this is truly mandated by the Standard, so we only
114 // test it for libc++.
115 #ifdef _LIBCPP_VERSION
117 Tracker tracker;
118 std::vector<TrackedAssignment> v;
120 // Set up the vector with 5 elements.
121 for (int i = 0; i != 5; ++i) {
122 v.emplace_back(&tracker);
124 assert(tracker.copy_assignments == 0);
125 assert(tracker.move_assignments == 0);
127 // Erase element [1] from it. Elements [2] [3] [4] should be shifted, so we should
128 // see 3 move assignments (and nothing else).
129 v.erase(v.begin() + 1);
130 assert(v.size() == 4);
131 assert(tracker.copy_assignments == 0);
132 assert(tracker.move_assignments == 3);
134 #endif
136 return 0;