libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

min_allocator.h (12606B)


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