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