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//===----------------------------------------------------------------------===//
8
9// <vector>
10
11// iterator erase(const_iterator position);
12
13#include <vector>
14#include <iterator>
15#include <cassert>
16
17#include "asan_testing.h"
18#include "min_allocator.h"
19#include "MoveOnly.h"
20#include "test_macros.h"
21
22#ifndef TEST_HAS_NO_EXCEPTIONS
23struct Throws {
24 Throws() : v_(0) {}
25 Throws(int v) : v_(v) {}
26 Throws(const Throws& rhs) : v_(rhs.v_) {
27 if (sThrows)
28 throw 1;
29 }
30 Throws(Throws&& rhs) : v_(rhs.v_) {
31 if (sThrows)
32 throw 1;
33 }
34 Throws& operator=(const Throws& rhs) {
35 v_ = rhs.v_;
36 return *this;
37 }
38 Throws& operator=(Throws&& rhs) {
39 v_ = rhs.v_;
40 return *this;
41 }
42 int v_;
43 static bool sThrows;
44};
45
46bool Throws::sThrows = false;
47#endif
48
49TEST_CONSTEXPR_CXX20 bool tests() {
50 {
51 int a1[] = {1, 2, 3, 4, 5};
52 std::vector<int> l1(a1, a1 + 5);
53 l1.erase(position: l1.begin());
54 assert(is_contiguous_container_asan_correct(l1));
55 assert(l1 == std::vector<int>(a1 + 1, a1 + 5));
56 }
57 {
58 int a1[] = {1, 2, 3, 4, 5};
59 int e1[] = {1, 3, 4, 5};
60 std::vector<int> l1(a1, a1 + 5);
61 l1.erase(position: l1.begin() + 1);
62 assert(is_contiguous_container_asan_correct(l1));
63 assert(l1 == std::vector<int>(e1, e1 + 4));
64 }
65 {
66 int a1[] = {1, 2, 3};
67 std::vector<int> l1(a1, a1 + 3);
68 std::vector<int>::const_iterator i = l1.begin();
69 assert(is_contiguous_container_asan_correct(l1));
70 ++i;
71 std::vector<int>::iterator j = l1.erase(position: i);
72 assert(l1.size() == 2);
73 assert(std::distance(l1.begin(), l1.end()) == 2);
74 assert(*j == 3);
75 assert(*l1.begin() == 1);
76 assert(*std::next(l1.begin()) == 3);
77 assert(is_contiguous_container_asan_correct(l1));
78 j = l1.erase(position: j);
79 assert(j == l1.end());
80 assert(l1.size() == 1);
81 assert(std::distance(l1.begin(), l1.end()) == 1);
82 assert(*l1.begin() == 1);
83 assert(is_contiguous_container_asan_correct(l1));
84 j = l1.erase(position: l1.begin());
85 assert(j == l1.end());
86 assert(l1.size() == 0);
87 assert(std::distance(l1.begin(), l1.end()) == 0);
88 assert(is_contiguous_container_asan_correct(l1));
89 }
90
91 // Make sure vector::erase works with move-only types
92 // When non-trivial
93 {
94 std::vector<MoveOnly> v;
95 v.emplace_back(1);
96 v.emplace_back(2);
97 v.emplace_back(3);
98 v.erase(v.begin());
99 assert(v.size() == 2);
100 assert(v[0] == MoveOnly(2));
101 assert(v[1] == MoveOnly(3));
102 }
103 // When trivial
104 {
105 std::vector<TrivialMoveOnly> v;
106 v.emplace_back(1);
107 v.emplace_back(2);
108 v.emplace_back(3);
109 v.erase(v.begin());
110 assert(v.size() == 2);
111 assert(v[0] == TrivialMoveOnly(2));
112 assert(v[1] == TrivialMoveOnly(3));
113 }
114
115#if TEST_STD_VER >= 11
116 {
117 int a1[] = {1, 2, 3};
118 std::vector<int, min_allocator<int>> l1(a1, a1 + 3);
119 std::vector<int, min_allocator<int>>::const_iterator i = l1.begin();
120 assert(is_contiguous_container_asan_correct(l1));
121 ++i;
122 std::vector<int, min_allocator<int>>::iterator j = l1.erase(i);
123 assert(l1.size() == 2);
124 assert(std::distance(l1.begin(), l1.end()) == 2);
125 assert(*j == 3);
126 assert(*l1.begin() == 1);
127 assert(*std::next(l1.begin()) == 3);
128 assert(is_contiguous_container_asan_correct(l1));
129 j = l1.erase(j);
130 assert(j == l1.end());
131 assert(l1.size() == 1);
132 assert(std::distance(l1.begin(), l1.end()) == 1);
133 assert(*l1.begin() == 1);
134 assert(is_contiguous_container_asan_correct(l1));
135 j = l1.erase(l1.begin());
136 assert(j == l1.end());
137 assert(l1.size() == 0);
138 assert(std::distance(l1.begin(), l1.end()) == 0);
139 assert(is_contiguous_container_asan_correct(l1));
140 }
141#endif
142
143 return true;
144}
145
146int main(int, char**) {
147 tests();
148#if TEST_STD_VER > 17
149 static_assert(tests());
150#endif
151
152#ifndef TEST_HAS_NO_EXCEPTIONS
153 // Test for LWG2853:
154 // Throws: Nothing unless an exception is thrown by the assignment operator or move assignment operator of T.
155 {
156 Throws arr[] = {1, 2, 3};
157 std::vector<Throws> v(arr, arr + 3);
158 Throws::sThrows = true;
159 v.erase(position: v.begin());
160 v.erase(position: --v.end());
161 v.erase(position: v.begin());
162 assert(v.size() == 0);
163 }
164#endif
165
166 return 0;
167}
168

source code of libcxx/test/std/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp