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 private:
116 template <class U>
117 Deleter(Deleter<U> d,
118 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
119 : state_(d.state()) {}
120
121 public:
state()122 int state() const {return state_;}
set_state(int i)123 void set_state(int i) {state_ = i;}
124
operator()125 void operator()(T* p) {delete p;}
126 };
127
128 template <class T>
129 class Deleter<T[]>
130 {
131 mutable int state_;
132
133 public:
134
Deleter(Deleter const & other)135 Deleter(Deleter const& other) : state_(other.state_) {
136 other.state_ = 0;
137 }
138 Deleter& operator=(Deleter const& other) {
139 state_ = other.state_;
140 other.state_ = 0;
141 return *this;
142 }
143
Deleter()144 Deleter() : state_(0) {}
Deleter(int s)145 explicit Deleter(int s) : state_(s) {}
~Deleter()146 ~Deleter() {assert(state_ >= 0); state_ = -1;}
147
state()148 int state() const {return state_;}
set_state(int i)149 void set_state(int i) {state_ = i;}
150
operator()151 void operator()(T* p) {delete [] p;}
152 };
153
154 #endif
155
156 template <class T>
157 void
swap(Deleter<T> & x,Deleter<T> & y)158 swap(Deleter<T>& x, Deleter<T>& y)
159 {
160 Deleter<T> t(std::move(x));
161 x = std::move(y);
162 y = std::move(t);
163 }
164
165
166 template <class T>
167 class CDeleter
168 {
169 int state_;
170
171 public:
172
CDeleter()173 CDeleter() : state_(0) {}
CDeleter(int s)174 explicit CDeleter(int s) : state_(s) {}
~CDeleter()175 ~CDeleter() {assert(state_ >= 0); state_ = -1;}
176
177 template <class U>
CDeleter(const CDeleter<U> & d)178 CDeleter(const CDeleter<U>& d)
179 : state_(d.state()) {}
180
state()181 int state() const {return state_;}
set_state(int i)182 void set_state(int i) {state_ = i;}
183
operator()184 void operator()(T* p) {delete p;}
185 };
186
187 template <class T>
188 class CDeleter<T[]>
189 {
190 int state_;
191
192 public:
193
CDeleter()194 CDeleter() : state_(0) {}
CDeleter(int s)195 explicit CDeleter(int s) : state_(s) {}
~CDeleter()196 ~CDeleter() {assert(state_ >= 0); state_ = -1;}
197
state()198 int state() const {return state_;}
set_state(int i)199 void set_state(int i) {state_ = i;}
200
operator()201 void operator()(T* p) {delete [] p;}
202 };
203
204 template <class T>
205 void
swap(CDeleter<T> & x,CDeleter<T> & y)206 swap(CDeleter<T>& x, CDeleter<T>& y)
207 {
208 CDeleter<T> t(std::move(x));
209 x = std::move(y);
210 y = std::move(t);
211 }
212
213 // Non-copyable deleter
214 template <class T>
215 class NCDeleter
216 {
217 int state_;
218 NCDeleter(NCDeleter const&);
219 NCDeleter& operator=(NCDeleter const&);
220 public:
221
NCDeleter()222 NCDeleter() : state_(0) {}
NCDeleter(int s)223 explicit NCDeleter(int s) : state_(s) {}
~NCDeleter()224 ~NCDeleter() {assert(state_ >= 0); state_ = -1;}
225
state()226 int state() const {return state_;}
set_state(int i)227 void set_state(int i) {state_ = i;}
228
operator()229 void operator()(T* p) {delete p;}
230 };
231
232
233 template <class T>
234 class NCDeleter<T[]>
235 {
236 int state_;
237 NCDeleter(NCDeleter const&);
238 NCDeleter& operator=(NCDeleter const&);
239 public:
240
NCDeleter()241 NCDeleter() : state_(0) {}
NCDeleter(int s)242 explicit NCDeleter(int s) : state_(s) {}
~NCDeleter()243 ~NCDeleter() {assert(state_ >= 0); state_ = -1;}
244
state()245 int state() const {return state_;}
set_state(int i)246 void set_state(int i) {state_ = i;}
247
operator()248 void operator()(T* p) {delete [] p;}
249 };
250
251
252 // Non-copyable deleter
253 template <class T>
254 class NCConstDeleter
255 {
256 int state_;
257 NCConstDeleter(NCConstDeleter const&);
258 NCConstDeleter& operator=(NCConstDeleter const&);
259 public:
260
NCConstDeleter()261 NCConstDeleter() : state_(0) {}
NCConstDeleter(int s)262 explicit NCConstDeleter(int s) : state_(s) {}
~NCConstDeleter()263 ~NCConstDeleter() {assert(state_ >= 0); state_ = -1;}
264
state()265 int state() const {return state_;}
set_state(int i)266 void set_state(int i) {state_ = i;}
267
operator()268 void operator()(T* p) const {delete p;}
269 };
270
271
272 template <class T>
273 class NCConstDeleter<T[]>
274 {
275 int state_;
276 NCConstDeleter(NCConstDeleter const&);
277 NCConstDeleter& operator=(NCConstDeleter const&);
278 public:
279
NCConstDeleter()280 NCConstDeleter() : state_(0) {}
NCConstDeleter(int s)281 explicit NCConstDeleter(int s) : state_(s) {}
~NCConstDeleter()282 ~NCConstDeleter() {assert(state_ >= 0); state_ = -1;}
283
state()284 int state() const {return state_;}
set_state(int i)285 void set_state(int i) {state_ = i;}
286
operator()287 void operator()(T* p) const {delete [] p;}
288 };
289
290
291 // Non-copyable deleter
292 template <class T>
293 class CopyDeleter
294 {
295 int state_;
296 public:
297
CopyDeleter()298 CopyDeleter() : state_(0) {}
CopyDeleter(int s)299 explicit CopyDeleter(int s) : state_(s) {}
~CopyDeleter()300 ~CopyDeleter() {assert(state_ >= 0); state_ = -1;}
301
CopyDeleter(CopyDeleter const & other)302 CopyDeleter(CopyDeleter const& other) : state_(other.state_) {}
303 CopyDeleter& operator=(CopyDeleter const& other) {
304 state_ = other.state_;
305 return *this;
306 }
307
state()308 int state() const {return state_;}
set_state(int i)309 void set_state(int i) {state_ = i;}
310
operator()311 void operator()(T* p) {delete p;}
312 };
313
314
315 template <class T>
316 class CopyDeleter<T[]>
317 {
318 int state_;
319
320 public:
321
CopyDeleter()322 CopyDeleter() : state_(0) {}
CopyDeleter(int s)323 explicit CopyDeleter(int s) : state_(s) {}
~CopyDeleter()324 ~CopyDeleter() {assert(state_ >= 0); state_ = -1;}
325
CopyDeleter(CopyDeleter const & other)326 CopyDeleter(CopyDeleter const& other) : state_(other.state_) {}
327 CopyDeleter& operator=(CopyDeleter const& other) {
328 state_ = other.state_;
329 return *this;
330 }
331
state()332 int state() const {return state_;}
set_state(int i)333 void set_state(int i) {state_ = i;}
334
operator()335 void operator()(T* p) {delete [] p;}
336 };
337
338
339 #endif // DELETER_H
340