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