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
Deleter(Deleter && r)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
Deleter()55 Deleter() : state_(0) {}
Deleter(int s)56 explicit Deleter(int s) : state_(s) {}
~Deleter()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:
state()76 int state() const {return state_;}
set_state(int i)77 void set_state(int i) {state_ = i;}
78
operator()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
Deleter(Deleter && r)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
Deleter()115 Deleter() : state_(0) {}
Deleter(int s)116 explicit Deleter(int s) : state_(s) {}
~Deleter()117 ~Deleter() {assert(state_ >= 0); state_ = -1;}
118
state()119 int state() const {return state_;}
set_state(int i)120 void set_state(int i) {state_ = i;}
121
operator()122 void operator()(T* p) {delete [] p;}
123 };
124
125 template <class T>
126 void
swap(Deleter<T> & x,Deleter<T> & y)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
CDeleter()141 CDeleter() : state_(0) {}
CDeleter(int s)142 explicit CDeleter(int s) : state_(s) {}
~CDeleter()143 ~CDeleter() {assert(state_ >= 0); state_ = -1;}
144
145 template <class U>
CDeleter(const CDeleter<U> & d)146 CDeleter(const CDeleter<U>& d)
147 : state_(d.state()) {}
148
state()149 int state() const {return state_;}
set_state(int i)150 void set_state(int i) {state_ = i;}
151
operator()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
CDeleter()162 CDeleter() : state_(0) {}
CDeleter(int s)163 explicit CDeleter(int s) : state_(s) {}
~CDeleter()164 ~CDeleter() {assert(state_ >= 0); state_ = -1;}
165
state()166 int state() const {return state_;}
set_state(int i)167 void set_state(int i) {state_ = i;}
168
operator()169 void operator()(T* p) {delete [] p;}
170 };
171
172 template <class T>
173 void
swap(CDeleter<T> & x,CDeleter<T> & y)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