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