Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(373)

Side by Side Diff: base/memory/scoped_ptr.h

Issue 11149006: Extend scoped_ptr to be closer to unique_ptr. Support custom deleters, and deleting arrays. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merged to ToT Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/callback_internal.h ('k') | base/memory/scoped_ptr_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Scopers help you manage ownership of a pointer, helping you easily manage the 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 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 7 // end of a scope. There are two main classes you will use, which correspond
8 // to the operators new/delete and new[]/delete[]. 8 // to the operators new/delete and new[]/delete[].
9 // 9 //
10 // Example usage (scoped_ptr): 10 // Example usage (scoped_ptr):
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 #define BASE_MEMORY_SCOPED_PTR_H_ 88 #define BASE_MEMORY_SCOPED_PTR_H_
89 89
90 // This is an implementation designed to match the anticipated future TR2 90 // This is an implementation designed to match the anticipated future TR2
91 // implementation of the scoped_ptr class, and its closely-related brethren, 91 // implementation of the scoped_ptr class, and its closely-related brethren,
92 // scoped_array, scoped_ptr_malloc. 92 // scoped_array, scoped_ptr_malloc.
93 93
94 #include <assert.h> 94 #include <assert.h>
95 #include <stddef.h> 95 #include <stddef.h>
96 #include <stdlib.h> 96 #include <stdlib.h>
97 97
98 #include <algorithm> // For std::swap().
99
98 #include "base/basictypes.h" 100 #include "base/basictypes.h"
99 #include "base/compiler_specific.h" 101 #include "base/compiler_specific.h"
100 #include "base/move.h" 102 #include "base/move.h"
101 #include "base/template_util.h" 103 #include "base/template_util.h"
102 104
103 namespace base { 105 namespace base {
104 106
105 namespace subtle { 107 namespace subtle {
106 class RefCountedBase; 108 class RefCountedBase;
107 class RefCountedThreadSafeBase; 109 class RefCountedThreadSafeBase;
108 } // namespace subtle 110 } // namespace subtle
109 111
112 // Function object which deletes its parameter, which must be a pointer.
113 // If C is an array type, invokes 'delete[]' on the parameter; otherwise,
114 // invokes 'delete'. The default deleter for scoped_ptr<T>.
115 template <class T>
116 struct DefaultDeleter {
117 DefaultDeleter() {}
118 template <typename U> DefaultDeleter(const DefaultDeleter<U>& other) {
119 // Spec for std::default_deleter only provies this constructor of
120 // U* is implicitly convertible to T* and U is not an array type.
121 //
122 // Correct implementation should use SFINAE to disable this
123 // constructor. However, since there are no other 1-argument constructors
124 // using a COMPILE_ASSERT() based on is_convertible<> and requiring
125 // complete types is simpler and will cause compile failures for equivalent
126 // misuses.
127 //
128 // Note, the is_convertible<U*, T*> check also ensures that U is not an
129 // array. T is guaranteed to be a non-array so any U* where U is an array
130 // cannot convert to T*.
131 enum { T_must_be_complete = sizeof(T) };
132 enum { U_must_be_complete = sizeof(U) };
133 COMPILE_ASSERT((base::is_convertible<U*, T*>::value),
134 U_ptr_must_implicitly_convert_to_T_ptr);
135 }
136 inline void operator()(T* ptr) const {
137 enum { type_must_be_complete = sizeof(T) };
138 delete ptr;
139 }
140 };
141
142 // Specialization of DefaultDeleter for array types.
143 template <class T>
144 struct DefaultDeleter<T[]> {
145 inline void operator()(T* ptr) const {
146 enum { type_must_be_complete = sizeof(T) };
147 delete[] ptr;
148 }
149
150 private:
151 // Disable this operator for any U != T because it is undefined to execute
152 // an array delete when the static type of the array mismatches the dynamic
153 // type.
154 //
155 // References:
156 // C++98 [expr.delete]p3
157 // http://cplusplus.github.com/LWG/lwg-defects.html#938
158 template <typename U> void operator()(U* array) const;
159 };
160
161 template <class T, int n>
162 struct DefaultDeleter<T[n]> {
163 // Never allow someone to delcare something like scoped_ptr<int[10]>.
gromer 2012/12/12 17:29:57 Is there any particular reason to enforce this? I'
awong 2012/12/12 21:00:14 I think without this, you actually do the wrong th
gromer 2012/12/14 16:57:26 Still, it's odd that std::unique_ptr doesn't make
awong 2012/12/14 20:25:26 Kinda... If I remove this code and then do: int
gromer 2012/12/14 21:11:46 I'm confused; doesn't this answer your question? I
awong 2012/12/14 21:18:39 Yes...but it must be matched with an delete[]. Wi
164 COMPILE_ASSERT(sizeof(T) == -1, do_not_use_array_with_size_as_type);
165 };
166
167 // Function object which invokes 'free' on its parameter, which must be
168 // a pointer. Can be used to store malloc-allocated pointers in scoped_ptr:
169 //
170 // scoped_ptr<int, base::FreeDeleter> foo_ptr(
171 // static_cast<int*>(malloc(sizeof(int))));
172 struct FreeDeleter {
173 inline void operator()(void* ptr) const {
174 free(ptr);
175 }
176 };
177
110 namespace internal { 178 namespace internal {
111 179
112 template <typename T> struct IsNotRefCounted { 180 template <typename T> struct IsNotRefCounted {
113 enum { 181 enum {
114 value = !base::is_convertible<T*, base::subtle::RefCountedBase*>::value && 182 value = !base::is_convertible<T*, base::subtle::RefCountedBase*>::value &&
115 !base::is_convertible<T*, base::subtle::RefCountedThreadSafeBase*>:: 183 !base::is_convertible<T*, base::subtle::RefCountedThreadSafeBase*>::
116 value 184 value
117 }; 185 };
118 }; 186 };
119 187
188 // Minimal implementation of the core logic of scoped_ptr, suitable for
189 // reuse in both scoped_ptr and its specializations.
190 template <class T, class D>
191 class scoped_ptr_impl {
192 public:
193 explicit scoped_ptr_impl(T* p) : data_(p) { }
194
195 // Initializer for deleters that have data parameters.
196 scoped_ptr_impl(T* p, const D& d) : data_(p, d) {}
197
198 // Templated constructor that destructively takes the value from another
199 // scoped_ptr_impl.
200 template <typename U, typename V>
201 scoped_ptr_impl(scoped_ptr_impl<U, V>* other)
202 : data_(other->release(), other->get_deleter()) {
203 // We do not support move-only deleters. We could modify our move
204 // emulation to have base::subtle::move() and base::subtle::forward()
205 // functions that are imperfect emulations of their C++11 equivalents,
206 // but until there's a requirement, just assume deleters are copyable.
207 }
208
209 template <typename U, typename V>
210 void TakeState(scoped_ptr_impl<U, V>* other) {
211 // See comment in templated constructor above regarding lack of support
212 // for move-only deleters.
213 reset(other->release());
214 get_deleter() = other->get_deleter();
215 }
216
217 ~scoped_ptr_impl() {
218 if (data_.ptr != NULL) {
219 // Not using get_deleter() saves one function call in non-optimized
220 // builds.
221 static_cast<D&>(data_)(data_.ptr);
222 }
223 }
224
225 void reset(T* p) {
226 // This self-reset check is deprecated.
227 // this->reset(this->get()) currently works, but it is DEPRECATED, and
228 // will be removed once we verify that no one depends on it.
229 //
230 // TODO(ajwong): Change this behavior to match unique_ptr<>.
231 // http://crbug.com/162971
232 if (p != data_.ptr) {
233 if (data_.ptr != NULL) {
234 // Note that this can lead to undefined behavior and memory leaks
235 // in the unlikely but possible case that get_deleter()(get())
236 // indirectly deletes this. The fix is to reset ptr_ before deleting
237 // its old value, but first we need to clean up the code that relies
238 // on the current sequencing.
239 static_cast<D&>(data_)(data_.ptr);
240 }
241 data_.ptr = p;
242 }
243 }
244
245 T* get() const { return data_.ptr; }
246
247 D& get_deleter() { return data_; }
248 const D& get_deleter() const { return data_; }
249
250 void swap(scoped_ptr_impl& p2) {
251 // Standard swap idiom: 'using std::swap' ensures that std::swap is
252 // present in the overload set, but we call swap unqualified so that
253 // any more-specific overloads can be used, if available.
254 using std::swap;
255 swap(static_cast<D&>(data_), static_cast<D&>(p2.data_));
256 swap(data_.ptr, p2.data_.ptr);
257 }
258
259 T* release() {
260 T* old_ptr = data_.ptr;
261 data_.ptr = NULL;
262 return old_ptr;
263 }
264
265 private:
266 // Needed to allow type-converting constructor.
267 template <typename U, typename V> friend class scoped_ptr_impl;
268
269 // Use the empty base class optimization to allow us to have a D
270 // member, while avoiding any space overhead for it when D is an
271 // empty class. See e.g. http://www.cantrip.org/emptyopt.html for a good
272 // discussion of this technique.
273 struct Data : public D {
274 explicit Data(T* ptr_in) : ptr(ptr_in) {}
275 Data(T* ptr_in, const D& other) : D(other), ptr(ptr_in) {}
276 T* ptr;
277 };
278
279 Data data_;
280
281 DISALLOW_COPY_AND_ASSIGN(scoped_ptr_impl);
282 };
283
120 } // namespace internal 284 } // namespace internal
285
121 } // namespace base 286 } // namespace base
122 287
123 // A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T> 288 // A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T>
124 // automatically deletes the pointer it holds (if any). 289 // automatically deletes the pointer it holds (if any).
125 // That is, scoped_ptr<T> owns the T object that it points to. 290 // That is, scoped_ptr<T> owns the T object that it points to.
126 // Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object. 291 // Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object.
127 // Also like T*, scoped_ptr<T> is thread-compatible, and once you 292 // Also like T*, scoped_ptr<T> is thread-compatible, and once you
128 // dereference it, you get the thread safety guarantees of T. 293 // dereference it, you get the thread safety guarantees of T.
129 // 294 //
130 // The size of a scoped_ptr is small: 295 // The size of a scoped_ptr is small:
131 // sizeof(scoped_ptr<C>) == sizeof(C*) 296 // sizeof(scoped_ptr<T>) == sizeof(T*)
gromer 2012/12/12 17:29:57 Might want to give a little more detail here: size
awong 2012/12/12 21:00:14 Referred people to the scoped_ptr_impl<> comment.
gromer 2012/12/14 16:57:26 "size ... is small" is redundant, and it'd be good
awong 2012/12/14 20:25:26 Hedged it by saying "on most compilers"
gromer 2012/12/14 21:11:46 I feel like this still risks giving the impression
awong 2012/12/15 00:19:08 Added more details.
gromer 2012/12/15 00:21:40 FWIW I would have accepted _fewer_ details, a la m
132 template <class C> 297 //
298 // Current implementation targets having a strict subset of C++11's
299 // unique_ptr<> features. Known deficiencies include not supporting move-only
300 // deleteres, function pointers as deleteres, and deleters with reference
Ryan Sleevi 2012/12/12 03:37:47 spelling nit: deleteres -> deleters
awong 2012/12/12 21:00:14 Done.
301 // types.
302 template <class T, class D = base::DefaultDeleter<T> >
133 class scoped_ptr { 303 class scoped_ptr {
134 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue) 304 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue)
135 305
136 COMPILE_ASSERT(base::internal::IsNotRefCounted<C>::value, 306 COMPILE_ASSERT(base::internal::IsNotRefCounted<T>::value,
137 C_is_refcounted_type_and_needs_scoped_refptr); 307 T_is_refcounted_type_and_needs_scoped_refptr);
138 308
139 public: 309 public:
140 310 // The element and deleter types.
141 // The element type 311 typedef T element_type;
142 typedef C element_type; 312 typedef D deleter_type;
143 313
144 // Constructor. Defaults to initializing with NULL. 314 // Constructor. Defaults to initializing with NULL.
145 // There is no way to create an uninitialized scoped_ptr. 315 scoped_ptr() : impl_(NULL) { }
146 // The input parameter must be allocated with new. 316
147 explicit scoped_ptr(C* p = NULL) : ptr_(p) { } 317 // Constructor. Takes ownership of p.
318 explicit scoped_ptr(element_type* p) : impl_(p) { }
319
320 // Constructor. Allows initialization of a stateful deleter.
321 scoped_ptr(element_type* p, const D& d) : impl_(p, d) { }
148 322
149 // Constructor. Allows construction from a scoped_ptr rvalue for a 323 // Constructor. Allows construction from a scoped_ptr rvalue for a
150 // convertible type. 324 // convertible type and deleter.
151 template <typename U> 325 //
152 scoped_ptr(scoped_ptr<U> other) : ptr_(other.release()) { } 326 // Note: C++11 unique_ptr<> keeps this destructor distinct from
gromer 2012/12/12 17:29:57 destructor -> constructor
gromer 2012/12/12 17:29:57 I'm not sure this comment is necessary; readers wh
awong 2012/12/12 21:00:14 Done.
awong 2012/12/12 21:00:14 I changed it to IMPLEMENTATION NOTE. I want to ke
327 // the normal move constructor. By C++11 20.7.1.2.1.21, this constructor
328 // has different post-conditions if D is a reference type. Since this
329 // implementation does not support deleters with reference type,
330 // we do not need a separate move constructor allowing us to avoid one
331 // use of SFINAE.
332 template <typename U, typename V>
333 scoped_ptr(scoped_ptr<U, V> other) : impl_(&other.impl_) {
334 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array);
335 }
153 336
154 // Constructor. Move constructor for C++03 move emulation of this type. 337 // Constructor. Move constructor for C++03 move emulation of this type.
155 scoped_ptr(RValue rvalue) 338 scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { }
156 : ptr_(rvalue.object->release()) {
157 }
158
159 // Destructor. If there is a C object, delete it.
160 // We don't need to test ptr_ == NULL because C++ does that for us.
161 ~scoped_ptr() {
162 enum { type_must_be_complete = sizeof(C) };
163 delete ptr_;
164 }
165 339
166 // operator=. Allows assignment from a scoped_ptr rvalue for a convertible 340 // operator=. Allows assignment from a scoped_ptr rvalue for a convertible
167 // type. 341 // type and deleter.
168 template <typename U> 342 //
169 scoped_ptr& operator=(scoped_ptr<U> rhs) { 343 // Note: C++11 unique_ptr<> keeps this operator= distinct from
gromer 2012/12/12 17:29:57 Same here.
awong 2012/12/12 21:00:14 Done.
170 reset(rhs.release()); 344 // the normal move operator. By C++11 20.7.1.2.3.4, this templated form has
gromer 2012/12/12 17:29:57 move -> move assignment
awong 2012/12/12 21:00:14 Done.
gromer 2012/12/14 16:57:26 Still need to fix line 345
awong 2012/12/14 20:25:26 Done.
345 // different requirements on for move-only Deleters. Since this
346 // implementation does not support move-only Deleters, we do not need a
347 // separate move operator allowing us to avoid one use of SFINAE.
348 template <typename U, typename V>
349 scoped_ptr& operator=(scoped_ptr<U, V> rhs) {
350 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array);
351 impl_.TakeState(&rhs.impl_);
171 return *this; 352 return *this;
172 } 353 }
173 354
174 // operator=. Move operator= for C++03 move emulation of this type. 355 // Reset. Deletes the currently owned object, if any.
175 scoped_ptr& operator=(RValue rhs) {
176 swap(*rhs->object);
177 return *this;
178 }
179
180 // Reset. Deletes the current owned object, if any.
181 // Then takes ownership of a new object, if given. 356 // Then takes ownership of a new object, if given.
182 // this->reset(this->get()) works. 357 void reset(element_type* p = NULL) { impl_.reset(p); }
183 void reset(C* p = NULL) {
184 if (p != ptr_) {
185 enum { type_must_be_complete = sizeof(C) };
186 delete ptr_;
187 ptr_ = p;
188 }
189 }
190 358
191 // Accessors to get the owned object. 359 // Accessors to get the owned object.
192 // operator* and operator-> will assert() if there is no current object. 360 // operator* and operator-> will assert() if there is no current object.
193 C& operator*() const { 361 element_type& operator*() const {
194 assert(ptr_ != NULL); 362 assert(impl_.get() != NULL);
195 return *ptr_; 363 return *impl_.get();
196 } 364 }
197 C* operator->() const { 365 element_type* operator->() const {
198 assert(ptr_ != NULL); 366 assert(impl_.get() != NULL);
199 return ptr_; 367 return impl_.get();
200 } 368 }
201 C* get() const { return ptr_; } 369 element_type* get() const { return impl_.get(); }
202 370
203 // Allow scoped_ptr<C> to be used in boolean expressions, but not 371 // Access to the deleter.
372 deleter_type& get_deleter() { return impl_.get_deleter(); }
373 const deleter_type& get_deleter() const { return impl_.get_deleter(); }
374
375 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not
204 // implicitly convertible to a real bool (which is dangerous). 376 // implicitly convertible to a real bool (which is dangerous).
205 typedef C* scoped_ptr::*Testable; 377 private:
206 operator Testable() const { return ptr_ ? &scoped_ptr::ptr_ : NULL; } 378 typedef base::internal::scoped_ptr_impl<element_type, deleter_type>
379 scoped_ptr::*Testable;
380
381 public:
382 operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; }
207 383
208 // Comparison operators. 384 // Comparison operators.
209 // These return whether two scoped_ptr refer to the same object, not just to 385 // These return whether two scoped_ptr refer to the same object, not just to
210 // two different but equal objects. 386 // two different but equal objects.
211 bool operator==(C* p) const { return ptr_ == p; } 387 bool operator==(element_type* p) const { return impl_.get() == p; }
212 bool operator!=(C* p) const { return ptr_ != p; } 388 bool operator!=(element_type* p) const { return impl_.get() != p; }
213 389
214 // Swap two scoped pointers. 390 // Swap two scoped pointers.
215 void swap(scoped_ptr& p2) { 391 void swap(scoped_ptr& p2) {
216 C* tmp = ptr_; 392 impl_.swap(p2.impl_);
217 ptr_ = p2.ptr_;
218 p2.ptr_ = tmp;
219 } 393 }
220 394
221 // Release a pointer. 395 // Release a pointer.
222 // The return value is the current pointer held by this object. 396 // The return value is the current pointer held by this object.
223 // If this object holds a NULL pointer, the return value is NULL. 397 // If this object holds a NULL pointer, the return value is NULL.
224 // After this operation, this object will hold a NULL pointer, 398 // After this operation, this object will hold a NULL pointer,
225 // and will not own the object any more. 399 // and will not own the object any more.
226 C* release() WARN_UNUSED_RESULT { 400 element_type* release() WARN_UNUSED_RESULT {
227 C* retVal = ptr_; 401 return impl_.release();
228 ptr_ = NULL;
229 return retVal;
230 } 402 }
231 403
404 // C++98 doesn't support functions templates with default parameters which
405 // makes it hard to write a PassAs() that understands converting the deleter
406 // while preserving simple calling semantics.
407 //
408 // Until there is a use case for PassAs() with custom deleters, just ignore
409 // the custom deleter.
232 template <typename PassAsType> 410 template <typename PassAsType>
233 scoped_ptr<PassAsType> PassAs() { 411 scoped_ptr<PassAsType> PassAs() {
234 return scoped_ptr<PassAsType>(release()); 412 return scoped_ptr<PassAsType>(Pass());
235 } 413 }
236 414
237 private: 415 private:
238 C* ptr_; 416 // Needed to reach into |impl_| in the constructor.
417 template <typename U, typename V> friend class scoped_ptr;
418 base::internal::scoped_ptr_impl<element_type, deleter_type> impl_;
239 419
240 // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't 420 // Forbid comparison of scoped_ptr types. If U != T, it totally
241 // make sense, and if C2 == C, it still doesn't make sense because you should 421 // doesn't make sense, and if U == T, it still doesn't make sense
242 // never have the same object owned by two different scoped_ptrs. 422 // because you should never have the same object owned by two different
243 template <class C2> bool operator==(scoped_ptr<C2> const& p2) const; 423 // scoped_ptrs.
244 template <class C2> bool operator!=(scoped_ptr<C2> const& p2) const; 424 template <class U> bool operator==(scoped_ptr<U> const& p2) const;
425 template <class U> bool operator!=(scoped_ptr<U> const& p2) const;
426 };
245 427
428 template <class T, class D>
429 class scoped_ptr<T[], D> {
430 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue)
431
432 public:
433 // The element and deleter types.
434 typedef T element_type;
435 typedef D deleter_type;
436
437 // Constructor. Defaults to initializing with NULL.
438 scoped_ptr() : impl_(NULL) { }
439
440 // Constructor. Stores the given array. Note that the argument's type
441 // must exactly match T*. In particular:
442 // - it cannot be a pointer to a type derived from T, because it is
443 // inherently unsafe in the general case to access an array through a
444 // pointer whose dynamic type does not match its static type (eg., if
445 // T and the derived types had different sizes access would be
446 // incorrectly calculated). Deletion is also always undefined
447 // (C++98 [expr.delete]p3). If you're doing this, fix your code.
448 // - it cannot be NULL, because NULL is an integral expression, not a
449 // pointer to T. Use the no-argument version instead of explicitly
450 // passing NULL.
451 // - it cannot be const-qualified differently from T per unique_ptr spec
452 // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting
453 // to work around this may use implicit_cast<const T*>().
454 // However, because of the first bullet in this comment, users MUST
455 // NOT use implicit_cast<Base*>() to upcast the static type of the array.
456 explicit scoped_ptr(element_type* array) : impl_(array) { }
457
458 // Constructor. Move constructor for C++03 move emulation of this type.
459 scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { }
460
461 // operator=. Move operator= for C++03 move emulation of this type.
462 scoped_ptr& operator=(RValue rhs) {
463 impl_.TakeState(&rhs.object->impl_);
464 return *this;
465 }
466
467 // Reset. Deletes the currently owned array, if any.
468 // Then takes ownership of a new object, if given.
469 void reset(element_type* array = NULL) { impl_.reset(array); }
470
471 // Accessors to get the owned array.
472 element_type& operator[](size_t i) const {
473 assert(impl_.get() != NULL);
474 return impl_.get()[i];
475 }
476 element_type* get() const { return impl_.get(); }
477
478 // Access to the deleter.
479 deleter_type& get_deleter() { return impl_.get_deleter(); }
480 const deleter_type& get_deleter() const { return impl_.get_deleter(); }
481
482 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not
483 // implicitly convertible to a real bool (which is dangerous).
484 private:
485 typedef base::internal::scoped_ptr_impl<element_type, deleter_type>
486 scoped_ptr::*Testable;
487
488 public:
489 operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; }
490
491 // Comparison operators.
492 // These return whether two scoped_ptr refer to the same object, not just to
493 // two different but equal objects.
494 bool operator==(element_type* array) const { return impl_.get() == array; }
495 bool operator!=(element_type* array) const { return impl_.get() != array; }
496
497 // Swap two scoped pointers.
498 void swap(scoped_ptr& p2) {
499 impl_.swap(p2.impl_);
500 }
501
502 // Release a pointer.
503 // The return value is the current pointer held by this object.
504 // If this object holds a NULL pointer, the return value is NULL.
505 // After this operation, this object will hold a NULL pointer,
506 // and will not own the object any more.
507 element_type* release() WARN_UNUSED_RESULT {
508 return impl_.release();
509 }
510
511 private:
512 // Force element_type to be a complete type.
513 enum { type_must_be_complete = sizeof(element_type) };
514
515 // Actually hold the data.
516 base::internal::scoped_ptr_impl<element_type, deleter_type> impl_;
517
518 // Disable initialization from any type other than element_type*, by
519 // providing a constructor that matches such an initialization, but is
520 // private and has no definition. This is disabled because it is not safe to
521 // call delete[] on an array whose static type does not match its dynamic
522 // type.
523 template <typename U>
524 explicit scoped_ptr(U* array);
525
526 // Disable reset() from any type other than element_type*, for the same
527 // reasons as the constructor above.
528 template <typename U>
529 void reset(U* array);
530
531 // Forbid comparison of scoped_ptr types. If U != T, it totally
532 // doesn't make sense, and if U == T, it still doesn't make sense
533 // because you should never have the same object owned by two different
534 // scoped_ptrs.
535 template <class U> bool operator==(scoped_ptr<U> const& p2) const;
536 template <class U> bool operator!=(scoped_ptr<U> const& p2) const;
246 }; 537 };
247 538
248 // Free functions 539 // Free functions
249 template <class C> 540 template <class T, class D>
250 void swap(scoped_ptr<C>& p1, scoped_ptr<C>& p2) { 541 void swap(scoped_ptr<T, D>& p1, scoped_ptr<T, D>& p2) {
251 p1.swap(p2); 542 p1.swap(p2);
252 } 543 }
253 544
254 template <class C> 545 template <class T, class D>
255 bool operator==(C* p1, const scoped_ptr<C>& p2) { 546 bool operator==(T* p1, const scoped_ptr<T, D>& p2) {
256 return p1 == p2.get(); 547 return p1 == p2.get();
257 } 548 }
258 549
259 template <class C> 550 template <class T, class D>
260 bool operator!=(C* p1, const scoped_ptr<C>& p2) { 551 bool operator!=(T* p1, const scoped_ptr<T, D>& p2) {
261 return p1 != p2.get(); 552 return p1 != p2.get();
262 } 553 }
263 554
555 // DEPRECATED: Use scoped_ptr<C[]> instead.
556 //
264 // scoped_array<C> is like scoped_ptr<C>, except that the caller must allocate 557 // scoped_array<C> is like scoped_ptr<C>, except that the caller must allocate
265 // with new [] and the destructor deletes objects with delete []. 558 // with new [] and the destructor deletes objects with delete [].
266 // 559 //
267 // As with scoped_ptr<C>, a scoped_array<C> either points to an object 560 // As with scoped_ptr<C>, a scoped_array<C> either points to an object
268 // or is NULL. A scoped_array<C> owns the object that it points to. 561 // or is NULL. A scoped_array<C> owns the object that it points to.
269 // scoped_array<T> is thread-compatible, and once you index into it, 562 // scoped_array<T> is thread-compatible, and once you index into it,
270 // the returned objects have only the thread safety guarantees of T. 563 // the returned objects have only the thread safety guarantees of T.
271 // 564 //
272 // Size: sizeof(scoped_array<C>) == sizeof(C*) 565 // Size: sizeof(scoped_array<C>) == sizeof(C*)
273 template <class C> 566 template <class C>
(...skipping 17 matching lines...) Expand all
291 584
292 // Destructor. If there is a C object, delete it. 585 // Destructor. If there is a C object, delete it.
293 // We don't need to test ptr_ == NULL because C++ does that for us. 586 // We don't need to test ptr_ == NULL because C++ does that for us.
294 ~scoped_array() { 587 ~scoped_array() {
295 enum { type_must_be_complete = sizeof(C) }; 588 enum { type_must_be_complete = sizeof(C) };
296 delete[] array_; 589 delete[] array_;
297 } 590 }
298 591
299 // operator=. Move operator= for C++03 move emulation of this type. 592 // operator=. Move operator= for C++03 move emulation of this type.
300 scoped_array& operator=(RValue rhs) { 593 scoped_array& operator=(RValue rhs) {
301 swap(*rhs.object); 594 reset(rhs.object->release());
302 return *this; 595 return *this;
303 } 596 }
304 597
305 // Reset. Deletes the current owned object, if any. 598 // Reset. Deletes the current owned object, if any.
306 // Then takes ownership of a new object, if given. 599 // Then takes ownership of a new object, if given.
307 // this->reset(this->get()) works. 600 // this->reset(this->get()) works.
308 void reset(C* p = NULL) { 601 void reset(C* p = NULL) {
309 if (p != array_) { 602 if (p != array_) {
310 enum { type_must_be_complete = sizeof(C) }; 603 enum { type_must_be_complete = sizeof(C) };
311 delete[] array_; 604 delete[] array_;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 template <class C> 666 template <class C>
374 bool operator==(C* p1, const scoped_array<C>& p2) { 667 bool operator==(C* p1, const scoped_array<C>& p2) {
375 return p1 == p2.get(); 668 return p1 == p2.get();
376 } 669 }
377 670
378 template <class C> 671 template <class C>
379 bool operator!=(C* p1, const scoped_array<C>& p2) { 672 bool operator!=(C* p1, const scoped_array<C>& p2) {
380 return p1 != p2.get(); 673 return p1 != p2.get();
381 } 674 }
382 675
383 // This class wraps the c library function free() in a class that can be 676 // DEPRECATED: Use scoped_ptr<C, base::FreeDeleter> instead.
384 // passed as a template argument to scoped_ptr_malloc below. 677 //
385 class ScopedPtrMallocFree {
386 public:
387 inline void operator()(void* x) const {
388 free(x);
389 }
390 };
391
392 // scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a 678 // scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a
393 // second template argument, the functor used to free the object. 679 // second template argument, the functor used to free the object.
394 680
395 template<class C, class FreeProc = ScopedPtrMallocFree> 681 template<class C, class FreeProc = base::FreeDeleter>
396 class scoped_ptr_malloc { 682 class scoped_ptr_malloc {
397 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr_malloc, RValue) 683 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr_malloc, RValue)
398 684
399 public: 685 public:
400 686
401 // The element type 687 // The element type
402 typedef C element_type; 688 typedef C element_type;
403 689
404 // Constructor. Defaults to initializing with NULL. 690 // Constructor. Defaults to initializing with NULL.
405 // There is no way to create an uninitialized scoped_ptr. 691 // There is no way to create an uninitialized scoped_ptr.
406 // The input parameter must be allocated with an allocator that matches the 692 // The input parameter must be allocated with an allocator that matches the
407 // Free functor. For the default Free functor, this is malloc, calloc, or 693 // Free functor. For the default Free functor, this is malloc, calloc, or
408 // realloc. 694 // realloc.
409 explicit scoped_ptr_malloc(C* p = NULL): ptr_(p) {} 695 explicit scoped_ptr_malloc(C* p = NULL): ptr_(p) {}
410 696
411 // Constructor. Move constructor for C++03 move emulation of this type. 697 // Constructor. Move constructor for C++03 move emulation of this type.
412 scoped_ptr_malloc(RValue rvalue) 698 scoped_ptr_malloc(RValue rvalue)
413 : ptr_(rvalue.object->release()) { 699 : ptr_(rvalue.object->release()) {
414 } 700 }
415 701
416 // Destructor. If there is a C object, call the Free functor. 702 // Destructor. If there is a C object, call the Free functor.
417 ~scoped_ptr_malloc() { 703 ~scoped_ptr_malloc() {
418 reset(); 704 reset();
419 } 705 }
420 706
421 // operator=. Move operator= for C++03 move emulation of this type. 707 // operator=. Move operator= for C++03 move emulation of this type.
422 scoped_ptr_malloc& operator=(RValue rhs) { 708 scoped_ptr_malloc& operator=(RValue rhs) {
423 swap(*rhs.object); 709 reset(rhs.object->release());
424 return *this; 710 return *this;
425 } 711 }
426 712
427 // Reset. Calls the Free functor on the current owned object, if any. 713 // Reset. Calls the Free functor on the current owned object, if any.
428 // Then takes ownership of a new object, if given. 714 // Then takes ownership of a new object, if given.
429 // this->reset(this->get()) works. 715 // this->reset(this->get()) works.
430 void reset(C* p = NULL) { 716 void reset(C* p = NULL) {
431 if (ptr_ != p) { 717 if (ptr_ != p) {
432 FreeProc free_proc; 718 if (ptr_ != NULL) {
433 free_proc(ptr_); 719 FreeProc free_proc;
720 free_proc(ptr_);
721 }
434 ptr_ = p; 722 ptr_ = p;
435 } 723 }
436 } 724 }
437 725
438 // Get the current object. 726 // Get the current object.
439 // operator* and operator-> will cause an assert() failure if there is 727 // operator* and operator-> will cause an assert() failure if there is
440 // no current object. 728 // no current object.
441 C& operator*() const { 729 C& operator*() const {
442 assert(ptr_ != NULL); 730 assert(ptr_ != NULL);
443 return *ptr_; 731 return *ptr_;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 803
516 // A function to convert T* into scoped_ptr<T> 804 // A function to convert T* into scoped_ptr<T>
517 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation 805 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation
518 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) 806 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
519 template <typename T> 807 template <typename T>
520 scoped_ptr<T> make_scoped_ptr(T* ptr) { 808 scoped_ptr<T> make_scoped_ptr(T* ptr) {
521 return scoped_ptr<T>(ptr); 809 return scoped_ptr<T>(ptr);
522 } 810 }
523 811
524 #endif // BASE_MEMORY_SCOPED_PTR_H_ 812 #endif // BASE_MEMORY_SCOPED_PTR_H_
OLDNEW
« no previous file with comments | « base/callback_internal.h ('k') | base/memory/scoped_ptr_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698