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