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
17template <class T>
18class bare_allocator
19{
20public:
21    typedef T value_type;
22
23    bare_allocator() TEST_NOEXCEPT {}
24
25    template <class U>
26    bare_allocator(bare_allocator<U>) TEST_NOEXCEPT {}
27
28    T* allocate(std::size_t n)
29    {
30        return static_cast<T*>(::operator new(n*sizeof(T)));
31    }
32
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
47template <class T> class min_pointer;
48template <class T> class min_pointer<const T>;
49template <> class min_pointer<void>;
50template <> class min_pointer<const void>;
51template <class T> class min_allocator;
52
53template <>
54class min_pointer<const void>
55{
56    const void* ptr_;
57public:
58    min_pointer() TEST_NOEXCEPT = default;
59    min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
60    template <class T>
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
70template <>
71class min_pointer<void>
72{
73    void* ptr_;
74public:
75    min_pointer() TEST_NOEXCEPT = default;
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             >
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
92template <class T>
93class min_pointer
94{
95    T* ptr_;
96
97    explicit min_pointer(T* p) TEST_NOEXCEPT : ptr_(p) {}
98public:
99    min_pointer() TEST_NOEXCEPT = default;
100    min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
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
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
162template <class T>
163class min_pointer<const T>
164{
165    const T* ptr_;
166
167    explicit min_pointer(const T* p) : ptr_(p) {}
168public:
169    min_pointer() TEST_NOEXCEPT = default;
170    min_pointer(std::nullptr_t) : ptr_(nullptr) {}
171    min_pointer(min_pointer<T> p) : ptr_(p.ptr_) {}
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
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
232template <class T>
233inline
234bool
235operator==(min_pointer<T> x, std::nullptr_t)
236{
237    return !static_cast<bool>(x);
238}
239
240template <class T>
241inline
242bool
243operator==(std::nullptr_t, min_pointer<T> x)
244{
245    return !static_cast<bool>(x);
246}
247
248template <class T>
249inline
250bool
251operator!=(min_pointer<T> x, std::nullptr_t)
252{
253    return static_cast<bool>(x);
254}
255
256template <class T>
257inline
258bool
259operator!=(std::nullptr_t, min_pointer<T> x)
260{
261    return static_cast<bool>(x);
262}
263
264template <class T>
265class min_allocator
266{
267public:
268    typedef T value_type;
269    typedef min_pointer<T> pointer;
270
271    min_allocator() = default;
272    template <class U>
273    min_allocator(min_allocator<U>) {}
274
275    pointer allocate(std::ptrdiff_t n)
276    {
277        return pointer(static_cast<T*>(::operator new(n*sizeof(T))));
278    }
279
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