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