blob: a3af9e1db66d01e23bd6cd836cb4993cc2318a92 [file] [log] [blame]
Marshall Clow354d39c2014-01-16 16:58:45 +00001//===----------------------------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Howard Hinnant07d3ecc2013-06-19 21:29:40 +000010#ifndef MIN_ALLOCATOR_H
11#define MIN_ALLOCATOR_H
12
Eric Fiseliere3981b82014-08-15 04:15:41 +000013#include <cstddef>
Eric Fiselierc7979582016-06-17 19:46:40 +000014#include <cstdlib>
15#include <cstddef>
16#include <cassert>
Eric Fiseliere3981b82014-08-15 04:15:41 +000017
Marshall Clowcbf166a2015-06-03 19:56:43 +000018#include "test_macros.h"
19
Eric Fiseliere3981b82014-08-15 04:15:41 +000020template <class T>
21class bare_allocator
22{
23public:
24 typedef T value_type;
25
Marshall Clowcbf166a2015-06-03 19:56:43 +000026 bare_allocator() TEST_NOEXCEPT {}
Eric Fiseliere3981b82014-08-15 04:15:41 +000027
28 template <class U>
Marshall Clowcbf166a2015-06-03 19:56:43 +000029 bare_allocator(bare_allocator<U>) TEST_NOEXCEPT {}
Eric Fiseliere3981b82014-08-15 04:15:41 +000030
31 T* allocate(std::size_t n)
32 {
33 return static_cast<T*>(::operator new(n*sizeof(T)));
34 }
35
36 void deallocate(T* p, std::size_t)
37 {
38 return ::operator delete(static_cast<void*>(p));
39 }
40
41 friend bool operator==(bare_allocator, bare_allocator) {return true;}
42 friend bool operator!=(bare_allocator x, bare_allocator y) {return !(x == y);}
43};
44
Eric Fiselier5cac7752016-12-14 22:48:38 +000045
46template <class T>
47class no_default_allocator
48{
49#if TEST_STD_VER >= 11
50 no_default_allocator() = delete;
51#else
52 no_default_allocator();
53#endif
54 struct construct_tag {};
55 explicit no_default_allocator(construct_tag) {}
56
57public:
58 static no_default_allocator create() {
59 construct_tag tag;
60 return no_default_allocator(tag);
61 }
62
63public:
64 typedef T value_type;
65
66 template <class U>
67 no_default_allocator(no_default_allocator<U>) TEST_NOEXCEPT {}
68
69 T* allocate(std::size_t n)
70 {
71 return static_cast<T*>(::operator new(n*sizeof(T)));
72 }
73
74 void deallocate(T* p, std::size_t)
75 {
76 return ::operator delete(static_cast<void*>(p));
77 }
78
79 friend bool operator==(no_default_allocator, no_default_allocator) {return true;}
80 friend bool operator!=(no_default_allocator x, no_default_allocator y) {return !(x == y);}
81};
82
Eric Fiselierc7979582016-06-17 19:46:40 +000083struct malloc_allocator_base {
84 static size_t alloc_count;
85 static size_t dealloc_count;
86 static bool disable_default_constructor;
87
88 static size_t outstanding_alloc() {
89 assert(alloc_count >= dealloc_count);
90 return (alloc_count - dealloc_count);
91 }
92
93 static void reset() {
94 assert(outstanding_alloc() == 0);
95 disable_default_constructor = false;
96 alloc_count = 0;
97 dealloc_count = 0;
98 }
99};
100
101
102size_t malloc_allocator_base::alloc_count = 0;
103size_t malloc_allocator_base::dealloc_count = 0;
104bool malloc_allocator_base::disable_default_constructor = false;
105
106
107template <class T>
108class malloc_allocator : public malloc_allocator_base
109{
110public:
111 typedef T value_type;
112
113 malloc_allocator() TEST_NOEXCEPT { assert(!disable_default_constructor); }
114
115 template <class U>
116 malloc_allocator(malloc_allocator<U>) TEST_NOEXCEPT {}
117
118 T* allocate(std::size_t n)
119 {
120 ++alloc_count;
121 return static_cast<T*>(std::malloc(n*sizeof(T)));
122 }
123
124 void deallocate(T* p, std::size_t)
125 {
126 ++dealloc_count;
127 std::free(static_cast<void*>(p));
128 }
129
130 friend bool operator==(malloc_allocator, malloc_allocator) {return true;}
131 friend bool operator!=(malloc_allocator x, malloc_allocator y) {return !(x == y);}
132};
133
Eric Fiseliere3981b82014-08-15 04:15:41 +0000134
Eric Fiselierf2f2a632016-06-14 21:31:42 +0000135#if TEST_STD_VER >= 11
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000136
137#include <memory>
138
Eric Fiselierf9127592017-01-21 00:02:12 +0000139template <class T, class = std::integral_constant<size_t, 0> > class min_pointer;
140template <class T, class ID> class min_pointer<const T, ID>;
141template <class ID> class min_pointer<void, ID>;
142template <class ID> class min_pointer<const void, ID>;
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000143template <class T> class min_allocator;
144
Eric Fiselierf9127592017-01-21 00:02:12 +0000145template <class ID>
146class min_pointer<const void, ID>
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000147{
148 const void* ptr_;
149public:
Marshall Clowcbf166a2015-06-03 19:56:43 +0000150 min_pointer() TEST_NOEXCEPT = default;
151 min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000152 template <class T>
Eric Fiselierf9127592017-01-21 00:02:12 +0000153 min_pointer(min_pointer<T, ID> p) TEST_NOEXCEPT : ptr_(p.ptr_) {}
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000154
155 explicit operator bool() const {return ptr_ != nullptr;}
156
Howard Hinnant3ec1f002013-06-27 19:35:32 +0000157 friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;}
158 friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);}
Eric Fiselierf9127592017-01-21 00:02:12 +0000159 template <class U, class XID> friend class min_pointer;
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000160};
161
Eric Fiselierf9127592017-01-21 00:02:12 +0000162template <class ID>
163class min_pointer<void, ID>
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000164{
165 void* ptr_;
166public:
Marshall Clowcbf166a2015-06-03 19:56:43 +0000167 min_pointer() TEST_NOEXCEPT = default;
168 min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000169 template <class T,
170 class = typename std::enable_if
171 <
172 !std::is_const<T>::value
173 >::type
174 >
Eric Fiselierf9127592017-01-21 00:02:12 +0000175 min_pointer(min_pointer<T, ID> p) TEST_NOEXCEPT : ptr_(p.ptr_) {}
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000176
177 explicit operator bool() const {return ptr_ != nullptr;}
178
Howard Hinnant3ec1f002013-06-27 19:35:32 +0000179 friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;}
180 friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);}
Eric Fiselierf9127592017-01-21 00:02:12 +0000181 template <class U, class XID> friend class min_pointer;
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000182};
183
Eric Fiselierf9127592017-01-21 00:02:12 +0000184template <class T, class ID>
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000185class min_pointer
186{
187 T* ptr_;
188
Marshall Clowcbf166a2015-06-03 19:56:43 +0000189 explicit min_pointer(T* p) TEST_NOEXCEPT : ptr_(p) {}
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000190public:
Marshall Clowcbf166a2015-06-03 19:56:43 +0000191 min_pointer() TEST_NOEXCEPT = default;
192 min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
Eric Fiselierf9127592017-01-21 00:02:12 +0000193 explicit min_pointer(min_pointer<void, ID> p) TEST_NOEXCEPT : ptr_(static_cast<T*>(p.ptr_)) {}
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000194
195 explicit operator bool() const {return ptr_ != nullptr;}
Eric Fiseliere3981b82014-08-15 04:15:41 +0000196
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000197 typedef std::ptrdiff_t difference_type;
198 typedef T& reference;
199 typedef T* pointer;
200 typedef T value_type;
201 typedef std::random_access_iterator_tag iterator_category;
202
203 reference operator*() const {return *ptr_;}
204 pointer operator->() const {return ptr_;}
205
206 min_pointer& operator++() {++ptr_; return *this;}
207 min_pointer operator++(int) {min_pointer tmp(*this); ++ptr_; return tmp;}
208
209 min_pointer& operator--() {--ptr_; return *this;}
210 min_pointer operator--(int) {min_pointer tmp(*this); --ptr_; return tmp;}
211
212 min_pointer& operator+=(difference_type n) {ptr_ += n; return *this;}
213 min_pointer& operator-=(difference_type n) {ptr_ -= n; return *this;}
214
215 min_pointer operator+(difference_type n) const
216 {
217 min_pointer tmp(*this);
218 tmp += n;
219 return tmp;
220 }
221
222 friend min_pointer operator+(difference_type n, min_pointer x)
223 {
224 return x + n;
225 }
226
227 min_pointer operator-(difference_type n) const
228 {
229 min_pointer tmp(*this);
230 tmp -= n;
231 return tmp;
232 }
233
234 friend difference_type operator-(min_pointer x, min_pointer y)
235 {
236 return x.ptr_ - y.ptr_;
237 }
238
239 reference operator[](difference_type n) const {return ptr_[n];}
240
241 friend bool operator< (min_pointer x, min_pointer y) {return x.ptr_ < y.ptr_;}
242 friend bool operator> (min_pointer x, min_pointer y) {return y < x;}
243 friend bool operator<=(min_pointer x, min_pointer y) {return !(y < x);}
244 friend bool operator>=(min_pointer x, min_pointer y) {return !(x < y);}
245
246 static min_pointer pointer_to(T& t) {return min_pointer(std::addressof(t));}
247
Howard Hinnant3ec1f002013-06-27 19:35:32 +0000248 friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;}
249 friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);}
Eric Fiselierf9127592017-01-21 00:02:12 +0000250 template <class U, class XID> friend class min_pointer;
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000251 template <class U> friend class min_allocator;
252};
253
Eric Fiselierf9127592017-01-21 00:02:12 +0000254template <class T, class ID>
255class min_pointer<const T, ID>
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000256{
257 const T* ptr_;
258
259 explicit min_pointer(const T* p) : ptr_(p) {}
260public:
Marshall Clowcbf166a2015-06-03 19:56:43 +0000261 min_pointer() TEST_NOEXCEPT = default;
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000262 min_pointer(std::nullptr_t) : ptr_(nullptr) {}
Eric Fiselierf9127592017-01-21 00:02:12 +0000263 min_pointer(min_pointer<T, ID> p) : ptr_(p.ptr_) {}
264 explicit min_pointer(min_pointer<const void, ID> p) : ptr_(static_cast<const T*>(p.ptr_)) {}
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000265
266 explicit operator bool() const {return ptr_ != nullptr;}
267
268 typedef std::ptrdiff_t difference_type;
269 typedef const T& reference;
270 typedef const T* pointer;
271 typedef const T value_type;
272 typedef std::random_access_iterator_tag iterator_category;
273
274 reference operator*() const {return *ptr_;}
275 pointer operator->() const {return ptr_;}
276
277 min_pointer& operator++() {++ptr_; return *this;}
278 min_pointer operator++(int) {min_pointer tmp(*this); ++ptr_; return tmp;}
279
280 min_pointer& operator--() {--ptr_; return *this;}
281 min_pointer operator--(int) {min_pointer tmp(*this); --ptr_; return tmp;}
282
283 min_pointer& operator+=(difference_type n) {ptr_ += n; return *this;}
284 min_pointer& operator-=(difference_type n) {ptr_ -= n; return *this;}
285
286 min_pointer operator+(difference_type n) const
287 {
288 min_pointer tmp(*this);
289 tmp += n;
290 return tmp;
291 }
292
293 friend min_pointer operator+(difference_type n, min_pointer x)
294 {
295 return x + n;
296 }
297
298 min_pointer operator-(difference_type n) const
299 {
300 min_pointer tmp(*this);
301 tmp -= n;
302 return tmp;
303 }
304
305 friend difference_type operator-(min_pointer x, min_pointer y)
306 {
307 return x.ptr_ - y.ptr_;
308 }
309
310 reference operator[](difference_type n) const {return ptr_[n];}
311
312 friend bool operator< (min_pointer x, min_pointer y) {return x.ptr_ < y.ptr_;}
313 friend bool operator> (min_pointer x, min_pointer y) {return y < x;}
314 friend bool operator<=(min_pointer x, min_pointer y) {return !(y < x);}
315 friend bool operator>=(min_pointer x, min_pointer y) {return !(x < y);}
316
317 static min_pointer pointer_to(const T& t) {return min_pointer(std::addressof(t));}
318
Howard Hinnant3ec1f002013-06-27 19:35:32 +0000319 friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;}
320 friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);}
Eric Fiselierf9127592017-01-21 00:02:12 +0000321 template <class U, class XID> friend class min_pointer;
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000322};
323
Eric Fiselierf9127592017-01-21 00:02:12 +0000324template <class T, class ID>
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000325inline
326bool
Eric Fiselierf9127592017-01-21 00:02:12 +0000327operator==(min_pointer<T, ID> x, std::nullptr_t)
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000328{
329 return !static_cast<bool>(x);
330}
331
Eric Fiselierf9127592017-01-21 00:02:12 +0000332template <class T, class ID>
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000333inline
334bool
Eric Fiselierf9127592017-01-21 00:02:12 +0000335operator==(std::nullptr_t, min_pointer<T, ID> x)
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000336{
337 return !static_cast<bool>(x);
338}
339
Eric Fiselierf9127592017-01-21 00:02:12 +0000340template <class T, class ID>
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000341inline
342bool
Eric Fiselierf9127592017-01-21 00:02:12 +0000343operator!=(min_pointer<T, ID> x, std::nullptr_t)
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000344{
345 return static_cast<bool>(x);
346}
347
Eric Fiselierf9127592017-01-21 00:02:12 +0000348template <class T, class ID>
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000349inline
350bool
Eric Fiselierf9127592017-01-21 00:02:12 +0000351operator!=(std::nullptr_t, min_pointer<T, ID> x)
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000352{
353 return static_cast<bool>(x);
354}
355
356template <class T>
357class min_allocator
358{
359public:
360 typedef T value_type;
361 typedef min_pointer<T> pointer;
362
363 min_allocator() = default;
364 template <class U>
365 min_allocator(min_allocator<U>) {}
366
367 pointer allocate(std::ptrdiff_t n)
368 {
369 return pointer(static_cast<T*>(::operator new(n*sizeof(T))));
370 }
371
372 void deallocate(pointer p, std::ptrdiff_t)
373 {
374 return ::operator delete(p.ptr_);
375 }
376
377 friend bool operator==(min_allocator, min_allocator) {return true;}
378 friend bool operator!=(min_allocator x, min_allocator y) {return !(x == y);}
379};
380
Marshall Clow2a10c962016-08-17 05:58:40 +0000381template <class T>
382class explicit_allocator
383{
384public:
385 typedef T value_type;
386
387 explicit_allocator() TEST_NOEXCEPT {}
388
389 template <class U>
390 explicit explicit_allocator(explicit_allocator<U>) TEST_NOEXCEPT {}
391
392 T* allocate(std::size_t n)
393 {
394 return static_cast<T*>(::operator new(n*sizeof(T)));
395 }
396
397 void deallocate(T* p, std::size_t)
398 {
399 return ::operator delete(static_cast<void*>(p));
400 }
401
402 friend bool operator==(explicit_allocator, explicit_allocator) {return true;}
403 friend bool operator!=(explicit_allocator x, explicit_allocator y) {return !(x == y);}
404};
405
Eric Fiselierf2f2a632016-06-14 21:31:42 +0000406#endif // TEST_STD_VER >= 11
Howard Hinnant07d3ecc2013-06-19 21:29:40 +0000407
408#endif // MIN_ALLOCATOR_H