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 
15 #include "test_macros.h"
16 
17 template <class T>
18 class bare_allocator
19 {
20 public:
21     typedef T value_type;
22 
bare_allocator()23     bare_allocator() TEST_NOEXCEPT {}
24 
25     template <class U>
bare_allocator(bare_allocator<U>)26     bare_allocator(bare_allocator<U>) TEST_NOEXCEPT {}
27 
allocate(std::size_t n)28     T* allocate(std::size_t n)
29     {
30         return static_cast<T*>(::operator new(n*sizeof(T)));
31     }
32 
deallocate(T * p,std::size_t)33     void deallocate(T* p, std::size_t)
34     {
35         return ::operator delete(static_cast<void*>(p));
36     }
37 
38     friend bool operator==(bare_allocator, bare_allocator) {return true;}
39     friend bool operator!=(bare_allocator x, bare_allocator y) {return !(x == y);}
40 };
41 
42 
43 #if __cplusplus >= 201103L
44 
45 #include <memory>
46 
47 template <class T> class min_pointer;
48 template <class T> class min_pointer<const T>;
49 template <> class min_pointer<void>;
50 template <> class min_pointer<const void>;
51 template <class T> class min_allocator;
52 
53 template <>
54 class min_pointer<const void>
55 {
56     const void* ptr_;
57 public:
58     min_pointer() TEST_NOEXCEPT = default;
min_pointer(std::nullptr_t)59     min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
60     template <class T>
min_pointer(min_pointer<T> p)61     min_pointer(min_pointer<T> p) TEST_NOEXCEPT : ptr_(p.ptr_) {}
62 
63     explicit operator bool() const {return ptr_ != nullptr;}
64 
65     friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;}
66     friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);}
67     template <class U> friend class min_pointer;
68 };
69 
70 template <>
71 class min_pointer<void>
72 {
73     void* ptr_;
74 public:
75     min_pointer() TEST_NOEXCEPT = default;
min_pointer(std::nullptr_t)76     min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
77     template <class T,
78               class = typename std::enable_if
79                        <
80                             !std::is_const<T>::value
81                        >::type
82              >
min_pointer(min_pointer<T> p)83     min_pointer(min_pointer<T> p) TEST_NOEXCEPT : ptr_(p.ptr_) {}
84 
85     explicit operator bool() const {return ptr_ != nullptr;}
86 
87     friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;}
88     friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);}
89     template <class U> friend class min_pointer;
90 };
91 
92 template <class T>
93 class min_pointer
94 {
95     T* ptr_;
96 
min_pointer(T * p)97     explicit min_pointer(T* p) TEST_NOEXCEPT : ptr_(p) {}
98 public:
99     min_pointer() TEST_NOEXCEPT = default;
min_pointer(std::nullptr_t)100     min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
min_pointer(min_pointer<void> p)101     explicit min_pointer(min_pointer<void> p) TEST_NOEXCEPT : ptr_(static_cast<T*>(p.ptr_)) {}
102 
103     explicit operator bool() const {return ptr_ != nullptr;}
104 
105     typedef std::ptrdiff_t difference_type;
106     typedef T& reference;
107     typedef T* pointer;
108     typedef T value_type;
109     typedef std::random_access_iterator_tag iterator_category;
110 
111     reference operator*() const {return *ptr_;}
112     pointer operator->() const {return ptr_;}
113 
114     min_pointer& operator++() {++ptr_; return *this;}
115     min_pointer operator++(int) {min_pointer tmp(*this); ++ptr_; return tmp;}
116 
117     min_pointer& operator--() {--ptr_; return *this;}
118     min_pointer operator--(int) {min_pointer tmp(*this); --ptr_; return tmp;}
119 
120     min_pointer& operator+=(difference_type n) {ptr_ += n; return *this;}
121     min_pointer& operator-=(difference_type n) {ptr_ -= n; return *this;}
122 
123     min_pointer operator+(difference_type n) const
124     {
125         min_pointer tmp(*this);
126         tmp += n;
127         return tmp;
128     }
129 
130     friend min_pointer operator+(difference_type n, min_pointer x)
131     {
132         return x + n;
133     }
134 
135     min_pointer operator-(difference_type n) const
136     {
137         min_pointer tmp(*this);
138         tmp -= n;
139         return tmp;
140     }
141 
142     friend difference_type operator-(min_pointer x, min_pointer y)
143     {
144         return x.ptr_ - y.ptr_;
145     }
146 
147     reference operator[](difference_type n) const {return ptr_[n];}
148 
149     friend bool operator< (min_pointer x, min_pointer y) {return x.ptr_ < y.ptr_;}
150     friend bool operator> (min_pointer x, min_pointer y) {return y < x;}
151     friend bool operator<=(min_pointer x, min_pointer y) {return !(y < x);}
152     friend bool operator>=(min_pointer x, min_pointer y) {return !(x < y);}
153 
pointer_to(T & t)154     static min_pointer pointer_to(T& t) {return min_pointer(std::addressof(t));}
155 
156     friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;}
157     friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);}
158     template <class U> friend class min_pointer;
159     template <class U> friend class min_allocator;
160 };
161 
162 template <class T>
163 class min_pointer<const T>
164 {
165     const T* ptr_;
166 
min_pointer(const T * p)167     explicit min_pointer(const T* p) : ptr_(p) {}
168 public:
169     min_pointer() TEST_NOEXCEPT = default;
min_pointer(std::nullptr_t)170     min_pointer(std::nullptr_t) : ptr_(nullptr) {}
min_pointer(min_pointer<T> p)171     min_pointer(min_pointer<T> p) : ptr_(p.ptr_) {}
min_pointer(min_pointer<const void> p)172     explicit min_pointer(min_pointer<const void> p) : ptr_(static_cast<const T*>(p.ptr_)) {}
173 
174     explicit operator bool() const {return ptr_ != nullptr;}
175 
176     typedef std::ptrdiff_t difference_type;
177     typedef const T& reference;
178     typedef const T* pointer;
179     typedef const T value_type;
180     typedef std::random_access_iterator_tag iterator_category;
181 
182     reference operator*() const {return *ptr_;}
183     pointer operator->() const {return ptr_;}
184 
185     min_pointer& operator++() {++ptr_; return *this;}
186     min_pointer operator++(int) {min_pointer tmp(*this); ++ptr_; return tmp;}
187 
188     min_pointer& operator--() {--ptr_; return *this;}
189     min_pointer operator--(int) {min_pointer tmp(*this); --ptr_; return tmp;}
190 
191     min_pointer& operator+=(difference_type n) {ptr_ += n; return *this;}
192     min_pointer& operator-=(difference_type n) {ptr_ -= n; return *this;}
193 
194     min_pointer operator+(difference_type n) const
195     {
196         min_pointer tmp(*this);
197         tmp += n;
198         return tmp;
199     }
200 
201     friend min_pointer operator+(difference_type n, min_pointer x)
202     {
203         return x + n;
204     }
205 
206     min_pointer operator-(difference_type n) const
207     {
208         min_pointer tmp(*this);
209         tmp -= n;
210         return tmp;
211     }
212 
213     friend difference_type operator-(min_pointer x, min_pointer y)
214     {
215         return x.ptr_ - y.ptr_;
216     }
217 
218     reference operator[](difference_type n) const {return ptr_[n];}
219 
220     friend bool operator< (min_pointer x, min_pointer y) {return x.ptr_ < y.ptr_;}
221     friend bool operator> (min_pointer x, min_pointer y) {return y < x;}
222     friend bool operator<=(min_pointer x, min_pointer y) {return !(y < x);}
223     friend bool operator>=(min_pointer x, min_pointer y) {return !(x < y);}
224 
pointer_to(const T & t)225     static min_pointer pointer_to(const T& t) {return min_pointer(std::addressof(t));}
226 
227     friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;}
228     friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);}
229     template <class U> friend class min_pointer;
230 };
231 
232 template <class T>
233 inline
234 bool
235 operator==(min_pointer<T> x, std::nullptr_t)
236 {
237     return !static_cast<bool>(x);
238 }
239 
240 template <class T>
241 inline
242 bool
243 operator==(std::nullptr_t, min_pointer<T> x)
244 {
245     return !static_cast<bool>(x);
246 }
247 
248 template <class T>
249 inline
250 bool
251 operator!=(min_pointer<T> x, std::nullptr_t)
252 {
253     return static_cast<bool>(x);
254 }
255 
256 template <class T>
257 inline
258 bool
259 operator!=(std::nullptr_t, min_pointer<T> x)
260 {
261     return static_cast<bool>(x);
262 }
263 
264 template <class T>
265 class min_allocator
266 {
267 public:
268     typedef T value_type;
269     typedef min_pointer<T> pointer;
270 
271     min_allocator() = default;
272     template <class U>
min_allocator(min_allocator<U>)273     min_allocator(min_allocator<U>) {}
274 
allocate(std::ptrdiff_t n)275     pointer allocate(std::ptrdiff_t n)
276     {
277         return pointer(static_cast<T*>(::operator new(n*sizeof(T))));
278     }
279 
deallocate(pointer p,std::ptrdiff_t)280     void deallocate(pointer p, std::ptrdiff_t)
281     {
282         return ::operator delete(p.ptr_);
283     }
284 
285     friend bool operator==(min_allocator, min_allocator) {return true;}
286     friend bool operator!=(min_allocator x, min_allocator y) {return !(x == y);}
287 };
288 
289 #endif  // __cplusplus >= 201103L
290 
291 #endif  // MIN_ALLOCATOR_H
292