blob: ab13c65105deee30fa825d584b1485c7adfb85b4 [file] [log] [blame]
Howard Hinnantc52f43e2010-08-22 00:59:46 +00001//===----------------------------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00005// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantc52f43e2010-08-22 00:59:46 +00007//
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>
Marshall Clow6b913d72015-01-09 20:25:52 +000020#include <utility>
Howard Hinnantc52f43e2010-08-22 00:59:46 +000021#include <cassert>
22
Eric Fiselier76581dc2015-07-31 02:43:52 +000023#include "test_macros.h"
24
25#if TEST_STD_VER >= 11
26
Howard Hinnantc52f43e2010-08-22 00:59:46 +000027template <class T>
28class Deleter
29{
30 int state_;
31
Howard Hinnantc52f43e2010-08-22 00:59:46 +000032 Deleter(const Deleter&);
33 Deleter& operator=(const Deleter&);
Howard Hinnantc52f43e2010-08-22 00:59:46 +000034
35public:
Howard Hinnantc52f43e2010-08-22 00:59:46 +000036 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 }
Eric Fiselier76581dc2015-07-31 02:43:52 +000043
Howard Hinnantc52f43e2010-08-22 00:59:46 +000044
45 Deleter() : state_(0) {}
46 explicit Deleter(int s) : state_(s) {}
47 ~Deleter() {assert(state_ >= 0); state_ = -1;}
48
Howard Hinnantc52f43e2010-08-22 00:59:46 +000049 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
54private:
55 template <class U>
56 Deleter(const Deleter<U>& d,
57 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
Howard Hinnantc52f43e2010-08-22 00:59:46 +000058public:
59 int state() const {return state_;}
60 void set_state(int i) {state_ = i;}
61
62 void operator()(T* p) {delete p;}
63};
64
65template <class T>
66class Deleter<T[]>
67{
68 int state_;
69
Howard Hinnantc52f43e2010-08-22 00:59:46 +000070 Deleter(const Deleter&);
71 Deleter& operator=(const Deleter&);
Howard Hinnantc52f43e2010-08-22 00:59:46 +000072
73public:
Eric Fiselier76581dc2015-07-31 02:43:52 +000074
Howard Hinnantc52f43e2010-08-22 00:59:46 +000075 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 }
Howard Hinnantc52f43e2010-08-22 00:59:46 +000082
83 Deleter() : state_(0) {}
84 explicit Deleter(int s) : state_(s) {}
85 ~Deleter() {assert(state_ >= 0); state_ = -1;}
86
87 int state() const {return state_;}
88 void set_state(int i) {state_ = i;}
89
90 void operator()(T* p) {delete [] p;}
91};
92
Eric Fiselier76581dc2015-07-31 02:43:52 +000093#else // TEST_STD_VER < 11
94
95template <class T>
96class Deleter
97{
98 mutable int state_;
99
100public:
101 Deleter() : state_(0) {}
102 explicit Deleter(int s) : state_(s) {}
103
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
113 ~Deleter() {assert(state_ >= 0); state_ = -1;}
114
Dan Albert1d4a1ed2016-05-25 22:36:09 -0700115private:
Eric Fiselier76581dc2015-07-31 02:43:52 +0000116 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
121public:
122 int state() const {return state_;}
123 void set_state(int i) {state_ = i;}
124
125 void operator()(T* p) {delete p;}
126};
127
128template <class T>
129class Deleter<T[]>
130{
131 mutable int state_;
132
133public:
134
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
144 Deleter() : state_(0) {}
145 explicit Deleter(int s) : state_(s) {}
146 ~Deleter() {assert(state_ >= 0); state_ = -1;}
147
148 int state() const {return state_;}
149 void set_state(int i) {state_ = i;}
150
151 void operator()(T* p) {delete [] p;}
152};
153
154#endif
155
Howard Hinnantc52f43e2010-08-22 00:59:46 +0000156template <class T>
157void
158swap(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
Eric Fiselier76581dc2015-07-31 02:43:52 +0000165
Howard Hinnantc52f43e2010-08-22 00:59:46 +0000166template <class T>
167class CDeleter
168{
169 int state_;
170
171public:
172
173 CDeleter() : state_(0) {}
174 explicit CDeleter(int s) : state_(s) {}
175 ~CDeleter() {assert(state_ >= 0); state_ = -1;}
176
177 template <class U>
178 CDeleter(const CDeleter<U>& d)
179 : state_(d.state()) {}
180
181 int state() const {return state_;}
182 void set_state(int i) {state_ = i;}
183
184 void operator()(T* p) {delete p;}
185};
186
187template <class T>
188class CDeleter<T[]>
189{
190 int state_;
191
192public:
193
194 CDeleter() : state_(0) {}
195 explicit CDeleter(int s) : state_(s) {}
196 ~CDeleter() {assert(state_ >= 0); state_ = -1;}
197
198 int state() const {return state_;}
199 void set_state(int i) {state_ = i;}
200
201 void operator()(T* p) {delete [] p;}
202};
203
204template <class T>
205void
206swap(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
Eric Fiselier76581dc2015-07-31 02:43:52 +0000213// Non-copyable deleter
214template <class T>
215class NCDeleter
216{
217 int state_;
218 NCDeleter(NCDeleter const&);
219 NCDeleter& operator=(NCDeleter const&);
220public:
221
222 NCDeleter() : state_(0) {}
223 explicit NCDeleter(int s) : state_(s) {}
224 ~NCDeleter() {assert(state_ >= 0); state_ = -1;}
225
226 int state() const {return state_;}
227 void set_state(int i) {state_ = i;}
228
229 void operator()(T* p) {delete p;}
230};
231
232
233template <class T>
234class NCDeleter<T[]>
235{
236 int state_;
237 NCDeleter(NCDeleter const&);
238 NCDeleter& operator=(NCDeleter const&);
239public:
240
241 NCDeleter() : state_(0) {}
242 explicit NCDeleter(int s) : state_(s) {}
243 ~NCDeleter() {assert(state_ >= 0); state_ = -1;}
244
245 int state() const {return state_;}
246 void set_state(int i) {state_ = i;}
247
248 void operator()(T* p) {delete [] p;}
249};
250
251
252// Non-copyable deleter
253template <class T>
254class NCConstDeleter
255{
256 int state_;
257 NCConstDeleter(NCConstDeleter const&);
258 NCConstDeleter& operator=(NCConstDeleter const&);
259public:
260
261 NCConstDeleter() : state_(0) {}
262 explicit NCConstDeleter(int s) : state_(s) {}
263 ~NCConstDeleter() {assert(state_ >= 0); state_ = -1;}
264
265 int state() const {return state_;}
266 void set_state(int i) {state_ = i;}
267
268 void operator()(T* p) const {delete p;}
269};
270
271
272template <class T>
273class NCConstDeleter<T[]>
274{
275 int state_;
276 NCConstDeleter(NCConstDeleter const&);
277 NCConstDeleter& operator=(NCConstDeleter const&);
278public:
279
280 NCConstDeleter() : state_(0) {}
281 explicit NCConstDeleter(int s) : state_(s) {}
282 ~NCConstDeleter() {assert(state_ >= 0); state_ = -1;}
283
284 int state() const {return state_;}
285 void set_state(int i) {state_ = i;}
286
287 void operator()(T* p) const {delete [] p;}
288};
289
290
291// Non-copyable deleter
292template <class T>
293class CopyDeleter
294{
295 int state_;
296public:
297
298 CopyDeleter() : state_(0) {}
299 explicit CopyDeleter(int s) : state_(s) {}
300 ~CopyDeleter() {assert(state_ >= 0); state_ = -1;}
301
302 CopyDeleter(CopyDeleter const& other) : state_(other.state_) {}
303 CopyDeleter& operator=(CopyDeleter const& other) {
304 state_ = other.state_;
305 return *this;
306 }
307
308 int state() const {return state_;}
309 void set_state(int i) {state_ = i;}
310
311 void operator()(T* p) {delete p;}
312};
313
314
315template <class T>
316class CopyDeleter<T[]>
317{
318 int state_;
319
320public:
321
322 CopyDeleter() : state_(0) {}
323 explicit CopyDeleter(int s) : state_(s) {}
324 ~CopyDeleter() {assert(state_ >= 0); state_ = -1;}
325
326 CopyDeleter(CopyDeleter const& other) : state_(other.state_) {}
327 CopyDeleter& operator=(CopyDeleter const& other) {
328 state_ = other.state_;
329 return *this;
330 }
331
332 int state() const {return state_;}
333 void set_state(int i) {state_ = i;}
334
335 void operator()(T* p) {delete [] p;}
336};
337
338
Howard Hinnantc52f43e2010-08-22 00:59:46 +0000339#endif // DELETER_H