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