min_allocator.h revision 061d0cc4db18d17bf01ed14c5db0be098205bd47
1#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 <>
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
26    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);}
28    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
48    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);}
50    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
117    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);}
119    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
188    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);}
190    template <class U> friend class min_pointer;
191};
192
193template <class T>
194inline
195bool
196operator==(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
253