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 #include <cstddef> 14 #include <cstdlib> 15 #include <cstddef> 16 #include <cassert> 17 18 #include "test_macros.h" 19 20 template <class T> 21 class bare_allocator 22 { 23 public: 24 typedef T value_type; 25 bare_allocator()26 bare_allocator() TEST_NOEXCEPT {} 27 28 template <class U> bare_allocator(bare_allocator<U>)29 bare_allocator(bare_allocator<U>) TEST_NOEXCEPT {} 30 allocate(std::size_t n)31 T* allocate(std::size_t n) 32 { 33 return static_cast<T*>(::operator new(n*sizeof(T))); 34 } 35 deallocate(T * p,std::size_t)36 void deallocate(T* p, std::size_t) 37 { 38 return ::operator delete(static_cast<void*>(p)); 39 } 40 41 friend bool operator==(bare_allocator, bare_allocator) {return true;} 42 friend bool operator!=(bare_allocator x, bare_allocator y) {return !(x == y);} 43 }; 44 45 46 template <class T> 47 class no_default_allocator 48 { 49 #if TEST_STD_VER >= 11 50 no_default_allocator() = delete; 51 #else 52 no_default_allocator(); 53 #endif 54 struct construct_tag {}; no_default_allocator(construct_tag)55 explicit no_default_allocator(construct_tag) {} 56 57 public: create()58 static no_default_allocator create() { 59 construct_tag tag; 60 return no_default_allocator(tag); 61 } 62 63 public: 64 typedef T value_type; 65 66 template <class U> no_default_allocator(no_default_allocator<U>)67 no_default_allocator(no_default_allocator<U>) TEST_NOEXCEPT {} 68 allocate(std::size_t n)69 T* allocate(std::size_t n) 70 { 71 return static_cast<T*>(::operator new(n*sizeof(T))); 72 } 73 deallocate(T * p,std::size_t)74 void deallocate(T* p, std::size_t) 75 { 76 return ::operator delete(static_cast<void*>(p)); 77 } 78 79 friend bool operator==(no_default_allocator, no_default_allocator) {return true;} 80 friend bool operator!=(no_default_allocator x, no_default_allocator y) {return !(x == y);} 81 }; 82 83 struct malloc_allocator_base { 84 static size_t alloc_count; 85 static size_t dealloc_count; 86 static bool disable_default_constructor; 87 outstanding_allocmalloc_allocator_base88 static size_t outstanding_alloc() { 89 assert(alloc_count >= dealloc_count); 90 return (alloc_count - dealloc_count); 91 } 92 resetmalloc_allocator_base93 static void reset() { 94 assert(outstanding_alloc() == 0); 95 disable_default_constructor = false; 96 alloc_count = 0; 97 dealloc_count = 0; 98 } 99 }; 100 101 102 size_t malloc_allocator_base::alloc_count = 0; 103 size_t malloc_allocator_base::dealloc_count = 0; 104 bool malloc_allocator_base::disable_default_constructor = false; 105 106 107 template <class T> 108 class malloc_allocator : public malloc_allocator_base 109 { 110 public: 111 typedef T value_type; 112 malloc_allocator()113 malloc_allocator() TEST_NOEXCEPT { assert(!disable_default_constructor); } 114 115 template <class U> malloc_allocator(malloc_allocator<U>)116 malloc_allocator(malloc_allocator<U>) TEST_NOEXCEPT {} 117 allocate(std::size_t n)118 T* allocate(std::size_t n) 119 { 120 ++alloc_count; 121 return static_cast<T*>(std::malloc(n*sizeof(T))); 122 } 123 deallocate(T * p,std::size_t)124 void deallocate(T* p, std::size_t) 125 { 126 ++dealloc_count; 127 std::free(static_cast<void*>(p)); 128 } 129 130 friend bool operator==(malloc_allocator, malloc_allocator) {return true;} 131 friend bool operator!=(malloc_allocator x, malloc_allocator y) {return !(x == y);} 132 }; 133 134 135 #if TEST_STD_VER >= 11 136 137 #include <memory> 138 139 template <class T, class = std::integral_constant<size_t, 0> > class min_pointer; 140 template <class T, class ID> class min_pointer<const T, ID>; 141 template <class ID> class min_pointer<void, ID>; 142 template <class ID> class min_pointer<const void, ID>; 143 template <class T> class min_allocator; 144 145 template <class ID> 146 class min_pointer<const void, ID> 147 { 148 const void* ptr_; 149 public: 150 min_pointer() TEST_NOEXCEPT = default; min_pointer(std::nullptr_t)151 min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {} 152 template <class T> min_pointer(min_pointer<T,ID> p)153 min_pointer(min_pointer<T, ID> p) TEST_NOEXCEPT : ptr_(p.ptr_) {} 154 155 explicit operator bool() const {return ptr_ != nullptr;} 156 157 friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;} 158 friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);} 159 template <class U, class XID> friend class min_pointer; 160 }; 161 162 template <class ID> 163 class min_pointer<void, ID> 164 { 165 void* ptr_; 166 public: 167 min_pointer() TEST_NOEXCEPT = default; min_pointer(std::nullptr_t)168 min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {} 169 template <class T, 170 class = typename std::enable_if 171 < 172 !std::is_const<T>::value 173 >::type 174 > min_pointer(min_pointer<T,ID> p)175 min_pointer(min_pointer<T, ID> p) TEST_NOEXCEPT : ptr_(p.ptr_) {} 176 177 explicit operator bool() const {return ptr_ != nullptr;} 178 179 friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;} 180 friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);} 181 template <class U, class XID> friend class min_pointer; 182 }; 183 184 template <class T, class ID> 185 class min_pointer 186 { 187 T* ptr_; 188 min_pointer(T * p)189 explicit min_pointer(T* p) TEST_NOEXCEPT : ptr_(p) {} 190 public: 191 min_pointer() TEST_NOEXCEPT = default; min_pointer(std::nullptr_t)192 min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {} min_pointer(min_pointer<void,ID> p)193 explicit min_pointer(min_pointer<void, ID> p) TEST_NOEXCEPT : ptr_(static_cast<T*>(p.ptr_)) {} 194 195 explicit operator bool() const {return ptr_ != nullptr;} 196 197 typedef std::ptrdiff_t difference_type; 198 typedef T& reference; 199 typedef T* pointer; 200 typedef T value_type; 201 typedef std::random_access_iterator_tag iterator_category; 202 203 reference operator*() const {return *ptr_;} 204 pointer operator->() const {return ptr_;} 205 206 min_pointer& operator++() {++ptr_; return *this;} 207 min_pointer operator++(int) {min_pointer tmp(*this); ++ptr_; return tmp;} 208 209 min_pointer& operator--() {--ptr_; return *this;} 210 min_pointer operator--(int) {min_pointer tmp(*this); --ptr_; return tmp;} 211 212 min_pointer& operator+=(difference_type n) {ptr_ += n; return *this;} 213 min_pointer& operator-=(difference_type n) {ptr_ -= n; return *this;} 214 215 min_pointer operator+(difference_type n) const 216 { 217 min_pointer tmp(*this); 218 tmp += n; 219 return tmp; 220 } 221 222 friend min_pointer operator+(difference_type n, min_pointer x) 223 { 224 return x + n; 225 } 226 227 min_pointer operator-(difference_type n) const 228 { 229 min_pointer tmp(*this); 230 tmp -= n; 231 return tmp; 232 } 233 234 friend difference_type operator-(min_pointer x, min_pointer y) 235 { 236 return x.ptr_ - y.ptr_; 237 } 238 239 reference operator[](difference_type n) const {return ptr_[n];} 240 241 friend bool operator< (min_pointer x, min_pointer y) {return x.ptr_ < y.ptr_;} 242 friend bool operator> (min_pointer x, min_pointer y) {return y < x;} 243 friend bool operator<=(min_pointer x, min_pointer y) {return !(y < x);} 244 friend bool operator>=(min_pointer x, min_pointer y) {return !(x < y);} 245 pointer_to(T & t)246 static min_pointer pointer_to(T& t) {return min_pointer(std::addressof(t));} 247 248 friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;} 249 friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);} 250 template <class U, class XID> friend class min_pointer; 251 template <class U> friend class min_allocator; 252 }; 253 254 template <class T, class ID> 255 class min_pointer<const T, ID> 256 { 257 const T* ptr_; 258 min_pointer(const T * p)259 explicit min_pointer(const T* p) : ptr_(p) {} 260 public: 261 min_pointer() TEST_NOEXCEPT = default; min_pointer(std::nullptr_t)262 min_pointer(std::nullptr_t) : ptr_(nullptr) {} min_pointer(min_pointer<T,ID> p)263 min_pointer(min_pointer<T, ID> p) : ptr_(p.ptr_) {} min_pointer(min_pointer<const void,ID> p)264 explicit min_pointer(min_pointer<const void, ID> p) : ptr_(static_cast<const T*>(p.ptr_)) {} 265 266 explicit operator bool() const {return ptr_ != nullptr;} 267 268 typedef std::ptrdiff_t difference_type; 269 typedef const T& reference; 270 typedef const T* pointer; 271 typedef const T value_type; 272 typedef std::random_access_iterator_tag iterator_category; 273 274 reference operator*() const {return *ptr_;} 275 pointer operator->() const {return ptr_;} 276 277 min_pointer& operator++() {++ptr_; return *this;} 278 min_pointer operator++(int) {min_pointer tmp(*this); ++ptr_; return tmp;} 279 280 min_pointer& operator--() {--ptr_; return *this;} 281 min_pointer operator--(int) {min_pointer tmp(*this); --ptr_; return tmp;} 282 283 min_pointer& operator+=(difference_type n) {ptr_ += n; return *this;} 284 min_pointer& operator-=(difference_type n) {ptr_ -= n; return *this;} 285 286 min_pointer operator+(difference_type n) const 287 { 288 min_pointer tmp(*this); 289 tmp += n; 290 return tmp; 291 } 292 293 friend min_pointer operator+(difference_type n, min_pointer x) 294 { 295 return x + n; 296 } 297 298 min_pointer operator-(difference_type n) const 299 { 300 min_pointer tmp(*this); 301 tmp -= n; 302 return tmp; 303 } 304 305 friend difference_type operator-(min_pointer x, min_pointer y) 306 { 307 return x.ptr_ - y.ptr_; 308 } 309 310 reference operator[](difference_type n) const {return ptr_[n];} 311 312 friend bool operator< (min_pointer x, min_pointer y) {return x.ptr_ < y.ptr_;} 313 friend bool operator> (min_pointer x, min_pointer y) {return y < x;} 314 friend bool operator<=(min_pointer x, min_pointer y) {return !(y < x);} 315 friend bool operator>=(min_pointer x, min_pointer y) {return !(x < y);} 316 pointer_to(const T & t)317 static min_pointer pointer_to(const T& t) {return min_pointer(std::addressof(t));} 318 319 friend bool operator==(min_pointer x, min_pointer y) {return x.ptr_ == y.ptr_;} 320 friend bool operator!=(min_pointer x, min_pointer y) {return !(x == y);} 321 template <class U, class XID> friend class min_pointer; 322 }; 323 324 template <class T, class ID> 325 inline 326 bool 327 operator==(min_pointer<T, ID> x, std::nullptr_t) 328 { 329 return !static_cast<bool>(x); 330 } 331 332 template <class T, class ID> 333 inline 334 bool 335 operator==(std::nullptr_t, min_pointer<T, ID> x) 336 { 337 return !static_cast<bool>(x); 338 } 339 340 template <class T, class ID> 341 inline 342 bool 343 operator!=(min_pointer<T, ID> x, std::nullptr_t) 344 { 345 return static_cast<bool>(x); 346 } 347 348 template <class T, class ID> 349 inline 350 bool 351 operator!=(std::nullptr_t, min_pointer<T, ID> x) 352 { 353 return static_cast<bool>(x); 354 } 355 356 template <class T> 357 class min_allocator 358 { 359 public: 360 typedef T value_type; 361 typedef min_pointer<T> pointer; 362 363 min_allocator() = default; 364 template <class U> min_allocator(min_allocator<U>)365 min_allocator(min_allocator<U>) {} 366 allocate(std::ptrdiff_t n)367 pointer allocate(std::ptrdiff_t n) 368 { 369 return pointer(static_cast<T*>(::operator new(n*sizeof(T)))); 370 } 371 deallocate(pointer p,std::ptrdiff_t)372 void deallocate(pointer p, std::ptrdiff_t) 373 { 374 return ::operator delete(p.ptr_); 375 } 376 377 friend bool operator==(min_allocator, min_allocator) {return true;} 378 friend bool operator!=(min_allocator x, min_allocator y) {return !(x == y);} 379 }; 380 381 template <class T> 382 class explicit_allocator 383 { 384 public: 385 typedef T value_type; 386 explicit_allocator()387 explicit_allocator() TEST_NOEXCEPT {} 388 389 template <class U> explicit_allocator(explicit_allocator<U>)390 explicit explicit_allocator(explicit_allocator<U>) TEST_NOEXCEPT {} 391 allocate(std::size_t n)392 T* allocate(std::size_t n) 393 { 394 return static_cast<T*>(::operator new(n*sizeof(T))); 395 } 396 deallocate(T * p,std::size_t)397 void deallocate(T* p, std::size_t) 398 { 399 return ::operator delete(static_cast<void*>(p)); 400 } 401 402 friend bool operator==(explicit_allocator, explicit_allocator) {return true;} 403 friend bool operator!=(explicit_allocator x, explicit_allocator y) {return !(x == y);} 404 }; 405 406 #endif // TEST_STD_VER >= 11 407 408 #endif // MIN_ALLOCATOR_H 409