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 #include "test_macros.h"
24
25 #if TEST_STD_VER >= 11
26
27 template <class T>
28 class Deleter
29 {
30 int state_;
31
32 Deleter(const Deleter&);
33 Deleter& operator=(const Deleter&);
34
35 public:
Deleter(Deleter && r)36 Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
37 Deleter& operator=(Deleter&& r)
38 {
39 state_ = r.state_;
40 r.state_ = 0;
41 return *this;
42 }
43
44
Deleter()45 Deleter() : state_(0) {}
Deleter(int s)46 explicit Deleter(int s) : state_(s) {}
~Deleter()47 ~Deleter() {assert(state_ >= 0); state_ = -1;}
48
49 template <class U>
50 Deleter(Deleter<U>&& d,
51 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
52 : state_(d.state()) {d.set_state(0);}
53
54 private:
55 template <class U>
56 Deleter(const Deleter<U>& d,
57 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
58 public:
state()59 int state() const {return state_;}
set_state(int i)60 void set_state(int i) {state_ = i;}
61
operator()62 void operator()(T* p) {delete p;}
63 };
64
65 template <class T>
66 class Deleter<T[]>
67 {
68 int state_;
69
70 Deleter(const Deleter&);
71 Deleter& operator=(const Deleter&);
72
73 public:
74
Deleter(Deleter && r)75 Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
76 Deleter& operator=(Deleter&& r)
77 {
78 state_ = r.state_;
79 r.state_ = 0;
80 return *this;
81 }
82
Deleter()83 Deleter() : state_(0) {}
Deleter(int s)84 explicit Deleter(int s) : state_(s) {}
~Deleter()85 ~Deleter() {assert(state_ >= 0); state_ = -1;}
86
state()87 int state() const {return state_;}
set_state(int i)88 void set_state(int i) {state_ = i;}
89
operator()90 void operator()(T* p) {delete [] p;}
91 };
92
93 #else // TEST_STD_VER < 11
94
95 template <class T>
96 class Deleter
97 {
98 mutable int state_;
99
100 public:
Deleter()101 Deleter() : state_(0) {}
Deleter(int s)102 explicit Deleter(int s) : state_(s) {}
103
Deleter(Deleter const & other)104 Deleter(Deleter const & other) : state_(other.state_) {
105 other.state_ = 0;
106 }
107 Deleter& operator=(Deleter const& other) {
108 state_ = other.state_;
109 other.state_ = 0;
110 return *this;
111 }
112
~Deleter()113 ~Deleter() {assert(state_ >= 0); state_ = -1;}
114
115 template <class U>
116 Deleter(Deleter<U> d,
117 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
118 : state_(d.state()) {}
119
120 public:
state()121 int state() const {return state_;}
set_state(int i)122 void set_state(int i) {state_ = i;}
123
operator()124 void operator()(T* p) {delete p;}
125 };
126
127 template <class T>
128 class Deleter<T[]>
129 {
130 mutable int state_;
131
132 public:
133
Deleter(Deleter const & other)134 Deleter(Deleter const& other) : state_(other.state_) {
135 other.state_ = 0;
136 }
137 Deleter& operator=(Deleter const& other) {
138 state_ = other.state_;
139 other.state_ = 0;
140 return *this;
141 }
142
Deleter()143 Deleter() : state_(0) {}
Deleter(int s)144 explicit Deleter(int s) : state_(s) {}
~Deleter()145 ~Deleter() {assert(state_ >= 0); state_ = -1;}
146
state()147 int state() const {return state_;}
set_state(int i)148 void set_state(int i) {state_ = i;}
149
operator()150 void operator()(T* p) {delete [] p;}
151 };
152
153 #endif
154
155 template <class T>
156 void
swap(Deleter<T> & x,Deleter<T> & y)157 swap(Deleter<T>& x, Deleter<T>& y)
158 {
159 Deleter<T> t(std::move(x));
160 x = std::move(y);
161 y = std::move(t);
162 }
163
164
165 template <class T>
166 class CDeleter
167 {
168 int state_;
169
170 public:
171
CDeleter()172 CDeleter() : state_(0) {}
CDeleter(int s)173 explicit CDeleter(int s) : state_(s) {}
~CDeleter()174 ~CDeleter() {assert(state_ >= 0); state_ = -1;}
175
176 template <class U>
CDeleter(const CDeleter<U> & d)177 CDeleter(const CDeleter<U>& d)
178 : state_(d.state()) {}
179
state()180 int state() const {return state_;}
set_state(int i)181 void set_state(int i) {state_ = i;}
182
operator()183 void operator()(T* p) {delete p;}
184 };
185
186 template <class T>
187 class CDeleter<T[]>
188 {
189 int state_;
190
191 public:
192
CDeleter()193 CDeleter() : state_(0) {}
CDeleter(int s)194 explicit CDeleter(int s) : state_(s) {}
~CDeleter()195 ~CDeleter() {assert(state_ >= 0); state_ = -1;}
196
state()197 int state() const {return state_;}
set_state(int i)198 void set_state(int i) {state_ = i;}
199
operator()200 void operator()(T* p) {delete [] p;}
201 };
202
203 template <class T>
204 void
swap(CDeleter<T> & x,CDeleter<T> & y)205 swap(CDeleter<T>& x, CDeleter<T>& y)
206 {
207 CDeleter<T> t(std::move(x));
208 x = std::move(y);
209 y = std::move(t);
210 }
211
212 // Non-copyable deleter
213 template <class T>
214 class NCDeleter
215 {
216 int state_;
217 NCDeleter(NCDeleter const&);
218 NCDeleter& operator=(NCDeleter const&);
219 public:
220
NCDeleter()221 NCDeleter() : state_(0) {}
NCDeleter(int s)222 explicit NCDeleter(int s) : state_(s) {}
~NCDeleter()223 ~NCDeleter() {assert(state_ >= 0); state_ = -1;}
224
state()225 int state() const {return state_;}
set_state(int i)226 void set_state(int i) {state_ = i;}
227
operator()228 void operator()(T* p) {delete p;}
229 };
230
231
232 template <class T>
233 class NCDeleter<T[]>
234 {
235 int state_;
236 NCDeleter(NCDeleter const&);
237 NCDeleter& operator=(NCDeleter const&);
238 public:
239
NCDeleter()240 NCDeleter() : state_(0) {}
NCDeleter(int s)241 explicit NCDeleter(int s) : state_(s) {}
~NCDeleter()242 ~NCDeleter() {assert(state_ >= 0); state_ = -1;}
243
state()244 int state() const {return state_;}
set_state(int i)245 void set_state(int i) {state_ = i;}
246
operator()247 void operator()(T* p) {delete [] p;}
248 };
249
250
251 // Non-copyable deleter
252 template <class T>
253 class NCConstDeleter
254 {
255 int state_;
256 NCConstDeleter(NCConstDeleter const&);
257 NCConstDeleter& operator=(NCConstDeleter const&);
258 public:
259
NCConstDeleter()260 NCConstDeleter() : state_(0) {}
NCConstDeleter(int s)261 explicit NCConstDeleter(int s) : state_(s) {}
~NCConstDeleter()262 ~NCConstDeleter() {assert(state_ >= 0); state_ = -1;}
263
state()264 int state() const {return state_;}
set_state(int i)265 void set_state(int i) {state_ = i;}
266
operator()267 void operator()(T* p) const {delete p;}
268 };
269
270
271 template <class T>
272 class NCConstDeleter<T[]>
273 {
274 int state_;
275 NCConstDeleter(NCConstDeleter const&);
276 NCConstDeleter& operator=(NCConstDeleter const&);
277 public:
278
NCConstDeleter()279 NCConstDeleter() : state_(0) {}
NCConstDeleter(int s)280 explicit NCConstDeleter(int s) : state_(s) {}
~NCConstDeleter()281 ~NCConstDeleter() {assert(state_ >= 0); state_ = -1;}
282
state()283 int state() const {return state_;}
set_state(int i)284 void set_state(int i) {state_ = i;}
285
operator()286 void operator()(T* p) const {delete [] p;}
287 };
288
289
290 // Non-copyable deleter
291 template <class T>
292 class CopyDeleter
293 {
294 int state_;
295 public:
296
CopyDeleter()297 CopyDeleter() : state_(0) {}
CopyDeleter(int s)298 explicit CopyDeleter(int s) : state_(s) {}
~CopyDeleter()299 ~CopyDeleter() {assert(state_ >= 0); state_ = -1;}
300
CopyDeleter(CopyDeleter const & other)301 CopyDeleter(CopyDeleter const& other) : state_(other.state_) {}
302 CopyDeleter& operator=(CopyDeleter const& other) {
303 state_ = other.state_;
304 return *this;
305 }
306
state()307 int state() const {return state_;}
set_state(int i)308 void set_state(int i) {state_ = i;}
309
operator()310 void operator()(T* p) {delete p;}
311 };
312
313
314 template <class T>
315 class CopyDeleter<T[]>
316 {
317 int state_;
318
319 public:
320
CopyDeleter()321 CopyDeleter() : state_(0) {}
CopyDeleter(int s)322 explicit CopyDeleter(int s) : state_(s) {}
~CopyDeleter()323 ~CopyDeleter() {assert(state_ >= 0); state_ = -1;}
324
CopyDeleter(CopyDeleter const & other)325 CopyDeleter(CopyDeleter const& other) : state_(other.state_) {}
326 CopyDeleter& operator=(CopyDeleter const& other) {
327 state_ = other.state_;
328 return *this;
329 }
330
state()331 int state() const {return state_;}
set_state(int i)332 void set_state(int i) {state_ = i;}
333
operator()334 void operator()(T* p) {delete [] p;}
335 };
336
337
338 #endif // DELETER_H
339