xref: /llvm-project/libcxx/test/support/nasty_containers.h (revision cb417401879ce70b441a999c4a30f7b64b8d426b)
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 NASTY_CONTAINERS_H
10 #define NASTY_CONTAINERS_H
11 
12 #include <cassert>
13 #include <cstddef>
14 #include <vector>
15 #include <list>
16 #include <type_traits>
17 
18 #include "test_macros.h"
19 
20 template <class T>
21 class nasty_vector
22 {
23 public:
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 
nasty_vector()39     nasty_vector() : v_() {}
nasty_vector(size_type n)40     explicit nasty_vector(size_type n) : v_(n) {}
nasty_vector(size_type n,const value_type & value)41     nasty_vector(size_type n, const value_type& value) : v_(n, value) {}
nasty_vector(InputIterator first,InputIterator last)42     template <class InputIterator> nasty_vector(InputIterator first, InputIterator last) : v_(first, last) {}
43 #if TEST_STD_VER >= 11
nasty_vector(std::initializer_list<value_type> il)44     nasty_vector(std::initializer_list<value_type> il) : v_(il) {}
45 #endif
46     nasty_vector(const nasty_vector&) = default;
47     nasty_vector& operator=(const nasty_vector&) = default;
~nasty_vector()48     ~nasty_vector() {}
49 
50     template <class InputIterator>
assign(InputIterator first,InputIterator last)51         void assign(InputIterator first, InputIterator last) { v_.assign(first, last); }
assign(size_type n,const value_type & u)52     void assign(size_type n, const value_type& u) { v_.assign(n, u); }
53 #if TEST_STD_VER >= 11
assign(std::initializer_list<value_type> il)54     void assign(std::initializer_list<value_type> il)  { v_.assign(il); }
55 #endif
56 
begin()57     iterator               begin() TEST_NOEXCEPT         { return v_.begin(); }
begin()58     const_iterator         begin()   const TEST_NOEXCEPT { return v_.begin(); }
end()59     iterator               end() TEST_NOEXCEPT           { return v_.end(); }
end()60     const_iterator         end()     const TEST_NOEXCEPT { return v_.end(); }
61 
rbegin()62     reverse_iterator       rbegin() TEST_NOEXCEPT        { return v_.rbegin(); }
rbegin()63     const_reverse_iterator rbegin()  const TEST_NOEXCEPT { return v_.rbegin(); }
rend()64     reverse_iterator       rend() TEST_NOEXCEPT          { return v_.rend(); }
rend()65     const_reverse_iterator rend()    const TEST_NOEXCEPT { return v_.rend(); }
66 
cbegin()67     const_iterator         cbegin()  const TEST_NOEXCEPT { return v_.cbegin(); }
cend()68     const_iterator         cend()    const TEST_NOEXCEPT { return v_.cend(); }
crbegin()69     const_reverse_iterator crbegin() const TEST_NOEXCEPT { return v_.crbegin(); }
crend()70     const_reverse_iterator crend()   const TEST_NOEXCEPT { return v_.crend(); }
71 
size()72     size_type size() const TEST_NOEXCEPT      { return v_.size(); }
max_size()73     size_type max_size() const TEST_NOEXCEPT  { return v_.max_size(); }
capacity()74     size_type capacity() const TEST_NOEXCEPT  { return v_.capacity(); }
empty()75     bool empty() const TEST_NOEXCEPT          { return v_.empty(); }
reserve(size_type n)76     void reserve(size_type n)             { v_.reserve(n); };
shrink_to_fit()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]; }
at(size_type n)81     reference       at(size_type n)               { return v_.at(n); }
at(size_type n)82     const_reference at(size_type n) const         { return v_.at(n); }
83 
front()84     reference       front()       { return v_.front(); }
front()85     const_reference front() const { return v_.front(); }
back()86     reference       back()        { return v_.back(); }
back()87     const_reference back() const  { return v_.back(); }
88 
data()89     value_type*       data() TEST_NOEXCEPT       { return v_.data(); }
data()90     const value_type* data() const TEST_NOEXCEPT { return v_.data(); }
91 
push_back(const value_type & x)92     void push_back(const value_type& x)     { v_.push_back(x); }
93 #if TEST_STD_VER >= 11
push_back(value_type && x)94     void push_back(value_type&& x)          { v_.push_back(std::forward<value_type&&>(x)); }
95     template <class... Args>
emplace_back(Args &&...args)96         void emplace_back(Args&&... args)   { v_.emplace_back(std::forward<Args>(args)...); }
97 #endif
pop_back()98     void pop_back()                         { v_.pop_back(); }
99 
100 #if TEST_STD_VER >= 11
emplace(const_iterator pos,Args &&...args)101     template <class... Args> iterator emplace(const_iterator pos, Args&&... args)
102     { return v_.emplace(pos, std::forward<Args>(args)...); }
103 #endif
104 
insert(const_iterator pos,const value_type & x)105     iterator insert(const_iterator pos, const value_type& x) { return v_.insert(pos, x); }
106 #if TEST_STD_VER >= 11
insert(const_iterator pos,value_type && x)107     iterator insert(const_iterator pos, value_type&& x)      { return v_.insert(pos, std::forward<value_type>(x)); }
108 #endif
insert(const_iterator pos,size_type n,const value_type & x)109     iterator insert(const_iterator pos, size_type n, const value_type& x) { return v_.insert(pos, n, x); }
110     template <class InputIterator>
insert(const_iterator pos,InputIterator first,InputIterator last)111         iterator insert(const_iterator pos, InputIterator first, InputIterator last)
112     { return v_.insert(pos, first, last); }
113 
114 #if TEST_STD_VER >= 11
insert(const_iterator pos,std::initializer_list<value_type> il)115     iterator insert(const_iterator pos, std::initializer_list<value_type> il) { return v_.insert(pos, il); }
116 #endif
117 
erase(const_iterator pos)118     iterator erase(const_iterator pos)                        { return v_.erase(pos); }
erase(const_iterator first,const_iterator last)119     iterator erase(const_iterator first, const_iterator last) { return v_.erase(first, last); }
120 
clear()121     void clear() TEST_NOEXCEPT { v_.clear(); }
122 
resize(size_type sz)123     void resize(size_type sz)                      { v_.resize(sz); }
resize(size_type sz,const value_type & c)124     void resize(size_type sz, const value_type& c) { v_.resize(sz, c); }
125 
swap(nasty_vector & nv)126     void swap(nasty_vector& nv)
127 #if TEST_STD_VER > 14
128         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 #endif
132     {
133       v_.swap(nv.v_);
134     }
135 
136     nasty_vector *operator &()             { assert(false); return nullptr; }  // nasty
137     const nasty_vector *operator &() const { assert(false); return nullptr; }  // nasty
138 
139     nested_container v_;
140 };
141 
142 template <class T>
143 bool operator==(const nasty_vector<T>& x, const nasty_vector<T>& y) { return x.v_ == y.v_; }
144 
145 
146 #if TEST_STD_VER >= 20
147 
148 template <class T>
149 auto operator<=>(const nasty_vector<T>& x, const nasty_vector<T>& y) { return x.v_ <=> y.v_; }
150 
151 #endif
152 
153 template <class T>
154 class nasty_list
155 {
156 public:
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 
nasty_list()173     nasty_list() : l_() {}
nasty_list(size_type n)174     explicit nasty_list(size_type n)  : l_(n) {}
nasty_list(size_type n,const value_type & value)175     nasty_list(size_type n, const value_type& value)  : l_(n,value) {}
176     template <class Iter>
nasty_list(Iter first,Iter last)177         nasty_list(Iter first, Iter last)  : l_(first, last) {}
178 #if TEST_STD_VER >= 11
nasty_list(std::initializer_list<value_type> il)179     nasty_list(std::initializer_list<value_type> il) : l_(il) {}
180 #endif
181     nasty_list(const nasty_list&) = default;
182     nasty_list& operator=(const nasty_list&) = default;
~nasty_list()183     ~nasty_list() {}
184 
185 #if TEST_STD_VER >= 11
186     nasty_list& operator=(std::initializer_list<value_type> il) { l_ = il; return *this; }
187 #endif
188     template <class Iter>
assign(Iter first,Iter last)189         void assign(Iter first, Iter last) { l_.assign(first, last); }
assign(size_type n,const value_type & t)190     void assign(size_type n, const value_type& t) { l_.assign(n, t); }
191 #if TEST_STD_VER >= 11
assign(std::initializer_list<value_type> il)192     void assign(std::initializer_list<value_type> il) { l_.assign(il); }
193 #endif
194 
195 
begin()196     iterator               begin() TEST_NOEXCEPT         { return l_.begin(); }
begin()197     const_iterator         begin()   const TEST_NOEXCEPT { return l_.begin(); }
end()198     iterator               end() TEST_NOEXCEPT           { return l_.end(); }
end()199     const_iterator         end()     const TEST_NOEXCEPT { return l_.end(); }
200 
rbegin()201     reverse_iterator       rbegin() TEST_NOEXCEPT        { return l_.rbegin(); }
rbegin()202     const_reverse_iterator rbegin()  const TEST_NOEXCEPT { return l_.rbegin(); }
rend()203     reverse_iterator       rend() TEST_NOEXCEPT          { return l_.rend(); }
rend()204     const_reverse_iterator rend()    const TEST_NOEXCEPT { return l_.rend(); }
205 
cbegin()206     const_iterator         cbegin()  const TEST_NOEXCEPT { return l_.cbegin(); }
cend()207     const_iterator         cend()    const TEST_NOEXCEPT { return l_.cend(); }
crbegin()208     const_reverse_iterator crbegin() const TEST_NOEXCEPT { return l_.crbegin(); }
crend()209     const_reverse_iterator crend()   const TEST_NOEXCEPT { return l_.crend(); }
210 
front()211     reference       front()       { return l_.front(); }
front()212     const_reference front() const { return l_.front(); }
back()213     reference       back()        { return l_.back(); }
back()214     const_reference back() const  { return l_.back(); }
215 
size()216     size_type size() const TEST_NOEXCEPT      { return l_.size(); }
max_size()217     size_type max_size() const TEST_NOEXCEPT  { return l_.max_size(); }
empty()218     bool empty() const TEST_NOEXCEPT          { return l_.empty(); }
219 
push_front(const value_type & x)220     void push_front(const value_type& x)    { l_.push_front(x); }
push_back(const value_type & x)221     void push_back(const value_type& x)     { l_.push_back(x); }
222 #if TEST_STD_VER >= 11
push_back(value_type && x)223     void push_back(value_type&& x)          { l_.push_back(std::forward<value_type&&>(x)); }
push_front(value_type && x)224     void push_front(value_type&& x)         { l_.push_front(std::forward<value_type&&>(x)); }
225     template <class... Args>
emplace_back(Args &&...args)226         void emplace_back(Args&&... args)   { l_.emplace_back(std::forward<Args>(args)...); }
227     template <class... Args>
emplace_front(Args &&...args)228         void emplace_front(Args&&... args)  { l_.emplace_front(std::forward<Args>(args)...); }
229 #endif
pop_front()230     void pop_front()                        { l_.pop_front(); }
pop_back()231     void pop_back()                         { l_.pop_back(); }
232 
233 #if TEST_STD_VER >= 11
emplace(const_iterator pos,Args &&...args)234     template <class... Args> iterator emplace(const_iterator pos, Args&&... args)
235     { return l_.emplace(pos, std::forward<Args>(args)...); }
236 #endif
237 
insert(const_iterator pos,const value_type & x)238     iterator insert(const_iterator pos, const value_type& x) { return l_.insert(pos, x); }
239 #if TEST_STD_VER >= 11
insert(const_iterator pos,value_type && x)240     iterator insert(const_iterator pos, value_type&& x)      { return l_.insert(pos, std::forward<value_type>(x)); }
241 #endif
insert(const_iterator pos,size_type n,const value_type & x)242     iterator insert(const_iterator pos, size_type n, const value_type& x) { return l_.insert(pos, n, x); }
243     template <class InputIterator>
insert(const_iterator pos,InputIterator first,InputIterator last)244         iterator insert(const_iterator pos, InputIterator first, InputIterator last)
245     { return l_.insert(pos, first, last); }
246 
247 #if TEST_STD_VER >= 11
insert(const_iterator pos,std::initializer_list<value_type> il)248     iterator insert(const_iterator pos, std::initializer_list<value_type> il) { return l_.insert(pos, il); }
249 #endif
250 
erase(const_iterator pos)251     iterator erase(const_iterator pos)                      { return l_.erase(pos); }
erase(const_iterator first,const_iterator last)252     iterator erase(const_iterator first, const_iterator last) { return l_.erase(first, last); }
253 
resize(size_type n)254     void resize(size_type n)                      { l_.resize(n); }
resize(size_type n,const value_type & c)255     void resize(size_type n, const value_type& c) { l_.resize(n, c); }
256 
swap(nasty_list & nl)257     void swap(nasty_list& nl)
258 #if TEST_STD_VER > 14
259         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 #endif
263     {
264       l_.swap(nl.l_);
265     }
266 
clear()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; }  // nasty
295     const nasty_list *operator &() const { assert(false); return nullptr; }  // nasty
296 
297     nested_container l_;
298 };
299 
300 template <class T>
301 bool operator==(const nasty_list<T>& x, const nasty_list<T>& y) { return x.l_ == y.l_; }
302 
303 #if TEST_STD_VER >= 20
304 
305 template <class T>
306 auto operator<=>(const nasty_list<T>& x, const nasty_list<T>& y) { return x.l_ <=> y.l_; }
307 
308 #endif
309 
310 // Not really a mutex, but can play one in tests
311 class nasty_mutex
312 {
313 public:
nasty_mutex()314      nasty_mutex() TEST_NOEXCEPT {}
~nasty_mutex()315      ~nasty_mutex() {}
316 
317     nasty_mutex *operator& ()   { assert(false); return nullptr; }
318     template <typename T>
319     void operator, (const T &) { assert(false); }
320 
321 private:
nasty_mutex(const nasty_mutex &)322     nasty_mutex(const nasty_mutex&)            { assert(false); }
323     nasty_mutex& operator=(const nasty_mutex&) { assert(false); return *this; }
324 
325 public:
lock()326     void lock()               {}
try_lock()327     bool try_lock() TEST_NOEXCEPT { return true; }
unlock()328     void unlock() TEST_NOEXCEPT   {}
329 
330     // Shared ownership
lock_shared()331     void lock_shared()     {}
try_lock_shared()332     bool try_lock_shared() { return true; }
unlock_shared()333     void unlock_shared()   {}
334 };
335 
336 #endif
337