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 "test_macros.h"
18 #include "min_allocator.h"
19 #include "asan_testing.h"
20 
21 #ifndef TEST_HAS_NO_EXCEPTIONS
22 struct Throws {
ThrowsThrows23     Throws() : v_(0) {}
ThrowsThrows24     Throws(int v) : v_(v) {}
ThrowsThrows25     Throws(const Throws  &rhs) : v_(rhs.v_) { if (sThrows) throw 1; }
ThrowsThrows26     Throws(      Throws &&rhs) : v_(rhs.v_) { if (sThrows) throw 1; }
operator =Throws27     Throws& operator=(const Throws  &rhs) { v_ = rhs.v_; return *this; }
operator =Throws28     Throws& operator=(      Throws &&rhs) { v_ = rhs.v_; return *this; }
29     int v_;
30     static bool sThrows;
31     };
32 
33 bool Throws::sThrows = false;
34 #endif
35 
tests()36 TEST_CONSTEXPR_CXX20 bool tests()
37 {
38     {
39     int a1[] = {1, 2, 3, 4, 5};
40     std::vector<int> l1(a1, a1+5);
41     l1.erase(l1.begin());
42     assert(is_contiguous_container_asan_correct(l1));
43     assert(l1 == std::vector<int>(a1+1, a1+5));
44     }
45     {
46     int a1[] = {1, 2, 3, 4, 5};
47     int e1[] = {1, 3, 4, 5};
48     std::vector<int> l1(a1, a1+5);
49     l1.erase(l1.begin() + 1);
50     assert(is_contiguous_container_asan_correct(l1));
51     assert(l1 == std::vector<int>(e1, e1+4));
52     }
53     {
54     int a1[] = {1, 2, 3};
55     std::vector<int> l1(a1, a1+3);
56     std::vector<int>::const_iterator i = l1.begin();
57     assert(is_contiguous_container_asan_correct(l1));
58     ++i;
59     std::vector<int>::iterator j = l1.erase(i);
60     assert(l1.size() == 2);
61     assert(std::distance(l1.begin(), l1.end()) == 2);
62     assert(*j == 3);
63     assert(*l1.begin() == 1);
64     assert(*std::next(l1.begin()) == 3);
65     assert(is_contiguous_container_asan_correct(l1));
66     j = l1.erase(j);
67     assert(j == l1.end());
68     assert(l1.size() == 1);
69     assert(std::distance(l1.begin(), l1.end()) == 1);
70     assert(*l1.begin() == 1);
71     assert(is_contiguous_container_asan_correct(l1));
72     j = l1.erase(l1.begin());
73     assert(j == l1.end());
74     assert(l1.size() == 0);
75     assert(std::distance(l1.begin(), l1.end()) == 0);
76     assert(is_contiguous_container_asan_correct(l1));
77     }
78 #if TEST_STD_VER >= 11
79     {
80     int a1[] = {1, 2, 3};
81     std::vector<int, min_allocator<int>> l1(a1, a1+3);
82     std::vector<int, min_allocator<int>>::const_iterator i = l1.begin();
83     assert(is_contiguous_container_asan_correct(l1));
84     ++i;
85     std::vector<int, min_allocator<int>>::iterator j = l1.erase(i);
86     assert(l1.size() == 2);
87     assert(std::distance(l1.begin(), l1.end()) == 2);
88     assert(*j == 3);
89     assert(*l1.begin() == 1);
90     assert(*std::next(l1.begin()) == 3);
91     assert(is_contiguous_container_asan_correct(l1));
92     j = l1.erase(j);
93     assert(j == l1.end());
94     assert(l1.size() == 1);
95     assert(std::distance(l1.begin(), l1.end()) == 1);
96     assert(*l1.begin() == 1);
97     assert(is_contiguous_container_asan_correct(l1));
98     j = l1.erase(l1.begin());
99     assert(j == l1.end());
100     assert(l1.size() == 0);
101     assert(std::distance(l1.begin(), l1.end()) == 0);
102     assert(is_contiguous_container_asan_correct(l1));
103     }
104 #endif
105 
106     return true;
107 }
108 
main(int,char **)109 int main(int, char**)
110 {
111     tests();
112 #if TEST_STD_VER > 17
113     static_assert(tests());
114 #endif
115 
116 #ifndef TEST_HAS_NO_EXCEPTIONS
117 // Test for LWG2853:
118 // Throws: Nothing unless an exception is thrown by the assignment operator or move assignment operator of T.
119     {
120         Throws arr[] = {1, 2, 3};
121         std::vector<Throws> v(arr, arr+3);
122         Throws::sThrows = true;
123         v.erase(v.begin());
124         v.erase(--v.end());
125         v.erase(v.begin());
126         assert(v.size() == 0);
127     }
128 #endif
129 
130     return 0;
131 }
132