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