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