blob: cbba3b67a4df23ee3082bd7fb94956b7e7909c7e [file] [log] [blame]
Howard Hinnantc52f43e2010-08-22 00:59:46 +00001//===----------------------------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. 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 <cassert>
21
22template <class T>
23class Deleter
24{
25 int state_;
26
Howard Hinnant73d21a42010-09-04 23:28:19 +000027#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000028 Deleter(const Deleter&);
29 Deleter& operator=(const Deleter&);
Howard Hinnant73d21a42010-09-04 23:28:19 +000030#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000031 Deleter(Deleter&);
32 Deleter& operator=(Deleter&);
Howard Hinnant73d21a42010-09-04 23:28:19 +000033#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000034
35public:
Howard Hinnant73d21a42010-09-04 23:28:19 +000036#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000037 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 }
Howard Hinnant73d21a42010-09-04 23:28:19 +000044#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000045 operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
46 Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
47 Deleter& operator=(std::__rv<Deleter> r)
48 {
49 state_ = r->state_;
50 r->state_ = 0;
51 return *this;
52 }
Howard Hinnant73d21a42010-09-04 23:28:19 +000053#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000054
55 Deleter() : state_(0) {}
56 explicit Deleter(int s) : state_(s) {}
57 ~Deleter() {assert(state_ >= 0); state_ = -1;}
58
Howard Hinnant73d21a42010-09-04 23:28:19 +000059#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000060 template <class U>
61 Deleter(Deleter<U>&& d,
62 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
63 : state_(d.state()) {d.set_state(0);}
64
65private:
66 template <class U>
67 Deleter(const Deleter<U>& d,
68 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
Howard Hinnant73d21a42010-09-04 23:28:19 +000069#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000070 template <class U>
71 Deleter(Deleter<U> d,
72 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
73 : state_(d.state()) {}
Howard Hinnant73d21a42010-09-04 23:28:19 +000074#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000075public:
76 int state() const {return state_;}
77 void set_state(int i) {state_ = i;}
78
79 void operator()(T* p) {delete p;}
80};
81
82template <class T>
83class Deleter<T[]>
84{
85 int state_;
86
Howard Hinnant73d21a42010-09-04 23:28:19 +000087#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000088 Deleter(const Deleter&);
89 Deleter& operator=(const Deleter&);
Howard Hinnant73d21a42010-09-04 23:28:19 +000090#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000091 Deleter(Deleter&);
92 Deleter& operator=(Deleter&);
Howard Hinnant73d21a42010-09-04 23:28:19 +000093#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000094
95public:
Howard Hinnant73d21a42010-09-04 23:28:19 +000096#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +000097 Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
98 Deleter& operator=(Deleter&& r)
99 {
100 state_ = r.state_;
101 r.state_ = 0;
102 return *this;
103 }
Howard Hinnant73d21a42010-09-04 23:28:19 +0000104#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +0000105 operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
106 Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
107 Deleter& operator=(std::__rv<Deleter> r)
108 {
109 state_ = r->state_;
110 r->state_ = 0;
111 return *this;
112 }
Howard Hinnant73d21a42010-09-04 23:28:19 +0000113#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnantc52f43e2010-08-22 00:59:46 +0000114
115 Deleter() : state_(0) {}
116 explicit Deleter(int s) : state_(s) {}
117 ~Deleter() {assert(state_ >= 0); state_ = -1;}
118
119 int state() const {return state_;}
120 void set_state(int i) {state_ = i;}
121
122 void operator()(T* p) {delete [] p;}
123};
124
125template <class T>
126void
127swap(Deleter<T>& x, Deleter<T>& y)
128{
129 Deleter<T> t(std::move(x));
130 x = std::move(y);
131 y = std::move(t);
132}
133
134template <class T>
135class CDeleter
136{
137 int state_;
138
139public:
140
141 CDeleter() : state_(0) {}
142 explicit CDeleter(int s) : state_(s) {}
143 ~CDeleter() {assert(state_ >= 0); state_ = -1;}
144
145 template <class U>
146 CDeleter(const CDeleter<U>& d)
147 : state_(d.state()) {}
148
149 int state() const {return state_;}
150 void set_state(int i) {state_ = i;}
151
152 void operator()(T* p) {delete p;}
153};
154
155template <class T>
156class CDeleter<T[]>
157{
158 int state_;
159
160public:
161
162 CDeleter() : state_(0) {}
163 explicit CDeleter(int s) : state_(s) {}
164 ~CDeleter() {assert(state_ >= 0); state_ = -1;}
165
166 int state() const {return state_;}
167 void set_state(int i) {state_ = i;}
168
169 void operator()(T* p) {delete [] p;}
170};
171
172template <class T>
173void
174swap(CDeleter<T>& x, CDeleter<T>& y)
175{
176 CDeleter<T> t(std::move(x));
177 x = std::move(y);
178 y = std::move(t);
179}
180
181#endif // DELETER_H