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 template <class T>
24 class Deleter
25 {
26 int state_;
27
28 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
29 Deleter(const Deleter&);
30 Deleter& operator=(const Deleter&);
31 #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
32 Deleter(Deleter&);
33 Deleter& operator=(Deleter&);
34 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
35
36 public:
37 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Deleter(Deleter && r)38 Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
39 Deleter& operator=(Deleter&& r)
40 {
41 state_ = r.state_;
42 r.state_ = 0;
43 return *this;
44 }
45 #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
46 operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
47 Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
48 Deleter& operator=(std::__rv<Deleter> r)
49 {
50 state_ = r->state_;
51 r->state_ = 0;
52 return *this;
53 }
54 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
55
Deleter()56 Deleter() : state_(0) {}
Deleter(int s)57 explicit Deleter(int s) : state_(s) {}
~Deleter()58 ~Deleter() {assert(state_ >= 0); state_ = -1;}
59
60 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
61 template <class U>
62 Deleter(Deleter<U>&& d,
63 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
64 : state_(d.state()) {d.set_state(0);}
65
66 private:
67 template <class U>
68 Deleter(const Deleter<U>& d,
69 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
70 #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
71 template <class U>
72 Deleter(Deleter<U> d,
73 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
74 : state_(d.state()) {}
75 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
76 public:
state()77 int state() const {return state_;}
set_state(int i)78 void set_state(int i) {state_ = i;}
79
operator()80 void operator()(T* p) {delete p;}
81 };
82
83 template <class T>
84 class Deleter<T[]>
85 {
86 int state_;
87
88 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
89 Deleter(const Deleter&);
90 Deleter& operator=(const Deleter&);
91 #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
92 Deleter(Deleter&);
93 Deleter& operator=(Deleter&);
94 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
95
96 public:
97 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Deleter(Deleter && r)98 Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
99 Deleter& operator=(Deleter&& r)
100 {
101 state_ = r.state_;
102 r.state_ = 0;
103 return *this;
104 }
105 #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
106 operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
107 Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
108 Deleter& operator=(std::__rv<Deleter> r)
109 {
110 state_ = r->state_;
111 r->state_ = 0;
112 return *this;
113 }
114 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
115
Deleter()116 Deleter() : state_(0) {}
Deleter(int s)117 explicit Deleter(int s) : state_(s) {}
~Deleter()118 ~Deleter() {assert(state_ >= 0); state_ = -1;}
119
state()120 int state() const {return state_;}
set_state(int i)121 void set_state(int i) {state_ = i;}
122
operator()123 void operator()(T* p) {delete [] p;}
124 };
125
126 template <class T>
127 void
swap(Deleter<T> & x,Deleter<T> & y)128 swap(Deleter<T>& x, Deleter<T>& y)
129 {
130 Deleter<T> t(std::move(x));
131 x = std::move(y);
132 y = std::move(t);
133 }
134
135 template <class T>
136 class CDeleter
137 {
138 int state_;
139
140 public:
141
CDeleter()142 CDeleter() : state_(0) {}
CDeleter(int s)143 explicit CDeleter(int s) : state_(s) {}
~CDeleter()144 ~CDeleter() {assert(state_ >= 0); state_ = -1;}
145
146 template <class U>
CDeleter(const CDeleter<U> & d)147 CDeleter(const CDeleter<U>& d)
148 : state_(d.state()) {}
149
state()150 int state() const {return state_;}
set_state(int i)151 void set_state(int i) {state_ = i;}
152
operator()153 void operator()(T* p) {delete p;}
154 };
155
156 template <class T>
157 class CDeleter<T[]>
158 {
159 int state_;
160
161 public:
162
CDeleter()163 CDeleter() : state_(0) {}
CDeleter(int s)164 explicit CDeleter(int s) : state_(s) {}
~CDeleter()165 ~CDeleter() {assert(state_ >= 0); state_ = -1;}
166
state()167 int state() const {return state_;}
set_state(int i)168 void set_state(int i) {state_ = i;}
169
operator()170 void operator()(T* p) {delete [] p;}
171 };
172
173 template <class T>
174 void
swap(CDeleter<T> & x,CDeleter<T> & y)175 swap(CDeleter<T>& x, CDeleter<T>& y)
176 {
177 CDeleter<T> t(std::move(x));
178 x = std::move(y);
179 y = std::move(t);
180 }
181
182 #endif // DELETER_H
183