• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 SUPPORT_DELETER_TYPES_H
17 #define SUPPORT_DELETER_TYPES_H
18 
19 #include <type_traits>
20 #include <utility>
21 #include <cassert>
22 
23 #include "test_macros.h"
24 #include "min_allocator.h"
25 
26 #if TEST_STD_VER >= 11
27 
28 template <class T>
29 class Deleter
30 {
31     int state_;
32 
33     Deleter(const Deleter&);
34     Deleter& operator=(const Deleter&);
35 
36 public:
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 
45 
Deleter()46     Deleter() : state_(0) {}
Deleter(int s)47     explicit Deleter(int s) : state_(s) {}
~Deleter()48     ~Deleter() {assert(state_ >= 0); state_ = -1;}
49 
50     template <class U>
51         Deleter(Deleter<U>&& d,
52             typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
53             : state_(d.state()) {d.set_state(0);}
54 
55 private:
56     template <class U>
57         Deleter(const Deleter<U>& d,
58             typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
59 public:
state()60     int state() const {return state_;}
set_state(int i)61     void set_state(int i) {state_ = i;}
62 
operator()63     void operator()(T* p) {delete p;}
64 };
65 
66 template <class T>
67 class Deleter<T[]>
68 {
69     int state_;
70 
71     Deleter(const Deleter&);
72     Deleter& operator=(const Deleter&);
73 
74 public:
75 
Deleter(Deleter && r)76     Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
77     Deleter& operator=(Deleter&& r)
78     {
79         state_ = r.state_;
80         r.state_ = 0;
81         return *this;
82     }
83 
Deleter()84     Deleter() : state_(0) {}
Deleter(int s)85     explicit Deleter(int s) : state_(s) {}
~Deleter()86     ~Deleter() {assert(state_ >= 0); state_ = -1;}
87 
state()88     int state() const {return state_;}
set_state(int i)89     void set_state(int i) {state_ = i;}
90 
operator()91     void operator()(T* p) {delete [] p;}
92 };
93 
94 #else // TEST_STD_VER < 11
95 
96 template <class T>
97 class Deleter
98 {
99     mutable int state_;
100 
101 public:
Deleter()102     Deleter() : state_(0) {}
Deleter(int s)103     explicit Deleter(int s) : state_(s) {}
104 
Deleter(Deleter const & other)105     Deleter(Deleter const & other) : state_(other.state_) {
106         other.state_ = 0;
107     }
108     Deleter& operator=(Deleter const& other) {
109         state_ = other.state_;
110         other.state_ = 0;
111         return *this;
112     }
113 
~Deleter()114     ~Deleter() {assert(state_ >= 0); state_ = -1;}
115 
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) {}
196     template <class U>
CDeleter(const CDeleter<U> & d)197         CDeleter(const CDeleter<U>& d)
198             : state_(d.state()) {}
199 
~CDeleter()200     ~CDeleter() {assert(state_ >= 0); state_ = -1;}
201 
state()202     int state() const {return state_;}
set_state(int i)203     void set_state(int i) {state_ = i;}
204 
operator()205     void operator()(T* p) {delete [] p;}
206 };
207 
208 template <class T>
209 void
swap(CDeleter<T> & x,CDeleter<T> & y)210 swap(CDeleter<T>& x, CDeleter<T>& y)
211 {
212     CDeleter<T> t(std::move(x));
213     x = std::move(y);
214     y = std::move(t);
215 }
216 
217 // Non-copyable deleter
218 template <class T>
219 class NCDeleter
220 {
221     int state_;
222     NCDeleter(NCDeleter const&);
223     NCDeleter& operator=(NCDeleter const&);
224 public:
225 
NCDeleter()226     NCDeleter() : state_(0) {}
NCDeleter(int s)227     explicit NCDeleter(int s) : state_(s) {}
~NCDeleter()228     ~NCDeleter() {assert(state_ >= 0); state_ = -1;}
229 
state()230     int state() const {return state_;}
set_state(int i)231     void set_state(int i) {state_ = i;}
232 
operator()233     void operator()(T* p) {delete p;}
234 };
235 
236 
237 template <class T>
238 class NCDeleter<T[]>
239 {
240     int state_;
241     NCDeleter(NCDeleter const&);
242     NCDeleter& operator=(NCDeleter const&);
243 public:
244 
NCDeleter()245     NCDeleter() : state_(0) {}
NCDeleter(int s)246     explicit NCDeleter(int s) : state_(s) {}
~NCDeleter()247     ~NCDeleter() {assert(state_ >= 0); state_ = -1;}
248 
state()249     int state() const {return state_;}
set_state(int i)250     void set_state(int i) {state_ = i;}
251 
operator()252     void operator()(T* p) {delete [] p;}
253 };
254 
255 
256 // Non-copyable deleter
257 template <class T>
258 class NCConstDeleter
259 {
260     int state_;
261     NCConstDeleter(NCConstDeleter const&);
262     NCConstDeleter& operator=(NCConstDeleter const&);
263 public:
264 
NCConstDeleter()265     NCConstDeleter() : state_(0) {}
NCConstDeleter(int s)266     explicit NCConstDeleter(int s) : state_(s) {}
~NCConstDeleter()267     ~NCConstDeleter() {assert(state_ >= 0); state_ = -1;}
268 
state()269     int state() const {return state_;}
set_state(int i)270     void set_state(int i) {state_ = i;}
271 
operator()272     void operator()(T* p) const {delete p;}
273 };
274 
275 
276 template <class T>
277 class NCConstDeleter<T[]>
278 {
279     int state_;
280     NCConstDeleter(NCConstDeleter const&);
281     NCConstDeleter& operator=(NCConstDeleter const&);
282 public:
283 
NCConstDeleter()284     NCConstDeleter() : state_(0) {}
NCConstDeleter(int s)285     explicit NCConstDeleter(int s) : state_(s) {}
~NCConstDeleter()286     ~NCConstDeleter() {assert(state_ >= 0); state_ = -1;}
287 
state()288     int state() const {return state_;}
set_state(int i)289     void set_state(int i) {state_ = i;}
290 
operator()291     void operator()(T* p) const {delete [] p;}
292 };
293 
294 
295 // Non-copyable deleter
296 template <class T>
297 class CopyDeleter
298 {
299     int state_;
300 public:
301 
CopyDeleter()302     CopyDeleter() : state_(0) {}
CopyDeleter(int s)303     explicit CopyDeleter(int s) : state_(s) {}
~CopyDeleter()304     ~CopyDeleter() {assert(state_ >= 0); state_ = -1;}
305 
CopyDeleter(CopyDeleter const & other)306     CopyDeleter(CopyDeleter const& other) : state_(other.state_) {}
307     CopyDeleter& operator=(CopyDeleter const& other) {
308         state_ = other.state_;
309         return *this;
310     }
311 
state()312     int state() const {return state_;}
set_state(int i)313     void set_state(int i) {state_ = i;}
314 
operator()315     void operator()(T* p) {delete p;}
316 };
317 
318 
319 template <class T>
320 class CopyDeleter<T[]>
321 {
322     int state_;
323 
324 public:
325 
CopyDeleter()326     CopyDeleter() : state_(0) {}
CopyDeleter(int s)327     explicit CopyDeleter(int s) : state_(s) {}
~CopyDeleter()328     ~CopyDeleter() {assert(state_ >= 0); state_ = -1;}
329 
CopyDeleter(CopyDeleter const & other)330     CopyDeleter(CopyDeleter const& other) : state_(other.state_) {}
331     CopyDeleter& operator=(CopyDeleter const& other) {
332         state_ = other.state_;
333         return *this;
334     }
335 
state()336     int state() const {return state_;}
set_state(int i)337     void set_state(int i) {state_ = i;}
338 
operator()339     void operator()(T* p) {delete [] p;}
340 };
341 
342 
343 struct test_deleter_base
344 {
345     static int count;
346     static int dealloc_count;
347 };
348 
349 int test_deleter_base::count = 0;
350 int test_deleter_base::dealloc_count = 0;
351 
352 template <class T>
353 class test_deleter
354     : public test_deleter_base
355 {
356     int state_;
357 
358 public:
359 
test_deleter()360     test_deleter() : state_(0) {++count;}
test_deleter(int s)361     explicit test_deleter(int s) : state_(s) {++count;}
test_deleter(const test_deleter & d)362     test_deleter(const test_deleter& d)
363         : state_(d.state_) {++count;}
~test_deleter()364     ~test_deleter() {assert(state_ >= 0); --count; state_ = -1;}
365 
state()366     int state() const {return state_;}
set_state(int i)367     void set_state(int i) {state_ = i;}
368 
operator()369     void operator()(T* p) {assert(state_ >= 0); ++dealloc_count; delete p;}
370 #if TEST_STD_VER >= 11
371     test_deleter* operator&() const = delete;
372 #else
373 private:
374   test_deleter* operator&() const;
375 #endif
376 };
377 
378 template <class T>
379 void
swap(test_deleter<T> & x,test_deleter<T> & y)380 swap(test_deleter<T>& x, test_deleter<T>& y)
381 {
382     test_deleter<T> t(std::move(x));
383     x = std::move(y);
384     y = std::move(t);
385 }
386 
387 #if TEST_STD_VER >= 11
388 
389 template <class T, size_t ID = 0>
390 class PointerDeleter
391 {
392     PointerDeleter(const PointerDeleter&);
393     PointerDeleter& operator=(const PointerDeleter&);
394 
395 public:
396     typedef min_pointer<T, std::integral_constant<size_t, ID>> pointer;
397 
398     PointerDeleter() = default;
399     PointerDeleter(PointerDeleter&&) = default;
400     PointerDeleter& operator=(PointerDeleter&&) = default;
PointerDeleter(int)401     explicit PointerDeleter(int) {}
402 
403     template <class U>
404         PointerDeleter(PointerDeleter<U, ID>&&,
405             typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
406     {}
407 
operator()408     void operator()(pointer p) { if (p) { delete std::addressof(*p); }}
409 
410 private:
411     template <class U>
412         PointerDeleter(const PointerDeleter<U, ID>&,
413             typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
414 };
415 
416 
417 template <class T, size_t ID>
418 class PointerDeleter<T[], ID>
419 {
420     PointerDeleter(const PointerDeleter&);
421     PointerDeleter& operator=(const PointerDeleter&);
422 
423 public:
424     typedef min_pointer<T, std::integral_constant<size_t, ID> > pointer;
425 
426     PointerDeleter() = default;
427     PointerDeleter(PointerDeleter&&) = default;
428     PointerDeleter& operator=(PointerDeleter&&) = default;
PointerDeleter(int)429     explicit PointerDeleter(int) {}
430 
431     template <class U>
432         PointerDeleter(PointerDeleter<U, ID>&&,
433             typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
434     {}
435 
operator()436     void operator()(pointer p) { if (p) { delete [] std::addressof(*p); }}
437 
438 private:
439     template <class U>
440         PointerDeleter(const PointerDeleter<U, ID>&,
441             typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
442 };
443 
444 #endif // TEST_STD_VER >= 11
445 
446 #endif  // SUPPORT_DELETER_TYPES_H
447