1 #ifndef MIN_ALLOCATOR_H 2 #define MIN_ALLOCATOR_H 3 4 #if __cplusplus >= 201103L 5 6 #include <memory> 7 8 template <class T> class min_pointer; 9 template <class T> class min_pointer<const T>; 10 template <> class min_pointer<void>; 11 template <> class min_pointer<const void>; 12 template <class T> class min_allocator; 13 14 template <> 15 class min_pointer<const void> 16 { 17 const void* ptr_; 18 public: 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 31 template <> 32 class min_pointer<void> 33 { 34 void* ptr_; 35 public: 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 53 template <class T> 54 class min_pointer 55 { 56 T* ptr_; 57 58 explicit min_pointer(T* p) : ptr_(p) {} 59 public: 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 123 template <class T> 124 class min_pointer<const T> 125 { 126 const T* ptr_; 127 128 explicit min_pointer(const T* p) : ptr_(p) {} 129 public: 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 193 template <class T> 194 inline 195 bool 196 operator==(min_pointer<T> x, std::nullptr_t) 197 { 198 return !static_cast<bool>(x); 199 } 200 201 template <class T> 202 inline 203 bool 204 operator==(std::nullptr_t, min_pointer<T> x) 205 { 206 return !static_cast<bool>(x); 207 } 208 209 template <class T> 210 inline 211 bool 212 operator!=(min_pointer<T> x, std::nullptr_t) 213 { 214 return static_cast<bool>(x); 215 } 216 217 template <class T> 218 inline 219 bool 220 operator!=(std::nullptr_t, min_pointer<T> x) 221 { 222 return static_cast<bool>(x); 223 } 224 225 template <class T> 226 class min_allocator 227 { 228 public: 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