264 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef TEST_STD_CONTAINERS_SEQUENCES_VECTOR_COMMON_H10#define TEST_STD_CONTAINERS_SEQUENCES_VECTOR_COMMON_H11 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 >= 1158 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#endif112 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_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.new_called == globalMemCounter.delete_called);218 ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.new_array_called == globalMemCounter.delete_array_called);219 ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(globalMemCounter.aligned_new_called == globalMemCounter.aligned_delete_called);220 ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(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 called226 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(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);250 for (std::size_t i = 0; i < n; ++i)251 v.push_back(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);258 for (std::size_t i = 0; i < n; ++i)259 v.push_back(getString(i, len));260 return v;261}262 263#endif // TEST_STD_CONTAINERS_SEQUENCES_VECTOR_COMMON_H264