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