|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
|
2 // Use of this source code is governed by a BSD-style license that can be |
|
3 // found in the LICENSE file. |
|
4 |
|
5 // Scopers help you manage ownership of a pointer, helping you easily manage the |
|
6 // a pointer within a scope, and automatically destroying the pointer at the |
|
7 // end of a scope. There are two main classes you will use, which correspond |
|
8 // to the operators new/delete and new[]/delete[]. |
|
9 // |
|
10 // Example usage (scoped_ptr<T>): |
|
11 // { |
|
12 // scoped_ptr<Foo> foo(new Foo("wee")); |
|
13 // } // foo goes out of scope, releasing the pointer with it. |
|
14 // |
|
15 // { |
|
16 // scoped_ptr<Foo> foo; // No pointer managed. |
|
17 // foo.reset(new Foo("wee")); // Now a pointer is managed. |
|
18 // foo.reset(new Foo("wee2")); // Foo("wee") was destroyed. |
|
19 // foo.reset(new Foo("wee3")); // Foo("wee2") was destroyed. |
|
20 // foo->Method(); // Foo::Method() called. |
|
21 // foo.get()->Method(); // Foo::Method() called. |
|
22 // SomeFunc(foo.release()); // SomeFunc takes ownership, foo no longer |
|
23 // // manages a pointer. |
|
24 // foo.reset(new Foo("wee4")); // foo manages a pointer again. |
|
25 // foo.reset(); // Foo("wee4") destroyed, foo no longer |
|
26 // // manages a pointer. |
|
27 // } // foo wasn't managing a pointer, so nothing was destroyed. |
|
28 // |
|
29 // Example usage (scoped_ptr<T[]>): |
|
30 // { |
|
31 // scoped_ptr<Foo[]> foo(new Foo[100]); |
|
32 // foo.get()->Method(); // Foo::Method on the 0th element. |
|
33 // foo[10].Method(); // Foo::Method on the 10th element. |
|
34 // } |
|
35 // |
|
36 // These scopers also implement part of the functionality of C++11 unique_ptr |
|
37 // in that they are "movable but not copyable." You can use the scopers in |
|
38 // the parameter and return types of functions to signify ownership transfer |
|
39 // in to and out of a function. When calling a function that has a scoper |
|
40 // as the argument type, it must be called with the result of an analogous |
|
41 // scoper's Pass() function or another function that generates a temporary; |
|
42 // passing by copy will NOT work. Here is an example using scoped_ptr: |
|
43 // |
|
44 // void TakesOwnership(scoped_ptr<Foo> arg) { |
|
45 // // Do something with arg |
|
46 // } |
|
47 // scoped_ptr<Foo> CreateFoo() { |
|
48 // // No need for calling Pass() because we are constructing a temporary |
|
49 // // for the return value. |
|
50 // return scoped_ptr<Foo>(new Foo("new")); |
|
51 // } |
|
52 // scoped_ptr<Foo> PassThru(scoped_ptr<Foo> arg) { |
|
53 // return arg.Pass(); |
|
54 // } |
|
55 // |
|
56 // { |
|
57 // scoped_ptr<Foo> ptr(new Foo("yay")); // ptr manages Foo("yay"). |
|
58 // TakesOwnership(ptr.Pass()); // ptr no longer owns Foo("yay"). |
|
59 // scoped_ptr<Foo> ptr2 = CreateFoo(); // ptr2 owns the return Foo. |
|
60 // scoped_ptr<Foo> ptr3 = // ptr3 now owns what was in ptr2. |
|
61 // PassThru(ptr2.Pass()); // ptr2 is correspondingly NULL. |
|
62 // } |
|
63 // |
|
64 // Notice that if you do not call Pass() when returning from PassThru(), or |
|
65 // when invoking TakesOwnership(), the code will not compile because scopers |
|
66 // are not copyable; they only implement move semantics which require calling |
|
67 // the Pass() function to signify a destructive transfer of state. CreateFoo() |
|
68 // is different though because we are constructing a temporary on the return |
|
69 // line and thus can avoid needing to call Pass(). |
|
70 // |
|
71 // Pass() properly handles upcast in assignment, i.e. you can assign |
|
72 // scoped_ptr<Child> to scoped_ptr<Parent>: |
|
73 // |
|
74 // scoped_ptr<Foo> foo(new Foo()); |
|
75 // scoped_ptr<FooParent> parent = foo.Pass(); |
|
76 // |
|
77 // PassAs<>() should be used to upcast return value in return statement: |
|
78 // |
|
79 // scoped_ptr<Foo> CreateFoo() { |
|
80 // scoped_ptr<FooChild> result(new FooChild()); |
|
81 // return result.PassAs<Foo>(); |
|
82 // } |
|
83 // |
|
84 // Note that PassAs<>() is implemented only for scoped_ptr<T>, but not for |
|
85 // scoped_ptr<T[]>. This is because casting array pointers may not be safe. |
|
86 |
|
87 #ifndef BASE_MEMORY_SCOPED_PTR_H_ |
|
88 #define BASE_MEMORY_SCOPED_PTR_H_ |
|
89 |
|
90 // This is an implementation designed to match the anticipated future TR2 |
|
91 // implementation of the scoped_ptr class and scoped_ptr_malloc (deprecated). |
|
92 |
|
93 #include <assert.h> |
|
94 #include <stddef.h> |
|
95 #include <stdlib.h> |
|
96 |
|
97 #include <algorithm> // For std::swap(). |
|
98 |
|
99 #include "base/basictypes.h" |
|
100 #include "base/compiler_specific.h" |
|
101 #include "base/move.h" |
|
102 #include "base/template_util.h" |
|
103 |
|
104 namespace base { |
|
105 |
|
106 namespace subtle { |
|
107 class RefCountedBase; |
|
108 class RefCountedThreadSafeBase; |
|
109 } // namespace subtle |
|
110 |
|
111 // Function object which deletes its parameter, which must be a pointer. |
|
112 // If C is an array type, invokes 'delete[]' on the parameter; otherwise, |
|
113 // invokes 'delete'. The default deleter for scoped_ptr<T>. |
|
114 template <class T> |
|
115 struct DefaultDeleter { |
|
116 DefaultDeleter() {} |
|
117 template <typename U> DefaultDeleter(const DefaultDeleter<U>& other) { |
|
118 // IMPLEMENTATION NOTE: C++11 20.7.1.1.2p2 only provides this constructor |
|
119 // if U* is implicitly convertible to T* and U is not an array type. |
|
120 // |
|
121 // Correct implementation should use SFINAE to disable this |
|
122 // constructor. However, since there are no other 1-argument constructors, |
|
123 // using a COMPILE_ASSERT() based on is_convertible<> and requiring |
|
124 // complete types is simpler and will cause compile failures for equivalent |
|
125 // misuses. |
|
126 // |
|
127 // Note, the is_convertible<U*, T*> check also ensures that U is not an |
|
128 // array. T is guaranteed to be a non-array, so any U* where U is an array |
|
129 // cannot convert to T*. |
|
130 enum { T_must_be_complete = sizeof(T) }; |
|
131 enum { U_must_be_complete = sizeof(U) }; |
|
132 COMPILE_ASSERT((base::is_convertible<U*, T*>::value), |
|
133 U_ptr_must_implicitly_convert_to_T_ptr); |
|
134 } |
|
135 inline void operator()(T* ptr) const { |
|
136 enum { type_must_be_complete = sizeof(T) }; |
|
137 delete ptr; |
|
138 } |
|
139 }; |
|
140 |
|
141 // Specialization of DefaultDeleter for array types. |
|
142 template <class T> |
|
143 struct DefaultDeleter<T[]> { |
|
144 inline void operator()(T* ptr) const { |
|
145 enum { type_must_be_complete = sizeof(T) }; |
|
146 delete[] ptr; |
|
147 } |
|
148 |
|
149 private: |
|
150 // Disable this operator for any U != T because it is undefined to execute |
|
151 // an array delete when the static type of the array mismatches the dynamic |
|
152 // type. |
|
153 // |
|
154 // References: |
|
155 // C++98 [expr.delete]p3 |
|
156 // http://cplusplus.github.com/LWG/lwg-defects.html#938 |
|
157 template <typename U> void operator()(U* array) const; |
|
158 }; |
|
159 |
|
160 template <class T, int n> |
|
161 struct DefaultDeleter<T[n]> { |
|
162 // Never allow someone to declare something like scoped_ptr<int[10]>. |
|
163 COMPILE_ASSERT(sizeof(T) == -1, do_not_use_array_with_size_as_type); |
|
164 }; |
|
165 |
|
166 // Function object which invokes 'free' on its parameter, which must be |
|
167 // a pointer. Can be used to store malloc-allocated pointers in scoped_ptr: |
|
168 // |
|
169 // scoped_ptr<int, base::FreeDeleter> foo_ptr( |
|
170 // static_cast<int*>(malloc(sizeof(int)))); |
|
171 struct FreeDeleter { |
|
172 inline void operator()(void* ptr) const { |
|
173 free(ptr); |
|
174 } |
|
175 }; |
|
176 |
|
177 namespace internal { |
|
178 |
|
179 template <typename T> struct IsNotRefCounted { |
|
180 enum { |
|
181 value = !base::is_convertible<T*, base::subtle::RefCountedBase*>::value && |
|
182 !base::is_convertible<T*, base::subtle::RefCountedThreadSafeBase*>:: |
|
183 value |
|
184 }; |
|
185 }; |
|
186 |
|
187 // Minimal implementation of the core logic of scoped_ptr, suitable for |
|
188 // reuse in both scoped_ptr and its specializations. |
|
189 template <class T, class D> |
|
190 class scoped_ptr_impl { |
|
191 public: |
|
192 explicit scoped_ptr_impl(T* p) : data_(p) { } |
|
193 |
|
194 // Initializer for deleters that have data parameters. |
|
195 scoped_ptr_impl(T* p, const D& d) : data_(p, d) {} |
|
196 |
|
197 // Templated constructor that destructively takes the value from another |
|
198 // scoped_ptr_impl. |
|
199 template <typename U, typename V> |
|
200 scoped_ptr_impl(scoped_ptr_impl<U, V>* other) |
|
201 : data_(other->release(), other->get_deleter()) { |
|
202 // We do not support move-only deleters. We could modify our move |
|
203 // emulation to have base::subtle::move() and base::subtle::forward() |
|
204 // functions that are imperfect emulations of their C++11 equivalents, |
|
205 // but until there's a requirement, just assume deleters are copyable. |
|
206 } |
|
207 |
|
208 template <typename U, typename V> |
|
209 void TakeState(scoped_ptr_impl<U, V>* other) { |
|
210 // See comment in templated constructor above regarding lack of support |
|
211 // for move-only deleters. |
|
212 reset(other->release()); |
|
213 get_deleter() = other->get_deleter(); |
|
214 } |
|
215 |
|
216 ~scoped_ptr_impl() { |
|
217 if (data_.ptr != NULL) { |
|
218 // Not using get_deleter() saves one function call in non-optimized |
|
219 // builds. |
|
220 static_cast<D&>(data_)(data_.ptr); |
|
221 } |
|
222 } |
|
223 |
|
224 void reset(T* p) { |
|
225 // This is a self-reset, which is no longer allowed: http://crbug.com/162971 |
|
226 if (p != NULL && p == data_.ptr) |
|
227 abort(); |
|
228 |
|
229 // Note that running data_.ptr = p can lead to undefined behavior if |
|
230 // get_deleter()(get()) deletes this. In order to pevent this, reset() |
|
231 // should update the stored pointer before deleting its old value. |
|
232 // |
|
233 // However, changing reset() to use that behavior may cause current code to |
|
234 // break in unexpected ways. If the destruction of the owned object |
|
235 // dereferences the scoped_ptr when it is destroyed by a call to reset(), |
|
236 // then it will incorrectly dispatch calls to |p| rather than the original |
|
237 // value of |data_.ptr|. |
|
238 // |
|
239 // During the transition period, set the stored pointer to NULL while |
|
240 // deleting the object. Eventually, this safety check will be removed to |
|
241 // prevent the scenario initially described from occuring and |
|
242 // http://crbug.com/176091 can be closed. |
|
243 T* old = data_.ptr; |
|
244 data_.ptr = NULL; |
|
245 if (old != NULL) |
|
246 static_cast<D&>(data_)(old); |
|
247 data_.ptr = p; |
|
248 } |
|
249 |
|
250 T* get() const { return data_.ptr; } |
|
251 |
|
252 D& get_deleter() { return data_; } |
|
253 const D& get_deleter() const { return data_; } |
|
254 |
|
255 void swap(scoped_ptr_impl& p2) { |
|
256 // Standard swap idiom: 'using std::swap' ensures that std::swap is |
|
257 // present in the overload set, but we call swap unqualified so that |
|
258 // any more-specific overloads can be used, if available. |
|
259 using std::swap; |
|
260 swap(static_cast<D&>(data_), static_cast<D&>(p2.data_)); |
|
261 swap(data_.ptr, p2.data_.ptr); |
|
262 } |
|
263 |
|
264 T* release() { |
|
265 T* old_ptr = data_.ptr; |
|
266 data_.ptr = NULL; |
|
267 return old_ptr; |
|
268 } |
|
269 |
|
270 private: |
|
271 // Needed to allow type-converting constructor. |
|
272 template <typename U, typename V> friend class scoped_ptr_impl; |
|
273 |
|
274 // Use the empty base class optimization to allow us to have a D |
|
275 // member, while avoiding any space overhead for it when D is an |
|
276 // empty class. See e.g. http://www.cantrip.org/emptyopt.html for a good |
|
277 // discussion of this technique. |
|
278 struct Data : public D { |
|
279 explicit Data(T* ptr_in) : ptr(ptr_in) {} |
|
280 Data(T* ptr_in, const D& other) : D(other), ptr(ptr_in) {} |
|
281 T* ptr; |
|
282 }; |
|
283 |
|
284 Data data_; |
|
285 |
|
286 DISALLOW_COPY_AND_ASSIGN(scoped_ptr_impl); |
|
287 }; |
|
288 |
|
289 } // namespace internal |
|
290 |
|
291 } // namespace base |
|
292 |
|
293 // A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T> |
|
294 // automatically deletes the pointer it holds (if any). |
|
295 // That is, scoped_ptr<T> owns the T object that it points to. |
|
296 // Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object. |
|
297 // Also like T*, scoped_ptr<T> is thread-compatible, and once you |
|
298 // dereference it, you get the thread safety guarantees of T. |
|
299 // |
|
300 // The size of scoped_ptr is small. On most compilers, when using the |
|
301 // DefaultDeleter, sizeof(scoped_ptr<T>) == sizeof(T*). Custom deleters will |
|
302 // increase the size proportional to whatever state they need to have. See |
|
303 // comments inside scoped_ptr_impl<> for details. |
|
304 // |
|
305 // Current implementation targets having a strict subset of C++11's |
|
306 // unique_ptr<> features. Known deficiencies include not supporting move-only |
|
307 // deleteres, function pointers as deleters, and deleters with reference |
|
308 // types. |
|
309 template <class T, class D = base::DefaultDeleter<T> > |
|
310 class scoped_ptr { |
|
311 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue) |
|
312 |
|
313 COMPILE_ASSERT(base::internal::IsNotRefCounted<T>::value, |
|
314 T_is_refcounted_type_and_needs_scoped_refptr); |
|
315 |
|
316 public: |
|
317 // The element and deleter types. |
|
318 typedef T element_type; |
|
319 typedef D deleter_type; |
|
320 |
|
321 // Constructor. Defaults to initializing with NULL. |
|
322 scoped_ptr() : impl_(NULL) { } |
|
323 |
|
324 // Constructor. Takes ownership of p. |
|
325 explicit scoped_ptr(element_type* p) : impl_(p) { } |
|
326 |
|
327 // Constructor. Allows initialization of a stateful deleter. |
|
328 scoped_ptr(element_type* p, const D& d) : impl_(p, d) { } |
|
329 |
|
330 // Constructor. Allows construction from a scoped_ptr rvalue for a |
|
331 // convertible type and deleter. |
|
332 // |
|
333 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this constructor distinct |
|
334 // from the normal move constructor. By C++11 20.7.1.2.1.21, this constructor |
|
335 // has different post-conditions if D is a reference type. Since this |
|
336 // implementation does not support deleters with reference type, |
|
337 // we do not need a separate move constructor allowing us to avoid one |
|
338 // use of SFINAE. You only need to care about this if you modify the |
|
339 // implementation of scoped_ptr. |
|
340 template <typename U, typename V> |
|
341 scoped_ptr(scoped_ptr<U, V> other) : impl_(&other.impl_) { |
|
342 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); |
|
343 } |
|
344 |
|
345 // Constructor. Move constructor for C++03 move emulation of this type. |
|
346 scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { } |
|
347 |
|
348 // operator=. Allows assignment from a scoped_ptr rvalue for a convertible |
|
349 // type and deleter. |
|
350 // |
|
351 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from |
|
352 // the normal move assignment operator. By C++11 20.7.1.2.3.4, this templated |
|
353 // form has different requirements on for move-only Deleters. Since this |
|
354 // implementation does not support move-only Deleters, we do not need a |
|
355 // separate move assignment operator allowing us to avoid one use of SFINAE. |
|
356 // You only need to care about this if you modify the implementation of |
|
357 // scoped_ptr. |
|
358 template <typename U, typename V> |
|
359 scoped_ptr& operator=(scoped_ptr<U, V> rhs) { |
|
360 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); |
|
361 impl_.TakeState(&rhs.impl_); |
|
362 return *this; |
|
363 } |
|
364 |
|
365 // Reset. Deletes the currently owned object, if any. |
|
366 // Then takes ownership of a new object, if given. |
|
367 void reset(element_type* p = NULL) { impl_.reset(p); } |
|
368 |
|
369 // Accessors to get the owned object. |
|
370 // operator* and operator-> will assert() if there is no current object. |
|
371 element_type& operator*() const { |
|
372 assert(impl_.get() != NULL); |
|
373 return *impl_.get(); |
|
374 } |
|
375 element_type* operator->() const { |
|
376 assert(impl_.get() != NULL); |
|
377 return impl_.get(); |
|
378 } |
|
379 element_type* get() const { return impl_.get(); } |
|
380 |
|
381 // Access to the deleter. |
|
382 deleter_type& get_deleter() { return impl_.get_deleter(); } |
|
383 const deleter_type& get_deleter() const { return impl_.get_deleter(); } |
|
384 |
|
385 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not |
|
386 // implicitly convertible to a real bool (which is dangerous). |
|
387 // |
|
388 // Note that this trick is only safe when the == and != operators |
|
389 // are declared explicitly, as otherwise "scoped_ptr1 == |
|
390 // scoped_ptr2" will compile but do the wrong thing (i.e., convert |
|
391 // to Testable and then do the comparison). |
|
392 private: |
|
393 typedef base::internal::scoped_ptr_impl<element_type, deleter_type> |
|
394 scoped_ptr::*Testable; |
|
395 |
|
396 public: |
|
397 operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; } |
|
398 |
|
399 // Comparison operators. |
|
400 // These return whether two scoped_ptr refer to the same object, not just to |
|
401 // two different but equal objects. |
|
402 bool operator==(const element_type* p) const { return impl_.get() == p; } |
|
403 bool operator!=(const element_type* p) const { return impl_.get() != p; } |
|
404 |
|
405 // Swap two scoped pointers. |
|
406 void swap(scoped_ptr& p2) { |
|
407 impl_.swap(p2.impl_); |
|
408 } |
|
409 |
|
410 // Release a pointer. |
|
411 // The return value is the current pointer held by this object. |
|
412 // If this object holds a NULL pointer, the return value is NULL. |
|
413 // After this operation, this object will hold a NULL pointer, |
|
414 // and will not own the object any more. |
|
415 element_type* release() WARN_UNUSED_RESULT { |
|
416 return impl_.release(); |
|
417 } |
|
418 |
|
419 // C++98 doesn't support functions templates with default parameters which |
|
420 // makes it hard to write a PassAs() that understands converting the deleter |
|
421 // while preserving simple calling semantics. |
|
422 // |
|
423 // Until there is a use case for PassAs() with custom deleters, just ignore |
|
424 // the custom deleter. |
|
425 template <typename PassAsType> |
|
426 scoped_ptr<PassAsType> PassAs() { |
|
427 return scoped_ptr<PassAsType>(Pass()); |
|
428 } |
|
429 |
|
430 private: |
|
431 // Needed to reach into |impl_| in the constructor. |
|
432 template <typename U, typename V> friend class scoped_ptr; |
|
433 base::internal::scoped_ptr_impl<element_type, deleter_type> impl_; |
|
434 |
|
435 // Forbidden for API compatibility with std::unique_ptr. |
|
436 explicit scoped_ptr(int disallow_construction_from_null); |
|
437 |
|
438 // Forbid comparison of scoped_ptr types. If U != T, it totally |
|
439 // doesn't make sense, and if U == T, it still doesn't make sense |
|
440 // because you should never have the same object owned by two different |
|
441 // scoped_ptrs. |
|
442 template <class U> bool operator==(scoped_ptr<U> const& p2) const; |
|
443 template <class U> bool operator!=(scoped_ptr<U> const& p2) const; |
|
444 }; |
|
445 |
|
446 template <class T, class D> |
|
447 class scoped_ptr<T[], D> { |
|
448 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue) |
|
449 |
|
450 public: |
|
451 // The element and deleter types. |
|
452 typedef T element_type; |
|
453 typedef D deleter_type; |
|
454 |
|
455 // Constructor. Defaults to initializing with NULL. |
|
456 scoped_ptr() : impl_(NULL) { } |
|
457 |
|
458 // Constructor. Stores the given array. Note that the argument's type |
|
459 // must exactly match T*. In particular: |
|
460 // - it cannot be a pointer to a type derived from T, because it is |
|
461 // inherently unsafe in the general case to access an array through a |
|
462 // pointer whose dynamic type does not match its static type (eg., if |
|
463 // T and the derived types had different sizes access would be |
|
464 // incorrectly calculated). Deletion is also always undefined |
|
465 // (C++98 [expr.delete]p3). If you're doing this, fix your code. |
|
466 // - it cannot be NULL, because NULL is an integral expression, not a |
|
467 // pointer to T. Use the no-argument version instead of explicitly |
|
468 // passing NULL. |
|
469 // - it cannot be const-qualified differently from T per unique_ptr spec |
|
470 // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting |
|
471 // to work around this may use implicit_cast<const T*>(). |
|
472 // However, because of the first bullet in this comment, users MUST |
|
473 // NOT use implicit_cast<Base*>() to upcast the static type of the array. |
|
474 explicit scoped_ptr(element_type* array) : impl_(array) { } |
|
475 |
|
476 // Constructor. Move constructor for C++03 move emulation of this type. |
|
477 scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { } |
|
478 |
|
479 // operator=. Move operator= for C++03 move emulation of this type. |
|
480 scoped_ptr& operator=(RValue rhs) { |
|
481 impl_.TakeState(&rhs.object->impl_); |
|
482 return *this; |
|
483 } |
|
484 |
|
485 // Reset. Deletes the currently owned array, if any. |
|
486 // Then takes ownership of a new object, if given. |
|
487 void reset(element_type* array = NULL) { impl_.reset(array); } |
|
488 |
|
489 // Accessors to get the owned array. |
|
490 element_type& operator[](size_t i) const { |
|
491 assert(impl_.get() != NULL); |
|
492 return impl_.get()[i]; |
|
493 } |
|
494 element_type* get() const { return impl_.get(); } |
|
495 |
|
496 // Access to the deleter. |
|
497 deleter_type& get_deleter() { return impl_.get_deleter(); } |
|
498 const deleter_type& get_deleter() const { return impl_.get_deleter(); } |
|
499 |
|
500 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not |
|
501 // implicitly convertible to a real bool (which is dangerous). |
|
502 private: |
|
503 typedef base::internal::scoped_ptr_impl<element_type, deleter_type> |
|
504 scoped_ptr::*Testable; |
|
505 |
|
506 public: |
|
507 operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; } |
|
508 |
|
509 // Comparison operators. |
|
510 // These return whether two scoped_ptr refer to the same object, not just to |
|
511 // two different but equal objects. |
|
512 bool operator==(element_type* array) const { return impl_.get() == array; } |
|
513 bool operator!=(element_type* array) const { return impl_.get() != array; } |
|
514 |
|
515 // Swap two scoped pointers. |
|
516 void swap(scoped_ptr& p2) { |
|
517 impl_.swap(p2.impl_); |
|
518 } |
|
519 |
|
520 // Release a pointer. |
|
521 // The return value is the current pointer held by this object. |
|
522 // If this object holds a NULL pointer, the return value is NULL. |
|
523 // After this operation, this object will hold a NULL pointer, |
|
524 // and will not own the object any more. |
|
525 element_type* release() WARN_UNUSED_RESULT { |
|
526 return impl_.release(); |
|
527 } |
|
528 |
|
529 private: |
|
530 // Force element_type to be a complete type. |
|
531 enum { type_must_be_complete = sizeof(element_type) }; |
|
532 |
|
533 // Actually hold the data. |
|
534 base::internal::scoped_ptr_impl<element_type, deleter_type> impl_; |
|
535 |
|
536 // Disable initialization from any type other than element_type*, by |
|
537 // providing a constructor that matches such an initialization, but is |
|
538 // private and has no definition. This is disabled because it is not safe to |
|
539 // call delete[] on an array whose static type does not match its dynamic |
|
540 // type. |
|
541 template <typename U> explicit scoped_ptr(U* array); |
|
542 explicit scoped_ptr(int disallow_construction_from_null); |
|
543 |
|
544 // Disable reset() from any type other than element_type*, for the same |
|
545 // reasons as the constructor above. |
|
546 template <typename U> void reset(U* array); |
|
547 void reset(int disallow_reset_from_null); |
|
548 |
|
549 // Forbid comparison of scoped_ptr types. If U != T, it totally |
|
550 // doesn't make sense, and if U == T, it still doesn't make sense |
|
551 // because you should never have the same object owned by two different |
|
552 // scoped_ptrs. |
|
553 template <class U> bool operator==(scoped_ptr<U> const& p2) const; |
|
554 template <class U> bool operator!=(scoped_ptr<U> const& p2) const; |
|
555 }; |
|
556 |
|
557 // Free functions |
|
558 template <class T, class D> |
|
559 void swap(scoped_ptr<T, D>& p1, scoped_ptr<T, D>& p2) { |
|
560 p1.swap(p2); |
|
561 } |
|
562 |
|
563 template <class T, class D> |
|
564 bool operator==(T* p1, const scoped_ptr<T, D>& p2) { |
|
565 return p1 == p2.get(); |
|
566 } |
|
567 |
|
568 template <class T, class D> |
|
569 bool operator!=(T* p1, const scoped_ptr<T, D>& p2) { |
|
570 return p1 != p2.get(); |
|
571 } |
|
572 |
|
573 // DEPRECATED: Use scoped_ptr<C, base::FreeDeleter> instead. |
|
574 // |
|
575 // scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a |
|
576 // second template argument, the functor used to free the object. |
|
577 |
|
578 template<class C, class FreeProc = base::FreeDeleter> |
|
579 class scoped_ptr_malloc { |
|
580 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr_malloc, RValue) |
|
581 |
|
582 public: |
|
583 |
|
584 // The element type |
|
585 typedef C element_type; |
|
586 |
|
587 // Constructor. Defaults to initializing with NULL. |
|
588 // There is no way to create an uninitialized scoped_ptr. |
|
589 // The input parameter must be allocated with an allocator that matches the |
|
590 // Free functor. For the default Free functor, this is malloc, calloc, or |
|
591 // realloc. |
|
592 explicit scoped_ptr_malloc(C* p = NULL): ptr_(p) {} |
|
593 |
|
594 // Constructor. Move constructor for C++03 move emulation of this type. |
|
595 scoped_ptr_malloc(RValue rvalue) |
|
596 : ptr_(rvalue.object->release()) { |
|
597 } |
|
598 |
|
599 // Destructor. If there is a C object, call the Free functor. |
|
600 ~scoped_ptr_malloc() { |
|
601 reset(); |
|
602 } |
|
603 |
|
604 // operator=. Move operator= for C++03 move emulation of this type. |
|
605 scoped_ptr_malloc& operator=(RValue rhs) { |
|
606 reset(rhs.object->release()); |
|
607 return *this; |
|
608 } |
|
609 |
|
610 // Reset. Calls the Free functor on the current owned object, if any. |
|
611 // Then takes ownership of a new object, if given. |
|
612 // this->reset(this->get()) works. |
|
613 void reset(C* p = NULL) { |
|
614 if (ptr_ != p) { |
|
615 if (ptr_ != NULL) { |
|
616 FreeProc free_proc; |
|
617 free_proc(ptr_); |
|
618 } |
|
619 ptr_ = p; |
|
620 } |
|
621 } |
|
622 |
|
623 // Get the current object. |
|
624 // operator* and operator-> will cause an assert() failure if there is |
|
625 // no current object. |
|
626 C& operator*() const { |
|
627 assert(ptr_ != NULL); |
|
628 return *ptr_; |
|
629 } |
|
630 |
|
631 C* operator->() const { |
|
632 assert(ptr_ != NULL); |
|
633 return ptr_; |
|
634 } |
|
635 |
|
636 C* get() const { |
|
637 return ptr_; |
|
638 } |
|
639 |
|
640 // Allow scoped_ptr_malloc<C> to be used in boolean expressions, but not |
|
641 // implicitly convertible to a real bool (which is dangerous). |
|
642 typedef C* scoped_ptr_malloc::*Testable; |
|
643 operator Testable() const { return ptr_ ? &scoped_ptr_malloc::ptr_ : NULL; } |
|
644 |
|
645 // Comparison operators. |
|
646 // These return whether a scoped_ptr_malloc and a plain pointer refer |
|
647 // to the same object, not just to two different but equal objects. |
|
648 // For compatibility with the boost-derived implementation, these |
|
649 // take non-const arguments. |
|
650 bool operator==(C* p) const { |
|
651 return ptr_ == p; |
|
652 } |
|
653 |
|
654 bool operator!=(C* p) const { |
|
655 return ptr_ != p; |
|
656 } |
|
657 |
|
658 // Swap two scoped pointers. |
|
659 void swap(scoped_ptr_malloc & b) { |
|
660 C* tmp = b.ptr_; |
|
661 b.ptr_ = ptr_; |
|
662 ptr_ = tmp; |
|
663 } |
|
664 |
|
665 // Release a pointer. |
|
666 // The return value is the current pointer held by this object. |
|
667 // If this object holds a NULL pointer, the return value is NULL. |
|
668 // After this operation, this object will hold a NULL pointer, |
|
669 // and will not own the object any more. |
|
670 C* release() WARN_UNUSED_RESULT { |
|
671 C* tmp = ptr_; |
|
672 ptr_ = NULL; |
|
673 return tmp; |
|
674 } |
|
675 |
|
676 private: |
|
677 C* ptr_; |
|
678 |
|
679 // no reason to use these: each scoped_ptr_malloc should have its own object |
|
680 template <class C2, class GP> |
|
681 bool operator==(scoped_ptr_malloc<C2, GP> const& p) const; |
|
682 template <class C2, class GP> |
|
683 bool operator!=(scoped_ptr_malloc<C2, GP> const& p) const; |
|
684 }; |
|
685 |
|
686 template<class C, class FP> inline |
|
687 void swap(scoped_ptr_malloc<C, FP>& a, scoped_ptr_malloc<C, FP>& b) { |
|
688 a.swap(b); |
|
689 } |
|
690 |
|
691 template<class C, class FP> inline |
|
692 bool operator==(C* p, const scoped_ptr_malloc<C, FP>& b) { |
|
693 return p == b.get(); |
|
694 } |
|
695 |
|
696 template<class C, class FP> inline |
|
697 bool operator!=(C* p, const scoped_ptr_malloc<C, FP>& b) { |
|
698 return p != b.get(); |
|
699 } |
|
700 |
|
701 // A function to convert T* into scoped_ptr<T> |
|
702 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation |
|
703 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) |
|
704 template <typename T> |
|
705 scoped_ptr<T> make_scoped_ptr(T* ptr) { |
|
706 return scoped_ptr<T>(ptr); |
|
707 } |
|
708 |
|
709 #endif // BASE_MEMORY_SCOPED_PTR_H_ |