1616#include < type_traits>
1717#include < vector>
1818
19+ #include " ../common.h"
1920#include " count_new.h"
2021#include " test_allocator.h"
2122#include " test_iterators.h"
2223
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-
10924int main (int , char **) {
110- using AllocVec = std::vector<int , Allocator <int > >;
25+ using AllocVec = std::vector<int , throwing_allocator <int > >;
11126 try { // vector()
11227 AllocVec vec;
11328 } catch (int ) {
11429 }
11530 check_new_delete_called ();
11631
11732 try { // Throw in vector(size_type) from type
118- std::vector<ThrowingT > get_alloc (1 );
33+ std::vector<throwing_t > get_alloc (1 );
11934 } catch (int ) {
12035 }
12136 check_new_delete_called ();
12237
12338#if TEST_STD_VER >= 14
12439 try { // Throw in vector(size_type, value_type) from type
12540 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);
12843 } catch (int ) {
12944 }
13045 check_new_delete_called ();
13146
13247 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 );
13449 AllocVec get_alloc (0 , alloc);
13550 } catch (int ) {
13651 }
13752 check_new_delete_called ();
13853
13954 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 >());
14156 } catch (int ) {
14257 }
14358 check_new_delete_called ();
14459#endif // TEST_STD_VER >= 14
14560
14661 try { // Throw in vector(size_type, value_type, const allocator_type&) from the type
14762 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 >());
15065 } catch (int ) {
15166 }
15267 check_new_delete_called ();
15368
15469 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 ));
15672 } catch (int ) {
15773 }
15874 check_new_delete_called ();
15975
16076 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 ));
16279 } catch (int ) {
16380 }
16481 check_new_delete_called ();
@@ -172,75 +89,76 @@ int main(int, char**) {
17289
17390 try { // Throw in vector(InputIterator, InputIterator, const allocator_type&) from input iterator
17491 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);
17694 } catch (int ) {
17795 }
17896 check_new_delete_called ();
17997
18098 try { // Throw in vector(InputIterator, InputIterator, const allocator_type&) from forward iterator
18199 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);
183103 } catch (int ) {
184104 }
185105 check_new_delete_called ();
186106
187107 try { // Throw in vector(InputIterator, InputIterator, const allocator_type&) from allocator
188108 int a[] = {1 , 2 };
189- Allocator <int > alloc (false );
109+ throwing_allocator <int > alloc (/* throw_on_ctor = */ false , /* throw_on_copy = */ true );
190110 AllocVec vec (cpp17_input_iterator<int *>(a), cpp17_input_iterator<int *>(a + 2 ), alloc);
191111 } catch (int ) {
192- // FIXME: never called.
193112 }
194113 check_new_delete_called ();
195114
196115 try { // Throw in vector(InputIterator, InputIterator, const allocator_type&) from allocator
197116 int a[] = {1 , 2 };
198- Allocator <int > alloc (false );
117+ throwing_allocator <int > alloc (/* throw_on_ctor = */ false , /* throw_on_copy = */ true );
199118 AllocVec vec (forward_iterator<int *>(a), forward_iterator<int *>(a + 2 ), alloc);
200119 } catch (int ) {
201- // FIXME: never called.
202120 }
203121 check_new_delete_called ();
204122
205123 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 ;
208126 vec.emplace_back (throw_after);
209127 auto vec2 = vec;
210128 } catch (int ) {
211129 }
212130 check_new_delete_called ();
213131
214132 try { // Throw in vector(const vector&, const allocator_type&) from type
215- std::vector<ThrowingT > vec;
133+ std::vector<throwing_t > vec;
216134 int throw_after = 1 ;
217135 vec.emplace_back (throw_after);
218- std::vector<ThrowingT > vec2 (vec, std::allocator<int >());
136+ std::vector<throwing_t > vec2 (vec, std::allocator<int >());
219137 } catch (int ) {
220138 }
221139 check_new_delete_called ();
222140
223141 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 ));
225143 int throw_after = 10 ;
226- ThrowingT v (throw_after);
144+ throwing_t v (throw_after);
227145 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 ));
229147 } catch (int ) {
230148 }
231149 check_new_delete_called ();
232150
233151#if TEST_STD_VER >= 11
234152 try { // Throw in vector(initializer_list<value_type>) from type
235153 int throw_after = 1 ;
236- std::vector<ThrowingT > vec ({ThrowingT (throw_after)});
154+ std::vector<throwing_t > vec ({throwing_t (throw_after)});
237155 } catch (int ) {
238156 }
239157 check_new_delete_called ();
240158
241159 try { // Throw in vector(initializer_list<value_type>, const allocator_type&) constructor from type
242160 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 >());
244162 } catch (int ) {
245163 }
246164 check_new_delete_called ();
0 commit comments