16
16
#include < type_traits>
17
17
#include < vector>
18
18
19
+ #include " ../common.h"
19
20
#include " count_new.h"
20
21
#include " test_allocator.h"
21
22
#include " test_iterators.h"
22
23
23
- template <class T >
24
- struct Allocator {
25
- using value_type = T;
26
- using is_always_equal = std::false_type;
27
-
28
- template <class U >
29
- Allocator (const Allocator<U>&) {}
30
-
31
- Allocator (bool should_throw = true ) {
32
- if (should_throw)
33
- throw 0 ;
34
- }
35
-
36
- T* allocate (std::size_t n) { return std::allocator<T>().allocate (n); }
37
- void deallocate (T* ptr, std::size_t n) { std::allocator<T>().deallocate (ptr, n); }
38
-
39
- template <class U >
40
- friend bool operator ==(const Allocator&, const Allocator<U>&) {
41
- return true ;
42
- }
43
- };
44
-
45
- struct ThrowingT {
46
- int * throw_after_n_ = nullptr ;
47
- ThrowingT () { throw 0 ; }
48
-
49
- ThrowingT (int & throw_after_n) : throw_after_n_(&throw_after_n) {
50
- if (throw_after_n == 0 )
51
- throw 0 ;
52
- --throw_after_n;
53
- }
54
-
55
- ThrowingT (const ThrowingT& rhs) : throw_after_n_(rhs.throw_after_n_) {
56
- if (throw_after_n_ == nullptr || *throw_after_n_ == 0 )
57
- throw 1 ;
58
- --*throw_after_n_;
59
- }
60
-
61
- ThrowingT& operator =(const ThrowingT& rhs) {
62
- throw_after_n_ = rhs.throw_after_n_ ;
63
- if (throw_after_n_ == nullptr || *throw_after_n_ == 0 )
64
- throw 1 ;
65
- --*throw_after_n_;
66
- return *this ;
67
- }
68
- };
69
-
70
- template <class IterCat >
71
- struct Iterator {
72
- using iterator_category = IterCat;
73
- using difference_type = std::ptrdiff_t ;
74
- using value_type = int ;
75
- using reference = int &;
76
- using pointer = int *;
77
-
78
- int i_;
79
- Iterator (int i = 0 ) : i_(i) {}
80
- int & operator *() {
81
- if (i_ == 1 )
82
- throw 1 ;
83
- return i_;
84
- }
85
-
86
- friend bool operator ==(const Iterator& lhs, const Iterator& rhs) { return lhs.i_ == rhs.i_ ; }
87
-
88
- friend bool operator !=(const Iterator& lhs, const Iterator& rhs) { return lhs.i_ != rhs.i_ ; }
89
-
90
- Iterator& operator ++() {
91
- ++i_;
92
- return *this ;
93
- }
94
-
95
- Iterator operator ++(int ) {
96
- auto tmp = *this ;
97
- ++i_;
98
- return tmp;
99
- }
100
- };
101
-
102
- void check_new_delete_called () {
103
- assert (globalMemCounter.new_called == globalMemCounter.delete_called );
104
- assert (globalMemCounter.new_array_called == globalMemCounter.delete_array_called );
105
- assert (globalMemCounter.aligned_new_called == globalMemCounter.aligned_delete_called );
106
- assert (globalMemCounter.aligned_new_array_called == globalMemCounter.aligned_delete_array_called );
107
- }
108
-
109
24
int main (int , char **) {
110
- using AllocVec = std::vector<int , Allocator <int > >;
25
+ using AllocVec = std::vector<int , throwing_allocator <int > >;
111
26
try { // vector()
112
27
AllocVec vec;
113
28
} catch (int ) {
114
29
}
115
30
check_new_delete_called ();
116
31
117
32
try { // Throw in vector(size_type) from type
118
- std::vector<ThrowingT > get_alloc (1 );
33
+ std::vector<throwing_t > get_alloc (1 );
119
34
} catch (int ) {
120
35
}
121
36
check_new_delete_called ();
122
37
123
38
#if TEST_STD_VER >= 14
124
39
try { // Throw in vector(size_type, value_type) from type
125
40
int throw_after = 1 ;
126
- ThrowingT v (throw_after);
127
- std::vector<ThrowingT > get_alloc (1 , v);
41
+ throwing_t v (throw_after);
42
+ std::vector<throwing_t > get_alloc (1 , v);
128
43
} catch (int ) {
129
44
}
130
45
check_new_delete_called ();
131
46
132
47
try { // Throw in vector(size_type, const allocator_type&) from allocator
133
- Allocator <int > alloc (false );
48
+ throwing_allocator <int > alloc (/* throw_on_ctor = */ false , /* throw_on_copy = */ true );
134
49
AllocVec get_alloc (0 , alloc);
135
50
} catch (int ) {
136
51
}
137
52
check_new_delete_called ();
138
53
139
54
try { // Throw in vector(size_type, const allocator_type&) from the type
140
- std::vector<ThrowingT > vec (1 , std::allocator<ThrowingT >());
55
+ std::vector<throwing_t > vec (1 , std::allocator<throwing_t >());
141
56
} catch (int ) {
142
57
}
143
58
check_new_delete_called ();
144
59
#endif // TEST_STD_VER >= 14
145
60
146
61
try { // Throw in vector(size_type, value_type, const allocator_type&) from the type
147
62
int throw_after = 1 ;
148
- ThrowingT v (throw_after);
149
- std::vector<ThrowingT > vec (1 , v, std::allocator<ThrowingT >());
63
+ throwing_t v (throw_after);
64
+ std::vector<throwing_t > vec (1 , v, std::allocator<throwing_t >());
150
65
} catch (int ) {
151
66
}
152
67
check_new_delete_called ();
153
68
154
69
try { // Throw in vector(InputIterator, InputIterator) from input iterator
155
- std::vector<int > vec ((Iterator<std::input_iterator_tag>()), Iterator<std::input_iterator_tag>(2 ));
70
+ std::vector<int > vec (
71
+ (throwing_iterator<int , std::input_iterator_tag>()), throwing_iterator<int , std::input_iterator_tag>(2 ));
156
72
} catch (int ) {
157
73
}
158
74
check_new_delete_called ();
159
75
160
76
try { // Throw in vector(InputIterator, InputIterator) from forward iterator
161
- std::vector<int > vec ((Iterator<std::forward_iterator_tag>()), Iterator<std::forward_iterator_tag>(2 ));
77
+ std::vector<int > vec (
78
+ (throwing_iterator<int , std::forward_iterator_tag>()), throwing_iterator<int , std::forward_iterator_tag>(2 ));
162
79
} catch (int ) {
163
80
}
164
81
check_new_delete_called ();
@@ -172,75 +89,76 @@ int main(int, char**) {
172
89
173
90
try { // Throw in vector(InputIterator, InputIterator, const allocator_type&) from input iterator
174
91
std::allocator<int > alloc;
175
- std::vector<int > vec (Iterator<std::input_iterator_tag>(), Iterator<std::input_iterator_tag>(2 ), alloc);
92
+ std::vector<int > vec (
93
+ throwing_iterator<int , std::input_iterator_tag>(), throwing_iterator<int , std::input_iterator_tag>(2 ), alloc);
176
94
} catch (int ) {
177
95
}
178
96
check_new_delete_called ();
179
97
180
98
try { // Throw in vector(InputIterator, InputIterator, const allocator_type&) from forward iterator
181
99
std::allocator<int > alloc;
182
- std::vector<int > vec (Iterator<std::forward_iterator_tag>(), Iterator<std::forward_iterator_tag>(2 ), alloc);
100
+ std::vector<int > vec (throwing_iterator<int , std::forward_iterator_tag>(),
101
+ throwing_iterator<int , std::forward_iterator_tag>(2 ),
102
+ alloc);
183
103
} catch (int ) {
184
104
}
185
105
check_new_delete_called ();
186
106
187
107
try { // Throw in vector(InputIterator, InputIterator, const allocator_type&) from allocator
188
108
int a[] = {1 , 2 };
189
- Allocator <int > alloc (false );
109
+ throwing_allocator <int > alloc (/* throw_on_ctor = */ false , /* throw_on_copy = */ true );
190
110
AllocVec vec (cpp17_input_iterator<int *>(a), cpp17_input_iterator<int *>(a + 2 ), alloc);
191
111
} catch (int ) {
192
- // FIXME: never called.
193
112
}
194
113
check_new_delete_called ();
195
114
196
115
try { // Throw in vector(InputIterator, InputIterator, const allocator_type&) from allocator
197
116
int a[] = {1 , 2 };
198
- Allocator <int > alloc (false );
117
+ throwing_allocator <int > alloc (/* throw_on_ctor = */ false , /* throw_on_copy = */ true );
199
118
AllocVec vec (forward_iterator<int *>(a), forward_iterator<int *>(a + 2 ), alloc);
200
119
} catch (int ) {
201
- // FIXME: never called.
202
120
}
203
121
check_new_delete_called ();
204
122
205
123
try { // Throw in vector(const vector&) from type
206
- std::vector<ThrowingT > vec;
207
- int throw_after = 0 ;
124
+ std::vector<throwing_t > vec;
125
+ int throw_after = 1 ;
208
126
vec.emplace_back (throw_after);
209
127
auto vec2 = vec;
210
128
} catch (int ) {
211
129
}
212
130
check_new_delete_called ();
213
131
214
132
try { // Throw in vector(const vector&, const allocator_type&) from type
215
- std::vector<ThrowingT > vec;
133
+ std::vector<throwing_t > vec;
216
134
int throw_after = 1 ;
217
135
vec.emplace_back (throw_after);
218
- std::vector<ThrowingT > vec2 (vec, std::allocator<int >());
136
+ std::vector<throwing_t > vec2 (vec, std::allocator<int >());
219
137
} catch (int ) {
220
138
}
221
139
check_new_delete_called ();
222
140
223
141
try { // Throw in vector(vector&&, const allocator_type&) from type during element-wise move
224
- std::vector<ThrowingT , test_allocator<ThrowingT > > vec (test_allocator<ThrowingT >(1 ));
142
+ std::vector<throwing_t , test_allocator<throwing_t > > vec (test_allocator<throwing_t >(1 ));
225
143
int throw_after = 10 ;
226
- ThrowingT v (throw_after);
144
+ throwing_t v (throw_after);
227
145
vec.insert (vec.end (), 6 , v);
228
- std::vector<ThrowingT , test_allocator<ThrowingT > > vec2 (std::move (vec), test_allocator<ThrowingT >(2 ));
146
+ std::vector<throwing_t , test_allocator<throwing_t > > vec2 (std::move (vec), test_allocator<throwing_t >(2 ));
229
147
} catch (int ) {
230
148
}
231
149
check_new_delete_called ();
232
150
233
151
#if TEST_STD_VER >= 11
234
152
try { // Throw in vector(initializer_list<value_type>) from type
235
153
int throw_after = 1 ;
236
- std::vector<ThrowingT > vec ({ThrowingT (throw_after)});
154
+ std::vector<throwing_t > vec ({throwing_t (throw_after)});
237
155
} catch (int ) {
238
156
}
239
157
check_new_delete_called ();
240
158
241
159
try { // Throw in vector(initializer_list<value_type>, const allocator_type&) constructor from type
242
160
int throw_after = 1 ;
243
- std::vector<ThrowingT > vec ({ThrowingT (throw_after)}, std::allocator<ThrowingT >());
161
+ std::vector<throwing_t > vec ({throwing_t (throw_after)}, std::allocator<throwing_t >());
244
162
} catch (int ) {
245
163
}
246
164
check_new_delete_called ();
0 commit comments