OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. | |
3 * | |
4 * This library is free software; you can redistribute it and/or | |
5 * modify it under the terms of the GNU Library General Public | |
6 * License as published by the Free Software Foundation; either | |
7 * version 2 of the License, or (at your option) any later version. | |
8 * | |
9 * This library is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 * Library General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU Library General Public License | |
15 * along with this library; see the file COPYING.LIB. If not, write to | |
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
17 * Boston, MA 02110-1301, USA. | |
18 * | |
19 */ | |
20 | |
21 #ifndef WTF_OwnPtr_h | |
22 #define WTF_OwnPtr_h | |
23 | |
24 #include <wtf/Assertions.h> | |
25 #include <wtf/Noncopyable.h> | |
26 #include <wtf/NullPtr.h> | |
27 #include <wtf/OwnPtrCommon.h> | |
28 #include <wtf/TypeTraits.h> | |
29 #include <algorithm> | |
30 #include <memory> | |
31 | |
32 namespace WTF { | |
33 | |
34 // Unlike most of our smart pointers, OwnPtr can take either the pointer typ
e or the pointed-to type. | |
35 | |
36 template<typename T> class PassOwnPtr; | |
37 template<typename T> PassOwnPtr<T> adoptPtr(T*); | |
38 | |
39 template<typename T> class OwnPtr { | |
40 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) | |
41 // If rvalue references are not supported, the copy constructor is | |
42 // public so OwnPtr cannot be marked noncopyable. See note below. | |
43 WTF_MAKE_NONCOPYABLE(OwnPtr); | |
44 #endif | |
45 public: | |
46 typedef typename RemovePointer<T>::Type ValueType; | |
47 typedef ValueType* PtrType; | |
48 | |
49 OwnPtr() : m_ptr(0) { } | |
50 OwnPtr(std::nullptr_t) : m_ptr(0) { } | |
51 | |
52 // See comment in PassOwnPtr.h for why this takes a const reference. | |
53 template<typename U> OwnPtr(const PassOwnPtr<U>& o); | |
54 | |
55 #if !COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) | |
56 // This copy constructor is used implicitly by gcc when it generates | |
57 // transients for assigning a PassOwnPtr<T> object to a stack-allocated | |
58 // OwnPtr<T> object. It should never be called explicitly and gcc | |
59 // should optimize away the constructor when generating code. | |
60 OwnPtr(const OwnPtr<ValueType>&); | |
61 #endif | |
62 | |
63 ~OwnPtr() { deleteOwnedPtr(m_ptr); } | |
64 | |
65 PtrType get() const { return m_ptr; } | |
66 | |
67 void clear(); | |
68 PassOwnPtr<T> release(); | |
69 PtrType leakPtr() WARN_UNUSED_RETURN; | |
70 | |
71 ValueType& operator*() const { ASSERT(m_ptr); return *m_ptr; } | |
72 PtrType operator->() const { ASSERT(m_ptr); return m_ptr; } | |
73 | |
74 bool operator!() const { return !m_ptr; } | |
75 | |
76 // This conversion operator allows implicit conversion to bool but not t
o other integer types. | |
77 typedef PtrType OwnPtr::*UnspecifiedBoolType; | |
78 operator UnspecifiedBoolType() const { return m_ptr ? &OwnPtr::m_ptr : 0
; } | |
79 | |
80 OwnPtr& operator=(const PassOwnPtr<T>&); | |
81 OwnPtr& operator=(std::nullptr_t) { clear(); return *this; } | |
82 template<typename U> OwnPtr& operator=(const PassOwnPtr<U>&); | |
83 | |
84 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) | |
85 OwnPtr(OwnPtr&&); | |
86 template<typename U> OwnPtr(OwnPtr<U>&&); | |
87 | |
88 OwnPtr& operator=(OwnPtr&&); | |
89 template<typename U> OwnPtr& operator=(OwnPtr<U>&&); | |
90 #endif | |
91 | |
92 void swap(OwnPtr& o) { std::swap(m_ptr, o.m_ptr); } | |
93 | |
94 private: | |
95 #if !COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) | |
96 // If rvalue references are supported, noncopyable takes care of this. | |
97 OwnPtr& operator=(const OwnPtr&); | |
98 #endif | |
99 | |
100 // We should never have two OwnPtrs for the same underlying object (othe
rwise we'll get | |
101 // double-destruction), so these equality operators should never be need
ed. | |
102 template<typename U> bool operator==(const OwnPtr<U>&) { COMPILE_ASSERT(
!sizeof(U*), OwnPtrs_should_never_be_equal); return false; } | |
103 template<typename U> bool operator!=(const OwnPtr<U>&) { COMPILE_ASSERT(
!sizeof(U*), OwnPtrs_should_never_be_equal); return false; } | |
104 template<typename U> bool operator==(const PassOwnPtr<U>&) { COMPILE_ASS
ERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; } | |
105 template<typename U> bool operator!=(const PassOwnPtr<U>&) { COMPILE_ASS
ERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; } | |
106 | |
107 PtrType m_ptr; | |
108 }; | |
109 | |
110 template<typename T> template<typename U> inline OwnPtr<T>::OwnPtr(const Pas
sOwnPtr<U>& o) | |
111 : m_ptr(o.leakPtr()) | |
112 { | |
113 } | |
114 | |
115 template<typename T> inline void OwnPtr<T>::clear() | |
116 { | |
117 PtrType ptr = m_ptr; | |
118 m_ptr = 0; | |
119 deleteOwnedPtr(ptr); | |
120 } | |
121 | |
122 template<typename T> inline PassOwnPtr<T> OwnPtr<T>::release() | |
123 { | |
124 PtrType ptr = m_ptr; | |
125 m_ptr = 0; | |
126 return adoptPtr(ptr); | |
127 } | |
128 | |
129 template<typename T> inline typename OwnPtr<T>::PtrType OwnPtr<T>::leakPtr() | |
130 { | |
131 PtrType ptr = m_ptr; | |
132 m_ptr = 0; | |
133 return ptr; | |
134 } | |
135 | |
136 template<typename T> inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr
<T>& o) | |
137 { | |
138 PtrType ptr = m_ptr; | |
139 m_ptr = o.leakPtr(); | |
140 ASSERT(!ptr || m_ptr != ptr); | |
141 deleteOwnedPtr(ptr); | |
142 return *this; | |
143 } | |
144 | |
145 template<typename T> template<typename U> inline OwnPtr<T>& OwnPtr<T>::opera
tor=(const PassOwnPtr<U>& o) | |
146 { | |
147 PtrType ptr = m_ptr; | |
148 m_ptr = o.leakPtr(); | |
149 ASSERT(!ptr || m_ptr != ptr); | |
150 deleteOwnedPtr(ptr); | |
151 return *this; | |
152 } | |
153 | |
154 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) | |
155 template<typename T> inline OwnPtr<T>::OwnPtr(OwnPtr<T>&& o) | |
156 : m_ptr(o.leakPtr()) | |
157 { | |
158 } | |
159 | |
160 template<typename T> template<typename U> inline OwnPtr<T>::OwnPtr(OwnPtr<U>
&& o) | |
161 : m_ptr(o.leakPtr()) | |
162 { | |
163 } | |
164 | |
165 template<typename T> inline OwnPtr<T>& OwnPtr<T>::operator=(OwnPtr<T>&& o) | |
166 { | |
167 PtrType ptr = m_ptr; | |
168 m_ptr = o.leakPtr(); | |
169 ASSERT(!ptr || m_ptr != ptr); | |
170 deleteOwnedPtr(ptr); | |
171 | |
172 return *this; | |
173 } | |
174 | |
175 template<typename T> template<typename U> inline OwnPtr<T>& OwnPtr<T>::opera
tor=(OwnPtr<U>&& o) | |
176 { | |
177 PtrType ptr = m_ptr; | |
178 m_ptr = o.leakPtr(); | |
179 ASSERT(!ptr || m_ptr != ptr); | |
180 deleteOwnedPtr(ptr); | |
181 | |
182 return *this; | |
183 } | |
184 #endif | |
185 | |
186 template<typename T> inline void swap(OwnPtr<T>& a, OwnPtr<T>& b) | |
187 { | |
188 a.swap(b); | |
189 } | |
190 | |
191 template<typename T, typename U> inline bool operator==(const OwnPtr<T>& a,
U* b) | |
192 { | |
193 return a.get() == b; | |
194 } | |
195 | |
196 template<typename T, typename U> inline bool operator==(T* a, const OwnPtr<U
>& b) | |
197 { | |
198 return a == b.get(); | |
199 } | |
200 | |
201 template<typename T, typename U> inline bool operator!=(const OwnPtr<T>& a,
U* b) | |
202 { | |
203 return a.get() != b; | |
204 } | |
205 | |
206 template<typename T, typename U> inline bool operator!=(T* a, const OwnPtr<U
>& b) | |
207 { | |
208 return a != b.get(); | |
209 } | |
210 | |
211 template<typename T> inline typename OwnPtr<T>::PtrType getPtr(const OwnPtr<
T>& p) | |
212 { | |
213 return p.get(); | |
214 } | |
215 | |
216 } // namespace WTF | |
217 | |
218 using WTF::OwnPtr; | |
219 | |
220 #endif // WTF_OwnPtr_h | |
OLD | NEW |