| OLD | NEW |
| 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 a | 5 // Scopers help you manage ownership of a pointer, helping you easily manage a |
| 6 // pointer within a scope, and automatically destroying the pointer at the end | 6 // pointer within a scope, and automatically destroying the pointer at the end |
| 7 // of a scope. There are two main classes you will use, which correspond to the | 7 // of a scope. There are two main classes you will use, which correspond to the |
| 8 // operators new/delete and new[]/delete[]. | 8 // operators new/delete and new[]/delete[]. |
| 9 // | 9 // |
| 10 // Example usage (scoped_ptr<T>): | 10 // Example usage (scoped_ptr<T>): |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 // } | 51 // } |
| 52 // scoped_ptr<Foo> PassThru(scoped_ptr<Foo> arg) { | 52 // scoped_ptr<Foo> PassThru(scoped_ptr<Foo> arg) { |
| 53 // return arg.Pass(); | 53 // return arg.Pass(); |
| 54 // } | 54 // } |
| 55 // | 55 // |
| 56 // { | 56 // { |
| 57 // scoped_ptr<Foo> ptr(new Foo("yay")); // ptr manages Foo("yay"). | 57 // scoped_ptr<Foo> ptr(new Foo("yay")); // ptr manages Foo("yay"). |
| 58 // TakesOwnership(ptr.Pass()); // ptr no longer owns Foo("yay"). | 58 // TakesOwnership(ptr.Pass()); // ptr no longer owns Foo("yay"). |
| 59 // scoped_ptr<Foo> ptr2 = CreateFoo(); // ptr2 owns the return Foo. | 59 // scoped_ptr<Foo> ptr2 = CreateFoo(); // ptr2 owns the return Foo. |
| 60 // scoped_ptr<Foo> ptr3 = // ptr3 now owns what was in ptr2. | 60 // scoped_ptr<Foo> ptr3 = // ptr3 now owns what was in ptr2. |
| 61 // PassThru(ptr2.Pass()); // ptr2 is correspondingly nullptr. | 61 // PassThru(ptr2.Pass()); // ptr2 is correspondingly NULL. |
| 62 // } | 62 // } |
| 63 // | 63 // |
| 64 // Notice that if you do not call Pass() when returning from PassThru(), or | 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 | 65 // when invoking TakesOwnership(), the code will not compile because scopers |
| 66 // are not copyable; they only implement move semantics which require calling | 66 // are not copyable; they only implement move semantics which require calling |
| 67 // the Pass() function to signify a destructive transfer of state. CreateFoo() | 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 | 68 // is different though because we are constructing a temporary on the return |
| 69 // line and thus can avoid needing to call Pass(). | 69 // line and thus can avoid needing to call Pass(). |
| 70 // | 70 // |
| 71 // Pass() properly handles upcast in initialization, i.e. you can use a | 71 // Pass() properly handles upcast in initialization, i.e. you can use a |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 !base::is_convertible<T*, base::subtle::RefCountedThreadSafeBase*>:: | 182 !base::is_convertible<T*, base::subtle::RefCountedThreadSafeBase*>:: |
| 183 value | 183 value |
| 184 }; | 184 }; |
| 185 }; | 185 }; |
| 186 | 186 |
| 187 // Minimal implementation of the core logic of scoped_ptr, suitable for | 187 // Minimal implementation of the core logic of scoped_ptr, suitable for |
| 188 // reuse in both scoped_ptr and its specializations. | 188 // reuse in both scoped_ptr and its specializations. |
| 189 template <class T, class D> | 189 template <class T, class D> |
| 190 class scoped_ptr_impl { | 190 class scoped_ptr_impl { |
| 191 public: | 191 public: |
| 192 explicit scoped_ptr_impl(T* p) : data_(p) {} | 192 explicit scoped_ptr_impl(T* p) : data_(p) { } |
| 193 | 193 |
| 194 // Initializer for deleters that have data parameters. | 194 // Initializer for deleters that have data parameters. |
| 195 scoped_ptr_impl(T* p, const D& d) : data_(p, d) {} | 195 scoped_ptr_impl(T* p, const D& d) : data_(p, d) {} |
| 196 | 196 |
| 197 // Templated constructor that destructively takes the value from another | 197 // Templated constructor that destructively takes the value from another |
| 198 // scoped_ptr_impl. | 198 // scoped_ptr_impl. |
| 199 template <typename U, typename V> | 199 template <typename U, typename V> |
| 200 scoped_ptr_impl(scoped_ptr_impl<U, V>* other) | 200 scoped_ptr_impl(scoped_ptr_impl<U, V>* other) |
| 201 : data_(other->release(), other->get_deleter()) { | 201 : data_(other->release(), other->get_deleter()) { |
| 202 // We do not support move-only deleters. We could modify our move | 202 // We do not support move-only deleters. We could modify our move |
| 203 // emulation to have base::subtle::move() and base::subtle::forward() | 203 // emulation to have base::subtle::move() and base::subtle::forward() |
| 204 // functions that are imperfect emulations of their C++11 equivalents, | 204 // functions that are imperfect emulations of their C++11 equivalents, |
| 205 // but until there's a requirement, just assume deleters are copyable. | 205 // but until there's a requirement, just assume deleters are copyable. |
| 206 } | 206 } |
| 207 | 207 |
| 208 template <typename U, typename V> | 208 template <typename U, typename V> |
| 209 void TakeState(scoped_ptr_impl<U, V>* other) { | 209 void TakeState(scoped_ptr_impl<U, V>* other) { |
| 210 // See comment in templated constructor above regarding lack of support | 210 // See comment in templated constructor above regarding lack of support |
| 211 // for move-only deleters. | 211 // for move-only deleters. |
| 212 reset(other->release()); | 212 reset(other->release()); |
| 213 get_deleter() = other->get_deleter(); | 213 get_deleter() = other->get_deleter(); |
| 214 } | 214 } |
| 215 | 215 |
| 216 ~scoped_ptr_impl() { | 216 ~scoped_ptr_impl() { |
| 217 if (data_.ptr != nullptr) { | 217 if (data_.ptr != NULL) { |
| 218 // Not using get_deleter() saves one function call in non-optimized | 218 // Not using get_deleter() saves one function call in non-optimized |
| 219 // builds. | 219 // builds. |
| 220 static_cast<D&>(data_)(data_.ptr); | 220 static_cast<D&>(data_)(data_.ptr); |
| 221 } | 221 } |
| 222 } | 222 } |
| 223 | 223 |
| 224 void reset(T* p) { | 224 void reset(T* p) { |
| 225 // This is a self-reset, which is no longer allowed: http://crbug.com/162971 | 225 // This is a self-reset, which is no longer allowed: http://crbug.com/162971 |
| 226 if (p != nullptr && p == data_.ptr) | 226 if (p != NULL && p == data_.ptr) |
| 227 abort(); | 227 abort(); |
| 228 | 228 |
| 229 // Note that running data_.ptr = p can lead to undefined behavior if | 229 // Note that running data_.ptr = p can lead to undefined behavior if |
| 230 // get_deleter()(get()) deletes this. In order to prevent this, reset() | 230 // get_deleter()(get()) deletes this. In order to prevent this, reset() |
| 231 // should update the stored pointer before deleting its old value. | 231 // should update the stored pointer before deleting its old value. |
| 232 // | 232 // |
| 233 // However, changing reset() to use that behavior may cause current code to | 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 | 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(), | 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 | 236 // then it will incorrectly dispatch calls to |p| rather than the original |
| 237 // value of |data_.ptr|. | 237 // value of |data_.ptr|. |
| 238 // | 238 // |
| 239 // During the transition period, set the stored pointer to nullptr while | 239 // During the transition period, set the stored pointer to NULL while |
| 240 // deleting the object. Eventually, this safety check will be removed to | 240 // deleting the object. Eventually, this safety check will be removed to |
| 241 // prevent the scenario initially described from occuring and | 241 // prevent the scenario initially described from occuring and |
| 242 // http://crbug.com/176091 can be closed. | 242 // http://crbug.com/176091 can be closed. |
| 243 T* old = data_.ptr; | 243 T* old = data_.ptr; |
| 244 data_.ptr = nullptr; | 244 data_.ptr = NULL; |
| 245 if (old != nullptr) | 245 if (old != NULL) |
| 246 static_cast<D&>(data_)(old); | 246 static_cast<D&>(data_)(old); |
| 247 data_.ptr = p; | 247 data_.ptr = p; |
| 248 } | 248 } |
| 249 | 249 |
| 250 T* get() const { return data_.ptr; } | 250 T* get() const { return data_.ptr; } |
| 251 | 251 |
| 252 D& get_deleter() { return data_; } | 252 D& get_deleter() { return data_; } |
| 253 const D& get_deleter() const { return data_; } | 253 const D& get_deleter() const { return data_; } |
| 254 | 254 |
| 255 void swap(scoped_ptr_impl& p2) { | 255 void swap(scoped_ptr_impl& p2) { |
| 256 // Standard swap idiom: 'using std::swap' ensures that std::swap is | 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 | 257 // present in the overload set, but we call swap unqualified so that |
| 258 // any more-specific overloads can be used, if available. | 258 // any more-specific overloads can be used, if available. |
| 259 using std::swap; | 259 using std::swap; |
| 260 swap(static_cast<D&>(data_), static_cast<D&>(p2.data_)); | 260 swap(static_cast<D&>(data_), static_cast<D&>(p2.data_)); |
| 261 swap(data_.ptr, p2.data_.ptr); | 261 swap(data_.ptr, p2.data_.ptr); |
| 262 } | 262 } |
| 263 | 263 |
| 264 T* release() { | 264 T* release() { |
| 265 T* old_ptr = data_.ptr; | 265 T* old_ptr = data_.ptr; |
| 266 data_.ptr = nullptr; | 266 data_.ptr = NULL; |
| 267 return old_ptr; | 267 return old_ptr; |
| 268 } | 268 } |
| 269 | 269 |
| 270 private: | 270 private: |
| 271 // Needed to allow type-converting constructor. | 271 // Needed to allow type-converting constructor. |
| 272 template <typename U, typename V> friend class scoped_ptr_impl; | 272 template <typename U, typename V> friend class scoped_ptr_impl; |
| 273 | 273 |
| 274 // Use the empty base class optimization to allow us to have a D | 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 | 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 | 276 // empty class. See e.g. http://www.cantrip.org/emptyopt.html for a good |
| 277 // discussion of this technique. | 277 // discussion of this technique. |
| 278 struct Data : public D { | 278 struct Data : public D { |
| 279 explicit Data(T* ptr_in) : ptr(ptr_in) {} | 279 explicit Data(T* ptr_in) : ptr(ptr_in) {} |
| 280 Data(T* ptr_in, const D& other) : D(other), ptr(ptr_in) {} | 280 Data(T* ptr_in, const D& other) : D(other), ptr(ptr_in) {} |
| 281 T* ptr; | 281 T* ptr; |
| 282 }; | 282 }; |
| 283 | 283 |
| 284 Data data_; | 284 Data data_; |
| 285 | 285 |
| 286 DISALLOW_COPY_AND_ASSIGN(scoped_ptr_impl); | 286 DISALLOW_COPY_AND_ASSIGN(scoped_ptr_impl); |
| 287 }; | 287 }; |
| 288 | 288 |
| 289 } // namespace internal | 289 } // namespace internal |
| 290 | 290 |
| 291 } // namespace base | 291 } // namespace base |
| 292 | 292 |
| 293 // A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T> | 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). | 294 // automatically deletes the pointer it holds (if any). |
| 295 // That is, scoped_ptr<T> owns the T object that it points to. | 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 nullptr or a pointer to a T | 296 // Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object. |
| 297 // object. Also like T*, scoped_ptr<T> is thread-compatible, and once you | 297 // Also like T*, scoped_ptr<T> is thread-compatible, and once you |
| 298 // dereference it, you get the thread safety guarantees of T. | 298 // dereference it, you get the thread safety guarantees of T. |
| 299 // | 299 // |
| 300 // The size of scoped_ptr is small. On most compilers, when using the | 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 | 301 // DefaultDeleter, sizeof(scoped_ptr<T>) == sizeof(T*). Custom deleters will |
| 302 // increase the size proportional to whatever state they need to have. See | 302 // increase the size proportional to whatever state they need to have. See |
| 303 // comments inside scoped_ptr_impl<> for details. | 303 // comments inside scoped_ptr_impl<> for details. |
| 304 // | 304 // |
| 305 // Current implementation targets having a strict subset of C++11's | 305 // Current implementation targets having a strict subset of C++11's |
| 306 // unique_ptr<> features. Known deficiencies include not supporting move-only | 306 // unique_ptr<> features. Known deficiencies include not supporting move-only |
| 307 // deleteres, function pointers as deleters, and deleters with reference | 307 // deleteres, function pointers as deleters, and deleters with reference |
| 308 // types. | 308 // types. |
| 309 template <class T, class D = base::DefaultDeleter<T> > | 309 template <class T, class D = base::DefaultDeleter<T> > |
| 310 class scoped_ptr { | 310 class scoped_ptr { |
| 311 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue) | 311 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue) |
| 312 | 312 |
| 313 COMPILE_ASSERT(base::internal::IsNotRefCounted<T>::value, | 313 COMPILE_ASSERT(base::internal::IsNotRefCounted<T>::value, |
| 314 T_is_refcounted_type_and_needs_scoped_refptr); | 314 T_is_refcounted_type_and_needs_scoped_refptr); |
| 315 | 315 |
| 316 public: | 316 public: |
| 317 // The element and deleter types. | 317 // The element and deleter types. |
| 318 typedef T element_type; | 318 typedef T element_type; |
| 319 typedef D deleter_type; | 319 typedef D deleter_type; |
| 320 | 320 |
| 321 // Constructor. Defaults to initializing with nullptr. | 321 // Constructor. Defaults to initializing with NULL. |
| 322 scoped_ptr() : impl_(nullptr) {} | 322 scoped_ptr() : impl_(NULL) { } |
| 323 | 323 |
| 324 // Constructor. Takes ownership of p. | 324 // Constructor. Takes ownership of p. |
| 325 explicit scoped_ptr(element_type* p) : impl_(p) {} | 325 explicit scoped_ptr(element_type* p) : impl_(p) { } |
| 326 | 326 |
| 327 // Constructor. Allows initialization of a stateful deleter. | 327 // Constructor. Allows initialization of a stateful deleter. |
| 328 scoped_ptr(element_type* p, const D& d) : impl_(p, d) {} | 328 scoped_ptr(element_type* p, const D& d) : impl_(p, d) { } |
| 329 | |
| 330 // Constructor. Allows construction from a nullptr. | |
| 331 scoped_ptr(decltype(nullptr)) : impl_(nullptr) {} | |
| 332 | 329 |
| 333 // Constructor. Allows construction from a scoped_ptr rvalue for a | 330 // Constructor. Allows construction from a scoped_ptr rvalue for a |
| 334 // convertible type and deleter. | 331 // convertible type and deleter. |
| 335 // | 332 // |
| 336 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this constructor distinct | 333 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this constructor distinct |
| 337 // from the normal move constructor. By C++11 20.7.1.2.1.21, this constructor | 334 // from the normal move constructor. By C++11 20.7.1.2.1.21, this constructor |
| 338 // has different post-conditions if D is a reference type. Since this | 335 // has different post-conditions if D is a reference type. Since this |
| 339 // implementation does not support deleters with reference type, | 336 // implementation does not support deleters with reference type, |
| 340 // we do not need a separate move constructor allowing us to avoid one | 337 // we do not need a separate move constructor allowing us to avoid one |
| 341 // use of SFINAE. You only need to care about this if you modify the | 338 // use of SFINAE. You only need to care about this if you modify the |
| 342 // implementation of scoped_ptr. | 339 // implementation of scoped_ptr. |
| 343 template <typename U, typename V> | 340 template <typename U, typename V> |
| 344 scoped_ptr(scoped_ptr<U, V>&& other) | 341 scoped_ptr(scoped_ptr<U, V> other) : impl_(&other.impl_) { |
| 345 : impl_(&other.impl_) { | |
| 346 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); | 342 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); |
| 347 } | 343 } |
| 348 | 344 |
| 349 // Constructor. Move constructor for C++03 move emulation of this type. | 345 // Constructor. Move constructor for C++03 move emulation of this type. |
| 350 scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) {} | 346 scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { } |
| 351 | 347 |
| 352 // operator=. Allows assignment from a scoped_ptr rvalue for a convertible | 348 // operator=. Allows assignment from a scoped_ptr rvalue for a convertible |
| 353 // type and deleter. | 349 // type and deleter. |
| 354 // | 350 // |
| 355 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from | 351 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from |
| 356 // the normal move assignment operator. By C++11 20.7.1.2.3.4, this templated | 352 // the normal move assignment operator. By C++11 20.7.1.2.3.4, this templated |
| 357 // form has different requirements on for move-only Deleters. Since this | 353 // form has different requirements on for move-only Deleters. Since this |
| 358 // implementation does not support move-only Deleters, we do not need a | 354 // implementation does not support move-only Deleters, we do not need a |
| 359 // separate move assignment operator allowing us to avoid one use of SFINAE. | 355 // separate move assignment operator allowing us to avoid one use of SFINAE. |
| 360 // You only need to care about this if you modify the implementation of | 356 // You only need to care about this if you modify the implementation of |
| 361 // scoped_ptr. | 357 // scoped_ptr. |
| 362 template <typename U, typename V> | 358 template <typename U, typename V> |
| 363 scoped_ptr& operator=(scoped_ptr<U, V>&& rhs) { | 359 scoped_ptr& operator=(scoped_ptr<U, V> rhs) { |
| 364 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); | 360 COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); |
| 365 impl_.TakeState(&rhs.impl_); | 361 impl_.TakeState(&rhs.impl_); |
| 366 return *this; | 362 return *this; |
| 367 } | 363 } |
| 368 | 364 |
| 369 // operator=. Allows assignment from a nullptr. Deletes the currently owned | |
| 370 // object, if any. | |
| 371 scoped_ptr& operator=(decltype(nullptr)) { | |
| 372 reset(); | |
| 373 return *this; | |
| 374 } | |
| 375 | |
| 376 // Reset. Deletes the currently owned object, if any. | 365 // Reset. Deletes the currently owned object, if any. |
| 377 // Then takes ownership of a new object, if given. | 366 // Then takes ownership of a new object, if given. |
| 378 void reset(element_type* p = nullptr) { impl_.reset(p); } | 367 void reset(element_type* p = NULL) { impl_.reset(p); } |
| 379 | 368 |
| 380 // Accessors to get the owned object. | 369 // Accessors to get the owned object. |
| 381 // operator* and operator-> will assert() if there is no current object. | 370 // operator* and operator-> will assert() if there is no current object. |
| 382 element_type& operator*() const { | 371 element_type& operator*() const { |
| 383 assert(impl_.get() != nullptr); | 372 assert(impl_.get() != NULL); |
| 384 return *impl_.get(); | 373 return *impl_.get(); |
| 385 } | 374 } |
| 386 element_type* operator->() const { | 375 element_type* operator->() const { |
| 387 assert(impl_.get() != nullptr); | 376 assert(impl_.get() != NULL); |
| 388 return impl_.get(); | 377 return impl_.get(); |
| 389 } | 378 } |
| 390 element_type* get() const { return impl_.get(); } | 379 element_type* get() const { return impl_.get(); } |
| 391 | 380 |
| 392 // Access to the deleter. | 381 // Access to the deleter. |
| 393 deleter_type& get_deleter() { return impl_.get_deleter(); } | 382 deleter_type& get_deleter() { return impl_.get_deleter(); } |
| 394 const deleter_type& get_deleter() const { return impl_.get_deleter(); } | 383 const deleter_type& get_deleter() const { return impl_.get_deleter(); } |
| 395 | 384 |
| 396 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not | 385 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not |
| 397 // implicitly convertible to a real bool (which is dangerous). | 386 // implicitly convertible to a real bool (which is dangerous). |
| 398 // | 387 // |
| 399 // Note that this trick is only safe when the == and != operators | 388 // Note that this trick is only safe when the == and != operators |
| 400 // are declared explicitly, as otherwise "scoped_ptr1 == | 389 // are declared explicitly, as otherwise "scoped_ptr1 == |
| 401 // scoped_ptr2" will compile but do the wrong thing (i.e., convert | 390 // scoped_ptr2" will compile but do the wrong thing (i.e., convert |
| 402 // to Testable and then do the comparison). | 391 // to Testable and then do the comparison). |
| 403 private: | 392 private: |
| 404 typedef base::internal::scoped_ptr_impl<element_type, deleter_type> | 393 typedef base::internal::scoped_ptr_impl<element_type, deleter_type> |
| 405 scoped_ptr::*Testable; | 394 scoped_ptr::*Testable; |
| 406 | 395 |
| 407 public: | 396 public: |
| 408 operator Testable() const { | 397 operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; } |
| 409 return impl_.get() ? &scoped_ptr::impl_ : nullptr; | |
| 410 } | |
| 411 | 398 |
| 412 // Comparison operators. | 399 // Comparison operators. |
| 413 // These return whether two scoped_ptr refer to the same object, not just to | 400 // These return whether two scoped_ptr refer to the same object, not just to |
| 414 // two different but equal objects. | 401 // two different but equal objects. |
| 415 bool operator==(const element_type* p) const { return impl_.get() == p; } | 402 bool operator==(const element_type* p) const { return impl_.get() == p; } |
| 416 bool operator!=(const element_type* p) const { return impl_.get() != p; } | 403 bool operator!=(const element_type* p) const { return impl_.get() != p; } |
| 417 | 404 |
| 418 // Swap two scoped pointers. | 405 // Swap two scoped pointers. |
| 419 void swap(scoped_ptr& p2) { | 406 void swap(scoped_ptr& p2) { |
| 420 impl_.swap(p2.impl_); | 407 impl_.swap(p2.impl_); |
| 421 } | 408 } |
| 422 | 409 |
| 423 // Release a pointer. | 410 // Release a pointer. |
| 424 // The return value is the current pointer held by this object. If this object | 411 // The return value is the current pointer held by this object. |
| 425 // holds a nullptr, the return value is nullptr. After this operation, this | 412 // If this object holds a NULL pointer, the return value is NULL. |
| 426 // object will hold a nullptr, and will not own the object any more. | 413 // After this operation, this object will hold a NULL pointer, |
| 414 // and will not own the object any more. |
| 427 element_type* release() WARN_UNUSED_RESULT { | 415 element_type* release() WARN_UNUSED_RESULT { |
| 428 return impl_.release(); | 416 return impl_.release(); |
| 429 } | 417 } |
| 430 | 418 |
| 431 // C++98 doesn't support functions templates with default parameters which | 419 // C++98 doesn't support functions templates with default parameters which |
| 432 // makes it hard to write a PassAs() that understands converting the deleter | 420 // makes it hard to write a PassAs() that understands converting the deleter |
| 433 // while preserving simple calling semantics. | 421 // while preserving simple calling semantics. |
| 434 // | 422 // |
| 435 // Until there is a use case for PassAs() with custom deleters, just ignore | 423 // Until there is a use case for PassAs() with custom deleters, just ignore |
| 436 // the custom deleter. | 424 // the custom deleter. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 457 | 445 |
| 458 template <class T, class D> | 446 template <class T, class D> |
| 459 class scoped_ptr<T[], D> { | 447 class scoped_ptr<T[], D> { |
| 460 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue) | 448 MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue) |
| 461 | 449 |
| 462 public: | 450 public: |
| 463 // The element and deleter types. | 451 // The element and deleter types. |
| 464 typedef T element_type; | 452 typedef T element_type; |
| 465 typedef D deleter_type; | 453 typedef D deleter_type; |
| 466 | 454 |
| 467 // Constructor. Defaults to initializing with nullptr. | 455 // Constructor. Defaults to initializing with NULL. |
| 468 scoped_ptr() : impl_(nullptr) {} | 456 scoped_ptr() : impl_(NULL) { } |
| 469 | 457 |
| 470 // Constructor. Stores the given array. Note that the argument's type | 458 // Constructor. Stores the given array. Note that the argument's type |
| 471 // must exactly match T*. In particular: | 459 // must exactly match T*. In particular: |
| 472 // - it cannot be a pointer to a type derived from T, because it is | 460 // - it cannot be a pointer to a type derived from T, because it is |
| 473 // inherently unsafe in the general case to access an array through a | 461 // inherently unsafe in the general case to access an array through a |
| 474 // pointer whose dynamic type does not match its static type (eg., if | 462 // pointer whose dynamic type does not match its static type (eg., if |
| 475 // T and the derived types had different sizes access would be | 463 // T and the derived types had different sizes access would be |
| 476 // incorrectly calculated). Deletion is also always undefined | 464 // incorrectly calculated). Deletion is also always undefined |
| 477 // (C++98 [expr.delete]p3). If you're doing this, fix your code. | 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. |
| 478 // - it cannot be const-qualified differently from T per unique_ptr spec | 469 // - it cannot be const-qualified differently from T per unique_ptr spec |
| 479 // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting | 470 // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting |
| 480 // to work around this may use implicit_cast<const T*>(). | 471 // to work around this may use implicit_cast<const T*>(). |
| 481 // However, because of the first bullet in this comment, users MUST | 472 // However, because of the first bullet in this comment, users MUST |
| 482 // NOT use implicit_cast<Base*>() to upcast the static type of the array. | 473 // NOT use implicit_cast<Base*>() to upcast the static type of the array. |
| 483 explicit scoped_ptr(element_type* array) : impl_(array) {} | 474 explicit scoped_ptr(element_type* array) : impl_(array) { } |
| 484 | |
| 485 // Constructor. Allows construction from a nullptr. | |
| 486 scoped_ptr(decltype(nullptr)) : impl_(nullptr) {} | |
| 487 | |
| 488 // Constructor. Allows construction from a scoped_ptr rvalue. | |
| 489 scoped_ptr(scoped_ptr&& other) : impl_(&other.impl_) {} | |
| 490 | 475 |
| 491 // Constructor. Move constructor for C++03 move emulation of this type. | 476 // Constructor. Move constructor for C++03 move emulation of this type. |
| 492 scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) {} | 477 scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { } |
| 493 | |
| 494 // operator=. Allows assignment from a scoped_ptr rvalue. | |
| 495 scoped_ptr& operator=(scoped_ptr&& rhs) { | |
| 496 impl_.TakeState(&rhs.impl_); | |
| 497 return *this; | |
| 498 } | |
| 499 | 478 |
| 500 // operator=. Move operator= for C++03 move emulation of this type. | 479 // operator=. Move operator= for C++03 move emulation of this type. |
| 501 scoped_ptr& operator=(RValue rhs) { | 480 scoped_ptr& operator=(RValue rhs) { |
| 502 impl_.TakeState(&rhs.object->impl_); | 481 impl_.TakeState(&rhs.object->impl_); |
| 503 return *this; | 482 return *this; |
| 504 } | 483 } |
| 505 | 484 |
| 506 // operator=. Allows assignment from a nullptr. Deletes the currently owned | |
| 507 // array, if any. | |
| 508 scoped_ptr& operator=(decltype(nullptr)) { | |
| 509 reset(); | |
| 510 return *this; | |
| 511 } | |
| 512 | |
| 513 // Reset. Deletes the currently owned array, if any. | 485 // Reset. Deletes the currently owned array, if any. |
| 514 // Then takes ownership of a new object, if given. | 486 // Then takes ownership of a new object, if given. |
| 515 void reset(element_type* array = nullptr) { impl_.reset(array); } | 487 void reset(element_type* array = NULL) { impl_.reset(array); } |
| 516 | 488 |
| 517 // Accessors to get the owned array. | 489 // Accessors to get the owned array. |
| 518 element_type& operator[](size_t i) const { | 490 element_type& operator[](size_t i) const { |
| 519 assert(impl_.get() != nullptr); | 491 assert(impl_.get() != NULL); |
| 520 return impl_.get()[i]; | 492 return impl_.get()[i]; |
| 521 } | 493 } |
| 522 element_type* get() const { return impl_.get(); } | 494 element_type* get() const { return impl_.get(); } |
| 523 | 495 |
| 524 // Access to the deleter. | 496 // Access to the deleter. |
| 525 deleter_type& get_deleter() { return impl_.get_deleter(); } | 497 deleter_type& get_deleter() { return impl_.get_deleter(); } |
| 526 const deleter_type& get_deleter() const { return impl_.get_deleter(); } | 498 const deleter_type& get_deleter() const { return impl_.get_deleter(); } |
| 527 | 499 |
| 528 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not | 500 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not |
| 529 // implicitly convertible to a real bool (which is dangerous). | 501 // implicitly convertible to a real bool (which is dangerous). |
| 530 private: | 502 private: |
| 531 typedef base::internal::scoped_ptr_impl<element_type, deleter_type> | 503 typedef base::internal::scoped_ptr_impl<element_type, deleter_type> |
| 532 scoped_ptr::*Testable; | 504 scoped_ptr::*Testable; |
| 533 | 505 |
| 534 public: | 506 public: |
| 535 operator Testable() const { | 507 operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; } |
| 536 return impl_.get() ? &scoped_ptr::impl_ : nullptr; | |
| 537 } | |
| 538 | 508 |
| 539 // Comparison operators. | 509 // Comparison operators. |
| 540 // These return whether two scoped_ptr refer to the same object, not just to | 510 // These return whether two scoped_ptr refer to the same object, not just to |
| 541 // two different but equal objects. | 511 // two different but equal objects. |
| 542 bool operator==(element_type* array) const { return impl_.get() == array; } | 512 bool operator==(element_type* array) const { return impl_.get() == array; } |
| 543 bool operator!=(element_type* array) const { return impl_.get() != array; } | 513 bool operator!=(element_type* array) const { return impl_.get() != array; } |
| 544 | 514 |
| 545 // Swap two scoped pointers. | 515 // Swap two scoped pointers. |
| 546 void swap(scoped_ptr& p2) { | 516 void swap(scoped_ptr& p2) { |
| 547 impl_.swap(p2.impl_); | 517 impl_.swap(p2.impl_); |
| 548 } | 518 } |
| 549 | 519 |
| 550 // Release a pointer. | 520 // Release a pointer. |
| 551 // The return value is the current pointer held by this object. If this object | 521 // The return value is the current pointer held by this object. |
| 552 // holds a nullptr, the return value is nullptr. After this operation, this | 522 // If this object holds a NULL pointer, the return value is NULL. |
| 553 // object will hold a nullptr, and will not own the object any more. | 523 // After this operation, this object will hold a NULL pointer, |
| 524 // and will not own the object any more. |
| 554 element_type* release() WARN_UNUSED_RESULT { | 525 element_type* release() WARN_UNUSED_RESULT { |
| 555 return impl_.release(); | 526 return impl_.release(); |
| 556 } | 527 } |
| 557 | 528 |
| 558 private: | 529 private: |
| 559 // Force element_type to be a complete type. | 530 // Force element_type to be a complete type. |
| 560 enum { type_must_be_complete = sizeof(element_type) }; | 531 enum { type_must_be_complete = sizeof(element_type) }; |
| 561 | 532 |
| 562 // Actually hold the data. | 533 // Actually hold the data. |
| 563 base::internal::scoped_ptr_impl<element_type, deleter_type> impl_; | 534 base::internal::scoped_ptr_impl<element_type, deleter_type> impl_; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 | 572 |
| 602 // A function to convert T* into scoped_ptr<T> | 573 // A function to convert T* into scoped_ptr<T> |
| 603 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation | 574 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation |
| 604 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) | 575 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) |
| 605 template <typename T> | 576 template <typename T> |
| 606 scoped_ptr<T> make_scoped_ptr(T* ptr) { | 577 scoped_ptr<T> make_scoped_ptr(T* ptr) { |
| 607 return scoped_ptr<T>(ptr); | 578 return scoped_ptr<T>(ptr); |
| 608 } | 579 } |
| 609 | 580 |
| 610 #endif // BASE_MEMORY_SCOPED_PTR_H_ | 581 #endif // BASE_MEMORY_SCOPED_PTR_H_ |
| OLD | NEW |