Home | History | Annotate | Download | only in support
      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 
     26     bare_allocator() TEST_NOEXCEPT {}
     27 
     28     template <class U>
     29     bare_allocator(bare_allocator<U>) TEST_NOEXCEPT {}
     30 
     31     T* allocate(std::size_t n)
     32     {
     33         return static_cast<T*>(::operator new(n*sizeof(T)));
     34     }
     35 
     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 {};
     55     explicit no_default_allocator(construct_tag) {}
     56 
     57 public:
     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>
     67     no_default_allocator(no_default_allocator<U>) TEST_NOEXCEPT {}
     68 
     69     T* allocate(std::size_t n)
     70     {
     71         return static_cast<T*>(::operator new(n*sizeof(T)));
     72     }
     73 
     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 
     88     static size_t outstanding_alloc() {
     89       assert(alloc_count >= dealloc_count);
     90       return (alloc_count - dealloc_count);
     91     }
     92 
     93     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 
    113     malloc_allocator() TEST_NOEXCEPT { assert(!disable_default_constructor); }
    114 
    115     template <class U>
    116     malloc_allocator(malloc_allocator<U>) TEST_NOEXCEPT {}
    117 
    118     T* allocate(std::size_t n)
    119     {
    120         ++alloc_count;
    121         return static_cast<T*>(std::malloc(n*sizeof(T)));
    122     }
    123 
    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;
    151     min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
    152     template <class T>
    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;
    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              >
    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 
    189     explicit min_pointer(T* p) TEST_NOEXCEPT : ptr_(p) {}
    190 public:
    191     min_pointer() TEST_NOEXCEPT = default;
    192     min_pointer(std::nullptr_t) TEST_NOEXCEPT : ptr_(nullptr) {}
    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 
    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 
    259     explicit min_pointer(const T* p) : ptr_(p) {}
    260 public:
    261     min_pointer() TEST_NOEXCEPT = default;
    262     min_pointer(std::nullptr_t) : ptr_(nullptr) {}
    263     min_pointer(min_pointer<T, ID> p) : ptr_(p.ptr_) {}
    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 
    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>
    365     min_allocator(min_allocator<U>) {}
    366 
    367     pointer allocate(std::ptrdiff_t n)
    368     {
    369         return pointer(static_cast<T*>(::operator new(n*sizeof(T))));
    370     }
    371 
    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 
    387     explicit_allocator() TEST_NOEXCEPT {}
    388 
    389     template <class U>
    390     explicit explicit_allocator(explicit_allocator<U>) TEST_NOEXCEPT {}
    391 
    392     T* allocate(std::size_t n)
    393     {
    394         return static_cast<T*>(::operator new(n*sizeof(T)));
    395     }
    396 
    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