• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===----------------------------------------------------------------------===//
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 
10 #ifndef MIN_ALLOCATOR_H
11 #define MIN_ALLOCATOR_H
12 
13 #include <cstddef>
14 #include <cstdlib>
15 #include <cstddef>
16 #include <cassert>
17 
18 #include "test_macros.h"
19 
20 template <class T>
21 class bare_allocator
22 {
23 public:
24     typedef T value_type;
25 
bare_allocator()26     bare_allocator() TEST_NOEXCEPT {}
27 
28     template <class U>
bare_allocator(bare_allocator<U>)29     bare_allocator(bare_allocator<U>) TEST_NOEXCEPT {}
30 
allocate(std::size_t n)31     T* allocate(std::size_t n)
32     {
33         return static_cast<T*>(::operator new(n*sizeof(T)));
34     }
35 
deallocate(T * p,std::size_t)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 
45 
46 template <class T>
47 class 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 {};
no_default_allocator(construct_tag)55     explicit no_default_allocator(construct_tag) {}
56 
57 public:
create()58     static no_default_allocator create() {
59       construct_tag tag;
60       return no_default_allocator(tag);
61     }
62 
63 public:
64     typedef T value_type;
65 
66     template <class U>
no_default_allocator(no_default_allocator<U>)67     no_default_allocator(no_default_allocator<U>) TEST_NOEXCEPT {}
68 
allocate(std::size_t n)69     T* allocate(std::size_t n)
70     {
71         return static_cast<T*>(::operator new(n*sizeof(T)));
72     }
73 
deallocate(T * p,std::size_t)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 
83 struct malloc_allocator_base {
84     static size_t alloc_count;
85     static size_t dealloc_count;
86     static bool disable_default_constructor;
87 
outstanding_allocmalloc_allocator_base88     static size_t outstanding_alloc() {
89       assert(alloc_count >= dealloc_count);
90       return (alloc_count - dealloc_count);
91     }
92 
resetmalloc_allocator_base93     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 
102 size_t malloc_allocator_base::alloc_count = 0;
103 size_t malloc_allocator_base::dealloc_count = 0;
104 bool malloc_allocator_base::disable_default_constructor = false;
105 
106 
107 template <class T>
108 class malloc_allocator : public malloc_allocator_base
109 {
110 public:
111     typedef T value_type;
112 
malloc_allocator()113     malloc_allocator() TEST_NOEXCEPT { assert(!disable_default_constructor); }
114 
115     template <class U>
malloc_allocator(malloc_allocator<U>)116     malloc_allocator(malloc_allocator<U>) TEST_NOEXCEPT {}
117 
allocate(std::size_t n)118     T* allocate(std::size_t n)
119     {
120         ++alloc_count;
121         return static_cast<T*>(std::malloc(n*sizeof(T)));
122     }
123 
deallocate(T * p,std::size_t)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 
134 
135 #if TEST_STD_VER >= 11
136 
137 #include <memory>
138 
139 template <class T, class = std::integral_constant<size_t, 0> > class min_pointer;
140 template <class T, class ID> class min_pointer<const T, ID>;
141 template <class ID> class min_pointer<void, ID>;
142 template <class ID> class min_pointer<const void, ID>;
143 template <class T> class min_allocator;
144 
145 template <class ID>
146 class min_pointer<const void, ID>
147 {
148     const void* ptr_;
149 public:
150     min_pointer() TEST_NOEXCEPT = default;
min_pointer(std::nullptr_t)151     min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
152     template <class T>
min_pointer(min_pointer<T,ID> p)153     min_pointer(min_pointer<T, ID> p) TEST_NOEXCEPT : ptr_(p.ptr_) {}
154 
155     explicit operator bool() const {return ptr_ != nullptr;}
156 
157     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);}
159     template <class U, class XID> friend class min_pointer;
160 };
161 
162 template <class ID>
163 class min_pointer<void, ID>
164 {
165     void* ptr_;
166 public:
167     min_pointer() TEST_NOEXCEPT = default;
min_pointer(std::nullptr_t)168     min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
169     template <class T,
170               class = typename std::enable_if
171                        <
172                             !std::is_const<T>::value
173                        >::type
174              >
min_pointer(min_pointer<T,ID> p)175     min_pointer(min_pointer<T, ID> p) TEST_NOEXCEPT : ptr_(p.ptr_) {}
176 
177     explicit operator bool() const {return ptr_ != nullptr;}
178 
179     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);}
181     template <class U, class XID> friend class min_pointer;
182 };
183 
184 template <class T, class ID>
185 class min_pointer
186 {
187     T* ptr_;
188 
min_pointer(T * p)189     explicit min_pointer(T* p) TEST_NOEXCEPT : ptr_(p) {}
190 public:
191     min_pointer() TEST_NOEXCEPT = default;
min_pointer(std::nullptr_t)192     min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
min_pointer(min_pointer<void,ID> p)193     explicit min_pointer(min_pointer<void, ID> p) TEST_NOEXCEPT : ptr_(static_cast<T*>(p.ptr_)) {}
194 
195     explicit operator bool() const {return ptr_ != nullptr;}
196 
197     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 
pointer_to(T & t)246     static min_pointer pointer_to(T& t) {return min_pointer(std::addressof(t));}
247 
248     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);}
250     template <class U, class XID> friend class min_pointer;
251     template <class U> friend class min_allocator;
252 };
253 
254 template <class T, class ID>
255 class min_pointer<const T, ID>
256 {
257     const T* ptr_;
258 
min_pointer(const T * p)259     explicit min_pointer(const T* p) : ptr_(p) {}
260 public:
261     min_pointer() TEST_NOEXCEPT = default;
min_pointer(std::nullptr_t)262     min_pointer(std::nullptr_t) : ptr_(nullptr) {}
min_pointer(min_pointer<T,ID> p)263     min_pointer(min_pointer<T, ID> p) : ptr_(p.ptr_) {}
min_pointer(min_pointer<const void,ID> p)264     explicit min_pointer(min_pointer<const void, ID> p) : ptr_(static_cast<const T*>(p.ptr_)) {}
265 
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 
pointer_to(const T & t)317     static min_pointer pointer_to(const T& t) {return min_pointer(std::addressof(t));}
318 
319     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);}
321     template <class U, class XID> friend class min_pointer;
322 };
323 
324 template <class T, class ID>
325 inline
326 bool
327 operator==(min_pointer<T, ID> x, std::nullptr_t)
328 {
329     return !static_cast<bool>(x);
330 }
331 
332 template <class T, class ID>
333 inline
334 bool
335 operator==(std::nullptr_t, min_pointer<T, ID> x)
336 {
337     return !static_cast<bool>(x);
338 }
339 
340 template <class T, class ID>
341 inline
342 bool
343 operator!=(min_pointer<T, ID> x, std::nullptr_t)
344 {
345     return static_cast<bool>(x);
346 }
347 
348 template <class T, class ID>
349 inline
350 bool
351 operator!=(std::nullptr_t, min_pointer<T, ID> x)
352 {
353     return static_cast<bool>(x);
354 }
355 
356 template <class T>
357 class min_allocator
358 {
359 public:
360     typedef T value_type;
361     typedef min_pointer<T> pointer;
362 
363     min_allocator() = default;
364     template <class U>
min_allocator(min_allocator<U>)365     min_allocator(min_allocator<U>) {}
366 
allocate(std::ptrdiff_t n)367     pointer allocate(std::ptrdiff_t n)
368     {
369         return pointer(static_cast<T*>(::operator new(n*sizeof(T))));
370     }
371 
deallocate(pointer p,std::ptrdiff_t)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 
381 template <class T>
382 class explicit_allocator
383 {
384 public:
385     typedef T value_type;
386 
explicit_allocator()387     explicit_allocator() TEST_NOEXCEPT {}
388 
389     template <class U>
explicit_allocator(explicit_allocator<U>)390     explicit explicit_allocator(explicit_allocator<U>) TEST_NOEXCEPT {}
391 
allocate(std::size_t n)392     T* allocate(std::size_t n)
393     {
394         return static_cast<T*>(::operator new(n*sizeof(T)));
395     }
396 
deallocate(T * p,std::size_t)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 
406 #endif  // TEST_STD_VER >= 11
407 
408 #endif  // MIN_ALLOCATOR_H
409