[Github] Bump Windows Actions Runner to v2.321.0 (#123508)
[llvm-project.git] / libcxx / test / std / containers / sequences / vector / common.h
blob4af6559a06e737176bbe6c4354de113cf6ff3700
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 //===----------------------------------------------------------------------===//
9 #ifndef TEST_STD_CONTAINERS_SEQUENCES_VECTOR_COMMON_H
10 #define TEST_STD_CONTAINERS_SEQUENCES_VECTOR_COMMON_H
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>
22 #include "count_new.h"
23 #include "test_macros.h"
25 struct throwing_t {
26 int* throw_after_n_ = nullptr;
27 throwing_t() { throw 0; }
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;
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_;
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;
49 friend bool operator==(const throwing_t& lhs, const throwing_t& rhs) {
50 return lhs.throw_after_n_ == rhs.throw_after_n_;
52 friend bool operator!=(const throwing_t& lhs, const throwing_t& rhs) {
53 return lhs.throw_after_n_ != rhs.throw_after_n_;
57 #if TEST_STD_VER >= 11
59 template <typename T>
60 struct move_only_throwing_t {
61 T data_;
62 int* throw_after_n_ = nullptr;
63 bool moved_from_ = false;
65 move_only_throwing_t() = default;
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;
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;
79 move_only_throwing_t(const move_only_throwing_t&) = delete;
80 move_only_throwing_t& operator=(const move_only_throwing_t&) = delete;
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_;
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;
103 friend bool operator==(const move_only_throwing_t& lhs, const move_only_throwing_t& rhs) {
104 return lhs.data_ == rhs.data_;
106 friend bool operator!=(const move_only_throwing_t& lhs, const move_only_throwing_t& rhs) {
107 return lhs.data_ != rhs.data_;
111 #endif
113 template <typename T>
114 struct throwing_data {
115 T data_;
116 int* throw_after_n_ = nullptr;
117 throwing_data() { throw 0; }
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;
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_;
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;
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_;
143 friend bool operator!=(const throwing_data& lhs, const throwing_data& rhs) { return !(lhs == rhs); }
146 template <class T>
147 struct throwing_allocator {
148 using value_type = T;
150 bool throw_on_copy_ = false;
152 explicit throwing_allocator(bool throw_on_ctor = true) {
153 if (throw_on_ctor)
154 throw 0;
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;
162 throwing_allocator(const throwing_allocator& rhs) : throw_on_copy_(rhs.throw_on_copy_) {
163 if (throw_on_copy_)
164 throw 0;
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;
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); }
176 template <class U>
177 friend bool operator==(const throwing_allocator&, const throwing_allocator<U>&) {
178 return true;
182 template <class T, class IterCat>
183 struct 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*;
190 int i_;
191 T v_;
193 explicit throwing_iterator(int i = 0, const T& v = T()) : i_(i), v_(v) {}
195 reference operator*() {
196 if (i_ == 1)
197 throw 1;
198 return v_;
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_; }
204 throwing_iterator& operator++() {
205 ++i_;
206 return *this;
209 throwing_iterator operator++(int) {
210 auto tmp = *this;
211 ++i_;
212 return tmp;
216 inline 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);
223 template <class T, typename Alloc>
224 void 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;
234 static 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'};
239 inline std::string getString(std::size_t n, std::size_t len) {
240 std::string s;
241 s.reserve(len);
242 for (std::size_t i = 0; i < len; ++i)
243 s += letters[(i * i + n) % letters.size()];
244 return s;
247 inline std::vector<int> getIntegerInputs(std::size_t n) {
248 std::vector<int> v;
249 v.reserve(n);
250 for (std::size_t i = 0; i < n; ++i)
251 v.push_back(static_cast<int>(i * i + n));
252 return v;
255 inline std::vector<std::string> getStringInputsWithLength(std::size_t n, std::size_t len) {
256 std::vector<std::string> v;
257 v.reserve(n);
258 for (std::size_t i = 0; i < n; ++i)
259 v.push_back(getString(i, len));
260 return v;
263 #endif // TEST_STD_CONTAINERS_SEQUENCES_VECTOR_COMMON_H