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#ifndef TEST_STD_CONTAINERS_SEQUENCES_VECTOR_COMMON_H
10#define TEST_STD_CONTAINERS_SEQUENCES_VECTOR_COMMON_H
11
12#include <array>
13#include <cassert>
14#include <cstddef>
15#include <cstdlib>
16#include <memory>
17#include <string>
18#include <type_traits>
19#include <utility>
20#include <vector>
21
22#include "count_new.h"
23#include "test_macros.h"
24
25struct throwing_t {
26 int* throw_after_n_ = nullptr;
27 throwing_t() { throw 0; }
28
29 explicit throwing_t(int& throw_after_n) : throw_after_n_(&throw_after_n) {
30 if (throw_after_n == 0)
31 throw 0;
32 --throw_after_n;
33 }
34
35 throwing_t(const throwing_t& rhs) : throw_after_n_(rhs.throw_after_n_) {
36 if (throw_after_n_ == nullptr || *throw_after_n_ == 0)
37 throw 1;
38 --*throw_after_n_;
39 }
40
41 throwing_t& operator=(const throwing_t& rhs) {
42 throw_after_n_ = rhs.throw_after_n_;
43 if (throw_after_n_ == nullptr || *throw_after_n_ == 0)
44 throw 1;
45 --*throw_after_n_;
46 return *this;
47 }
48
49 friend bool operator==(const throwing_t& lhs, const throwing_t& rhs) {
50 return lhs.throw_after_n_ == rhs.throw_after_n_;
51 }
52 friend bool operator!=(const throwing_t& lhs, const throwing_t& rhs) {
53 return lhs.throw_after_n_ != rhs.throw_after_n_;
54 }
55};
56
57#if TEST_STD_VER >= 11
58
59template <typename T>
60struct move_only_throwing_t {
61 T data_;
62 int* throw_after_n_ = nullptr;
63 bool moved_from_ = false;
64
65 move_only_throwing_t() = default;
66
67 explicit move_only_throwing_t(const T& data, int& throw_after_n) : data_(data), throw_after_n_(&throw_after_n) {
68 if (throw_after_n == 0)
69 throw 1;
70 --throw_after_n;
71 }
72
73 explicit move_only_throwing_t(T&& data, int& throw_after_n) : data_(std::move(data)), throw_after_n_(&throw_after_n) {
74 if (throw_after_n == 0)
75 throw 1;
76 --throw_after_n;
77 }
78
79 move_only_throwing_t(const move_only_throwing_t&) = delete;
80 move_only_throwing_t& operator=(const move_only_throwing_t&) = delete;
81
82 move_only_throwing_t(move_only_throwing_t&& rhs) : data_(std::move(rhs.data_)), throw_after_n_(rhs.throw_after_n_) {
83 rhs.throw_after_n_ = nullptr;
84 rhs.moved_from_ = true;
85 if (throw_after_n_ == nullptr || *throw_after_n_ == 0)
86 throw 1;
87 --*throw_after_n_;
88 }
89
90 move_only_throwing_t& operator=(move_only_throwing_t&& rhs) {
91 if (this == &rhs)
92 return *this;
93 data_ = std::move(rhs.data_);
94 throw_after_n_ = rhs.throw_after_n_;
95 rhs.moved_from_ = true;
96 rhs.throw_after_n_ = nullptr;
97 if (throw_after_n_ == nullptr || *throw_after_n_ == 0)
98 throw 1;
99 --*throw_after_n_;
100 return *this;
101 }
102
103 friend bool operator==(const move_only_throwing_t& lhs, const move_only_throwing_t& rhs) {
104 return lhs.data_ == rhs.data_;
105 }
106 friend bool operator!=(const move_only_throwing_t& lhs, const move_only_throwing_t& rhs) {
107 return lhs.data_ != rhs.data_;
108 }
109};
110
111#endif
112
113template <typename T>
114struct throwing_data {
115 T data_;
116 int* throw_after_n_ = nullptr;
117 throwing_data() { throw 0; }
118
119 throwing_data(const T& data, int& throw_after_n) : data_(data), throw_after_n_(&throw_after_n) {
120 if (throw_after_n == 0)
121 throw 0;
122 --throw_after_n;
123 }
124
125 throwing_data(const throwing_data& rhs) : data_(rhs.data_), throw_after_n_(rhs.throw_after_n_) {
126 if (throw_after_n_ == nullptr || *throw_after_n_ == 0)
127 throw 1;
128 --*throw_after_n_;
129 }
130
131 throwing_data& operator=(const throwing_data& rhs) {
132 data_ = rhs.data_;
133 throw_after_n_ = rhs.throw_after_n_;
134 if (throw_after_n_ == nullptr || *throw_after_n_ == 0)
135 throw 1;
136 --*throw_after_n_;
137 return *this;
138 }
139
140 friend bool operator==(const throwing_data& lhs, const throwing_data& rhs) {
141 return lhs.data_ == rhs.data_ && lhs.throw_after_n_ == rhs.throw_after_n_;
142 }
143 friend bool operator!=(const throwing_data& lhs, const throwing_data& rhs) { return !(lhs == rhs); }
144};
145
146template <class T>
147struct throwing_allocator {
148 using value_type = T;
149
150 bool throw_on_copy_ = false;
151
152 explicit throwing_allocator(bool throw_on_ctor = true) {
153 if (throw_on_ctor)
154 throw 0;
155 }
156
157 explicit throwing_allocator(bool throw_on_ctor, bool throw_on_copy) : throw_on_copy_(throw_on_copy) {
158 if (throw_on_ctor)
159 throw 0;
160 }
161
162 throwing_allocator(const throwing_allocator& rhs) : throw_on_copy_(rhs.throw_on_copy_) {
163 if (throw_on_copy_)
164 throw 0;
165 }
166
167 template <class U>
168 throwing_allocator(const throwing_allocator<U>& rhs) : throw_on_copy_(rhs.throw_on_copy_) {
169 if (throw_on_copy_)
170 throw 0;
171 }
172
173 T* allocate(std::size_t n) { return std::allocator<T>().allocate(n); }
174 void deallocate(T* ptr, std::size_t n) { std::allocator<T>().deallocate(ptr, n); }
175
176 template <class U>
177 friend bool operator==(const throwing_allocator&, const throwing_allocator<U>&) {
178 return true;
179 }
180};
181
182template <class T, class IterCat>
183struct throwing_iterator {
184 using iterator_category = IterCat;
185 using difference_type = std::ptrdiff_t;
186 using value_type = T;
187 using reference = T&;
188 using pointer = T*;
189
190 int i_;
191 T v_;
192
193 explicit throwing_iterator(int i = 0, const T& v = T()) : i_(i), v_(v) {}
194
195 reference operator*() {
196 if (i_ == 1)
197 throw 1;
198 return v_;
199 }
200
201 friend bool operator==(const throwing_iterator& lhs, const throwing_iterator& rhs) { return lhs.i_ == rhs.i_; }
202 friend bool operator!=(const throwing_iterator& lhs, const throwing_iterator& rhs) { return lhs.i_ != rhs.i_; }
203
204 throwing_iterator& operator++() {
205 ++i_;
206 return *this;
207 }
208
209 throwing_iterator operator++(int) {
210 auto tmp = *this;
211 ++i_;
212 return tmp;
213 }
214};
215
216inline void check_new_delete_called() {
217 assert(globalMemCounter.new_called == globalMemCounter.delete_called);
218 assert(globalMemCounter.new_array_called == globalMemCounter.delete_array_called);
219 assert(globalMemCounter.aligned_new_called == globalMemCounter.aligned_delete_called);
220 assert(globalMemCounter.aligned_new_array_called == globalMemCounter.aligned_delete_array_called);
221}
222
223template <class T, typename Alloc>
224void use_unspecified_but_valid_state_vector(std::vector<T, Alloc> const& v) {
225 assert(v.size() >= 0); // make sure it can be called
226 assert(v.capacity() >= 0);
227 assert(v.empty() || !v.empty());
228 for (auto it = v.begin(); it != v.end(); ++it) {
229 auto& element = *it;
230 (void)element;
231 }
232}
233
234static const std::array<char, 62> letters = {
235 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
236 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
237 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
238
239inline std::string getString(std::size_t n, std::size_t len) {
240 std::string s;
241 s.reserve(res: len);
242 for (std::size_t i = 0; i < len; ++i)
243 s += letters[(i * i + n) % letters.size()];
244 return s;
245}
246
247inline std::vector<int> getIntegerInputs(std::size_t n) {
248 std::vector<int> v;
249 v.reserve(n: n);
250 for (std::size_t i = 0; i < n; ++i)
251 v.push_back(x: static_cast<int>(i * i + n));
252 return v;
253}
254
255inline std::vector<std::string> getStringInputsWithLength(std::size_t n, std::size_t len) {
256 std::vector<std::string> v;
257 v.reserve(n: n);
258 for (std::size_t i = 0; i < n; ++i)
259 v.push_back(x: getString(n: i, len));
260 return v;
261}
262
263#endif // TEST_STD_CONTAINERS_SEQUENCES_VECTOR_COMMON_H
264

source code of libcxx/test/std/containers/sequences/vector/common.h