blob: f14c74f87d117c0749cb75b77b5d5cb3f7c6d014 [file] [log] [blame]
Howard Hinnant94b2dd02010-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
27#ifdef _LIBCPP_MOVE
28 Deleter(const Deleter&);
29 Deleter& operator=(const Deleter&);
30#else // _LIBCPP_MOVE
31 Deleter(Deleter&);
32 Deleter& operator=(Deleter&);
33#endif // _LIBCPP_MOVE
34
35public:
36#ifdef _LIBCPP_MOVE
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#else // _LIBCPP_MOVE
45 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 }
53#endif // _LIBCPP_MOVE
54
55 Deleter() : state_(0) {}
56 explicit Deleter(int s) : state_(s) {}
57 ~Deleter() {assert(state_ >= 0); state_ = -1;}
58
59#ifdef _LIBCPP_MOVE
60 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);
69#else // _LIBCPP_MOVE
70 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()) {}
74#endif // _LIBCPP_MOVE
75public:
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
87#ifdef _LIBCPP_MOVE
88 Deleter(const Deleter&);
89 Deleter& operator=(const Deleter&);
90#else // _LIBCPP_MOVE
91 Deleter(Deleter&);
92 Deleter& operator=(Deleter&);
93#endif // _LIBCPP_MOVE
94
95public:
96#ifdef _LIBCPP_MOVE
97 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 }
104#else // _LIBCPP_MOVE
105 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 }
113#endif // _LIBCPP_MOVE
114
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