Home | History | Annotate | Download | only in unique.ptr
      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 DELETER_H
     17 #define DELETER_H
     18 
     19 #include <type_traits>
     20 #include <cassert>
     21 
     22 template <class T>
     23 class Deleter
     24 {
     25     int state_;
     26 
     27 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     28     Deleter(const Deleter&);
     29     Deleter& operator=(const Deleter&);
     30 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     31     Deleter(Deleter&);
     32     Deleter& operator=(Deleter&);
     33 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     34 
     35 public:
     36 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     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 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     45     operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
     46     Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
     47     Deleter& operator=(std::__rv<Deleter> r)
     48     {
     49         state_ = r->state_;
     50         r->state_ = 0;
     51         return *this;
     52     }
     53 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     54 
     55     Deleter() : state_(0) {}
     56     explicit Deleter(int s) : state_(s) {}
     57     ~Deleter() {assert(state_ >= 0); state_ = -1;}
     58 
     59 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     60     template <class U>
     61         Deleter(Deleter<U>&& d,
     62             typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
     63             : state_(d.state()) {d.set_state(0);}
     64 
     65 private:
     66     template <class U>
     67         Deleter(const Deleter<U>& d,
     68             typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
     69 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     70     template <class U>
     71         Deleter(Deleter<U> d,
     72             typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
     73             : state_(d.state()) {}
     74 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     75 public:
     76     int state() const {return state_;}
     77     void set_state(int i) {state_ = i;}
     78 
     79     void operator()(T* p) {delete p;}
     80 };
     81 
     82 template <class T>
     83 class Deleter<T[]>
     84 {
     85     int state_;
     86 
     87 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     88     Deleter(const Deleter&);
     89     Deleter& operator=(const Deleter&);
     90 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     91     Deleter(Deleter&);
     92     Deleter& operator=(Deleter&);
     93 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     94 
     95 public:
     96 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     97     Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
     98     Deleter& operator=(Deleter&& r)
     99     {
    100         state_ = r.state_;
    101         r.state_ = 0;
    102         return *this;
    103     }
    104 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
    105     operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
    106     Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
    107     Deleter& operator=(std::__rv<Deleter> r)
    108     {
    109         state_ = r->state_;
    110         r->state_ = 0;
    111         return *this;
    112     }
    113 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
    114 
    115     Deleter() : state_(0) {}
    116     explicit Deleter(int s) : state_(s) {}
    117     ~Deleter() {assert(state_ >= 0); state_ = -1;}
    118 
    119     int state() const {return state_;}
    120     void set_state(int i) {state_ = i;}
    121 
    122     void operator()(T* p) {delete [] p;}
    123 };
    124 
    125 template <class T>
    126 void
    127 swap(Deleter<T>& x, Deleter<T>& y)
    128 {
    129     Deleter<T> t(std::move(x));
    130     x = std::move(y);
    131     y = std::move(t);
    132 }
    133 
    134 template <class T>
    135 class CDeleter
    136 {
    137     int state_;
    138 
    139 public:
    140 
    141     CDeleter() : state_(0) {}
    142     explicit CDeleter(int s) : state_(s) {}
    143     ~CDeleter() {assert(state_ >= 0); state_ = -1;}
    144 
    145     template <class U>
    146         CDeleter(const CDeleter<U>& d)
    147             : state_(d.state()) {}
    148 
    149     int state() const {return state_;}
    150     void set_state(int i) {state_ = i;}
    151 
    152     void operator()(T* p) {delete p;}
    153 };
    154 
    155 template <class T>
    156 class CDeleter<T[]>
    157 {
    158     int state_;
    159 
    160 public:
    161 
    162     CDeleter() : state_(0) {}
    163     explicit CDeleter(int s) : state_(s) {}
    164     ~CDeleter() {assert(state_ >= 0); state_ = -1;}
    165 
    166     int state() const {return state_;}
    167     void set_state(int i) {state_ = i;}
    168 
    169     void operator()(T* p) {delete [] p;}
    170 };
    171 
    172 template <class T>
    173 void
    174 swap(CDeleter<T>& x, CDeleter<T>& y)
    175 {
    176     CDeleter<T> t(std::move(x));
    177     x = std::move(y);
    178     y = std::move(t);
    179 }
    180 
    181 #endif  // DELETER_H
    182