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