1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
11 // iterator erase(const_iterator position);
17 #include "asan_testing.h"
19 #include "min_allocator.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
59 std::vector
<MoveOnly
, Allocator
<MoveOnly
> > v
;
64 assert(v
.size() == 2);
65 assert(v
[0] == MoveOnly(2));
66 assert(v
[1] == MoveOnly(3));
70 std::vector
<TrivialMoveOnly
, Allocator
<TrivialMoveOnly
> > v
;
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
>();
90 int main(int, char**) {
93 static_assert(tests());
96 #ifndef TEST_HAS_NO_EXCEPTIONS
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;
106 assert(v
.size() == 0);
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
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);