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 22template <class T> 23class 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 35public: 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 65private: 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 75public: 76 int state() const {return state_;} 77 void set_state(int i) {state_ = i;} 78 79 void operator()(T* p) {delete p;} 80}; 81 82template <class T> 83class 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 95public: 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 125template <class T> 126void 127swap(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 134template <class T> 135class CDeleter 136{ 137 int state_; 138 139public: 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 155template <class T> 156class CDeleter<T[]> 157{ 158 int state_; 159 160public: 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 172template <class T> 173void 174swap(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