337 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 NASTY_CONTAINERS_H10#define NASTY_CONTAINERS_H11 12#include <cassert>13#include <cstddef>14#include <vector>15#include <list>16#include <type_traits>17 18#include "test_macros.h"19 20template <class T>21class nasty_vector22{23public:24 typedef typename std::vector<T> nested_container;25 typedef typename nested_container::value_type value_type;26 typedef typename nested_container::reference reference;27 typedef typename nested_container::const_reference const_reference;28 typedef typename nested_container::iterator iterator;29 typedef typename nested_container::const_iterator const_iterator;30 31 typedef typename nested_container::size_type size_type;32 typedef typename nested_container::difference_type difference_type;33 typedef typename nested_container::pointer pointer;34 typedef typename nested_container::const_pointer const_pointer;35 36 typedef typename nested_container::reverse_iterator reverse_iterator;37 typedef typename nested_container::const_reverse_iterator const_reverse_iterator;38 39 nasty_vector() : v_() {}40 explicit nasty_vector(size_type n) : v_(n) {}41 nasty_vector(size_type n, const value_type& value) : v_(n, value) {}42 template <class InputIterator> nasty_vector(InputIterator first, InputIterator last) : v_(first, last) {}43#if TEST_STD_VER >= 1144 nasty_vector(std::initializer_list<value_type> il) : v_(il) {}45#endif46 nasty_vector(const nasty_vector&) = default;47 nasty_vector& operator=(const nasty_vector&) = default;48 ~nasty_vector() {}49 50 template <class InputIterator>51 void assign(InputIterator first, InputIterator last) { v_.assign(first, last); }52 void assign(size_type n, const value_type& u) { v_.assign(n, u); }53#if TEST_STD_VER >= 1154 void assign(std::initializer_list<value_type> il) { v_.assign(il); }55#endif56 57 iterator begin() TEST_NOEXCEPT { return v_.begin(); }58 const_iterator begin() const TEST_NOEXCEPT { return v_.begin(); }59 iterator end() TEST_NOEXCEPT { return v_.end(); }60 const_iterator end() const TEST_NOEXCEPT { return v_.end(); }61 62 reverse_iterator rbegin() TEST_NOEXCEPT { return v_.rbegin(); }63 const_reverse_iterator rbegin() const TEST_NOEXCEPT { return v_.rbegin(); }64 reverse_iterator rend() TEST_NOEXCEPT { return v_.rend(); }65 const_reverse_iterator rend() const TEST_NOEXCEPT { return v_.rend(); }66 67 const_iterator cbegin() const TEST_NOEXCEPT { return v_.cbegin(); }68 const_iterator cend() const TEST_NOEXCEPT { return v_.cend(); }69 const_reverse_iterator crbegin() const TEST_NOEXCEPT { return v_.crbegin(); }70 const_reverse_iterator crend() const TEST_NOEXCEPT { return v_.crend(); }71 72 size_type size() const TEST_NOEXCEPT { return v_.size(); }73 size_type max_size() const TEST_NOEXCEPT { return v_.max_size(); }74 size_type capacity() const TEST_NOEXCEPT { return v_.capacity(); }75 bool empty() const TEST_NOEXCEPT { return v_.empty(); }76 void reserve(size_type n) { v_.reserve(n); };77 void shrink_to_fit() TEST_NOEXCEPT { v_.shrink_to_fit(); }78 79 reference operator[](size_type n) { return v_[n]; }80 const_reference operator[](size_type n) const { return v_[n]; }81 reference at(size_type n) { return v_.at(n); }82 const_reference at(size_type n) const { return v_.at(n); }83 84 reference front() { return v_.front(); }85 const_reference front() const { return v_.front(); }86 reference back() { return v_.back(); }87 const_reference back() const { return v_.back(); }88 89 value_type* data() TEST_NOEXCEPT { return v_.data(); }90 const value_type* data() const TEST_NOEXCEPT { return v_.data(); }91 92 void push_back(const value_type& x) { v_.push_back(x); }93#if TEST_STD_VER >= 1194 void push_back(value_type&& x) { v_.push_back(std::forward<value_type&&>(x)); }95 template <class... Args>96 void emplace_back(Args&&... args) { v_.emplace_back(std::forward<Args>(args)...); }97#endif98 void pop_back() { v_.pop_back(); }99 100#if TEST_STD_VER >= 11101 template <class... Args> iterator emplace(const_iterator pos, Args&&... args)102 { return v_.emplace(pos, std::forward<Args>(args)...); }103#endif104 105 iterator insert(const_iterator pos, const value_type& x) { return v_.insert(pos, x); }106#if TEST_STD_VER >= 11107 iterator insert(const_iterator pos, value_type&& x) { return v_.insert(pos, std::forward<value_type>(x)); }108#endif109 iterator insert(const_iterator pos, size_type n, const value_type& x) { return v_.insert(pos, n, x); }110 template <class InputIterator>111 iterator insert(const_iterator pos, InputIterator first, InputIterator last)112 { return v_.insert(pos, first, last); }113 114#if TEST_STD_VER >= 11115 iterator insert(const_iterator pos, std::initializer_list<value_type> il) { return v_.insert(pos, il); }116#endif117 118 iterator erase(const_iterator pos) { return v_.erase(pos); }119 iterator erase(const_iterator first, const_iterator last) { return v_.erase(first, last); }120 121 void clear() TEST_NOEXCEPT { v_.clear(); }122 123 void resize(size_type sz) { v_.resize(sz); }124 void resize(size_type sz, const value_type& c) { v_.resize(sz, c); }125 126 void swap(nasty_vector& nv)127#if TEST_STD_VER > 14128 noexcept(std::is_nothrow_swappable<nested_container>::value)129#elif defined(_LIBCPP_VERSION)130 TEST_NOEXCEPT_COND(std::__is_nothrow_swappable_v<nested_container>)131#endif132 {133 v_.swap(nv.v_);134 }135 136 nasty_vector *operator &() { assert(false); return nullptr; } // nasty137 const nasty_vector *operator &() const { assert(false); return nullptr; } // nasty138 139 nested_container v_;140};141 142template <class T>143bool operator==(const nasty_vector<T>& x, const nasty_vector<T>& y) { return x.v_ == y.v_; }144 145 146#if TEST_STD_VER >= 20147 148template <class T>149auto operator<=>(const nasty_vector<T>& x, const nasty_vector<T>& y) { return x.v_ <=> y.v_; }150 151#endif152 153template <class T>154class nasty_list155{156public:157 158 typedef typename std::list<T> nested_container;159 typedef typename nested_container::value_type value_type;160 typedef typename nested_container::reference reference;161 typedef typename nested_container::const_reference const_reference;162 typedef typename nested_container::iterator iterator;163 typedef typename nested_container::const_iterator const_iterator;164 165 typedef typename nested_container::size_type size_type;166 typedef typename nested_container::difference_type difference_type;167 typedef typename nested_container::pointer pointer;168 typedef typename nested_container::const_pointer const_pointer;169 170 typedef typename nested_container::reverse_iterator reverse_iterator;171 typedef typename nested_container::const_reverse_iterator const_reverse_iterator;172 173 nasty_list() : l_() {}174 explicit nasty_list(size_type n) : l_(n) {}175 nasty_list(size_type n, const value_type& value) : l_(n,value) {}176 template <class Iter>177 nasty_list(Iter first, Iter last) : l_(first, last) {}178#if TEST_STD_VER >= 11179 nasty_list(std::initializer_list<value_type> il) : l_(il) {}180#endif181 nasty_list(const nasty_list&) = default;182 nasty_list& operator=(const nasty_list&) = default;183 ~nasty_list() {}184 185#if TEST_STD_VER >= 11186 nasty_list& operator=(std::initializer_list<value_type> il) { l_ = il; return *this; }187#endif188 template <class Iter>189 void assign(Iter first, Iter last) { l_.assign(first, last); }190 void assign(size_type n, const value_type& t) { l_.assign(n, t); }191#if TEST_STD_VER >= 11192 void assign(std::initializer_list<value_type> il) { l_.assign(il); }193#endif194 195 196 iterator begin() TEST_NOEXCEPT { return l_.begin(); }197 const_iterator begin() const TEST_NOEXCEPT { return l_.begin(); }198 iterator end() TEST_NOEXCEPT { return l_.end(); }199 const_iterator end() const TEST_NOEXCEPT { return l_.end(); }200 201 reverse_iterator rbegin() TEST_NOEXCEPT { return l_.rbegin(); }202 const_reverse_iterator rbegin() const TEST_NOEXCEPT { return l_.rbegin(); }203 reverse_iterator rend() TEST_NOEXCEPT { return l_.rend(); }204 const_reverse_iterator rend() const TEST_NOEXCEPT { return l_.rend(); }205 206 const_iterator cbegin() const TEST_NOEXCEPT { return l_.cbegin(); }207 const_iterator cend() const TEST_NOEXCEPT { return l_.cend(); }208 const_reverse_iterator crbegin() const TEST_NOEXCEPT { return l_.crbegin(); }209 const_reverse_iterator crend() const TEST_NOEXCEPT { return l_.crend(); }210 211 reference front() { return l_.front(); }212 const_reference front() const { return l_.front(); }213 reference back() { return l_.back(); }214 const_reference back() const { return l_.back(); }215 216 size_type size() const TEST_NOEXCEPT { return l_.size(); }217 size_type max_size() const TEST_NOEXCEPT { return l_.max_size(); }218 bool empty() const TEST_NOEXCEPT { return l_.empty(); }219 220 void push_front(const value_type& x) { l_.push_front(x); }221 void push_back(const value_type& x) { l_.push_back(x); }222#if TEST_STD_VER >= 11223 void push_back(value_type&& x) { l_.push_back(std::forward<value_type&&>(x)); }224 void push_front(value_type&& x) { l_.push_front(std::forward<value_type&&>(x)); }225 template <class... Args>226 void emplace_back(Args&&... args) { l_.emplace_back(std::forward<Args>(args)...); }227 template <class... Args>228 void emplace_front(Args&&... args) { l_.emplace_front(std::forward<Args>(args)...); }229#endif230 void pop_front() { l_.pop_front(); }231 void pop_back() { l_.pop_back(); }232 233#if TEST_STD_VER >= 11234 template <class... Args> iterator emplace(const_iterator pos, Args&&... args)235 { return l_.emplace(pos, std::forward<Args>(args)...); }236#endif237 238 iterator insert(const_iterator pos, const value_type& x) { return l_.insert(pos, x); }239#if TEST_STD_VER >= 11240 iterator insert(const_iterator pos, value_type&& x) { return l_.insert(pos, std::forward<value_type>(x)); }241#endif242 iterator insert(const_iterator pos, size_type n, const value_type& x) { return l_.insert(pos, n, x); }243 template <class InputIterator>244 iterator insert(const_iterator pos, InputIterator first, InputIterator last)245 { return l_.insert(pos, first, last); }246 247#if TEST_STD_VER >= 11248 iterator insert(const_iterator pos, std::initializer_list<value_type> il) { return l_.insert(pos, il); }249#endif250 251 iterator erase(const_iterator pos) { return l_.erase(pos); }252 iterator erase(const_iterator first, const_iterator last) { return l_.erase(first, last); }253 254 void resize(size_type n) { l_.resize(n); }255 void resize(size_type n, const value_type& c) { l_.resize(n, c); }256 257 void swap(nasty_list& nl)258#if TEST_STD_VER > 14259 noexcept(std::is_nothrow_swappable<nested_container>::value)260#elif defined(_LIBCPP_VERSION)261 TEST_NOEXCEPT_COND(std::__is_nothrow_swappable_v<nested_container>)262#endif263 {264 l_.swap(nl.l_);265 }266 267 void clear() TEST_NOEXCEPT { l_.clear(); }268 269// void splice(const_iterator position, list& x);270// void splice(const_iterator position, list&& x);271// void splice(const_iterator position, list& x, const_iterator i);272// void splice(const_iterator position, list&& x, const_iterator i);273// void splice(const_iterator position, list& x, const_iterator first,274// const_iterator last);275// void splice(const_iterator position, list&& x, const_iterator first,276// const_iterator last);277//278// void remove(const value_type& value);279// template <class Pred> void remove_if(Pred pred);280// void unique();281// template <class BinaryPredicate>282// void unique(BinaryPredicate binary_pred);283// void merge(list& x);284// void merge(list&& x);285// template <class Compare>286// void merge(list& x, Compare comp);287// template <class Compare>288// void merge(list&& x, Compare comp);289// void sort();290// template <class Compare>291// void sort(Compare comp);292// void reverse() noexcept;293 294 nasty_list *operator &() { assert(false); return nullptr; } // nasty295 const nasty_list *operator &() const { assert(false); return nullptr; } // nasty296 297 nested_container l_;298};299 300template <class T>301bool operator==(const nasty_list<T>& x, const nasty_list<T>& y) { return x.l_ == y.l_; }302 303#if TEST_STD_VER >= 20304 305template <class T>306auto operator<=>(const nasty_list<T>& x, const nasty_list<T>& y) { return x.l_ <=> y.l_; }307 308#endif309 310// Not really a mutex, but can play one in tests311class nasty_mutex312{313public:314 nasty_mutex() TEST_NOEXCEPT {}315 ~nasty_mutex() {}316 317 nasty_mutex *operator& () { assert(false); return nullptr; }318 template <typename T>319 void operator, (const T &) { assert(false); }320 321private:322 nasty_mutex(const nasty_mutex&) { assert(false); }323 nasty_mutex& operator=(const nasty_mutex&) { assert(false); return *this; }324 325public:326 void lock() {}327 bool try_lock() TEST_NOEXCEPT { return true; }328 void unlock() TEST_NOEXCEPT {}329 330 // Shared ownership331 void lock_shared() {}332 bool try_lock_shared() { return true; }333 void unlock_shared() {}334};335 336#endif337