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 a 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 8 // 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 an rvalue of a scoper, which 41 // can be created by using std::move(), or the result of another function that 42 // generates a temporary; passing by copy will NOT work. Here is an example 43 // using scoped_ptr: 44 // 45 // void TakesOwnership(scoped_ptr<Foo> arg) { 46 // // Do something with arg. 47 // } 48 // scoped_ptr<Foo> CreateFoo() { 49 // // No need for calling std::move() for returning a move-only value, or 50 // // when you already have an rvalue as we do here. 51 // return scoped_ptr<Foo>(new Foo("new")); 52 // } 53 // scoped_ptr<Foo> PassThru(scoped_ptr<Foo> arg) { 54 // return arg; 55 // } 56 // 57 // { 58 // scoped_ptr<Foo> ptr(new Foo("yay")); // ptr manages Foo("yay"). 59 // TakesOwnership(std::move(ptr)); // ptr no longer owns Foo("yay"). 60 // scoped_ptr<Foo> ptr2 = CreateFoo(); // ptr2 owns the return Foo. 61 // scoped_ptr<Foo> ptr3 = // ptr3 now owns what was in ptr2. 62 // PassThru(std::move(ptr2)); // ptr2 is correspondingly nullptr. 63 // } 64 // 65 // Notice that if you do not call std::move() when returning from PassThru(), or 66 // when invoking TakesOwnership(), the code will not compile because scopers 67 // are not copyable; they only implement move semantics which require calling 68 // the std::move() function to signify a destructive transfer of state. 69 // CreateFoo() is different though because we are constructing a temporary on 70 // the return line and thus can avoid needing to call std::move(). 71 // 72 // The conversion move-constructor properly handles upcast in initialization, 73 // i.e. you can use a scoped_ptr<Child> to initialize a scoped_ptr<Parent>: 74 // 75 // scoped_ptr<Foo> foo(new Foo()); 76 // scoped_ptr<FooParent> parent(std::move(foo)); 77 78 #ifndef BASE_MEMORY_SCOPED_PTR_H_ 79 #define BASE_MEMORY_SCOPED_PTR_H_ 80 81 // This is an implementation designed to match the anticipated future TR2 82 // implementation of the scoped_ptr class. 83 84 #include <assert.h> 85 #include <stddef.h> 86 #include <stdlib.h> 87 88 #include <iosfwd> 89 #include <memory> 90 #include <type_traits> 91 #include <utility> 92 93 #include "base/compiler_specific.h" 94 #include "base/macros.h" 95 #include "base/move.h" 96 #include "base/template_util.h" 97 98 namespace base { 99 100 namespace subtle { 101 class RefCountedBase; 102 class RefCountedThreadSafeBase; 103 } // namespace subtle 104 105 // Function object which invokes 'free' on its parameter, which must be 106 // a pointer. Can be used to store malloc-allocated pointers in scoped_ptr: 107 // 108 // scoped_ptr<int, base::FreeDeleter> foo_ptr( 109 // static_cast<int*>(malloc(sizeof(int)))); 110 struct FreeDeleter { 111 inline void operator()(void* ptr) const { 112 free(ptr); 113 } 114 }; 115 116 namespace internal { 117 118 template <typename T> struct IsNotRefCounted { 119 enum { 120 value = !base::is_convertible<T*, base::subtle::RefCountedBase*>::value && 121 !base::is_convertible<T*, base::subtle::RefCountedThreadSafeBase*>:: 122 value 123 }; 124 }; 125 126 // Minimal implementation of the core logic of scoped_ptr, suitable for 127 // reuse in both scoped_ptr and its specializations. 128 template <class T, class D> 129 class scoped_ptr_impl { 130 public: 131 explicit scoped_ptr_impl(T* p) : data_(p) {} 132 133 // Initializer for deleters that have data parameters. 134 scoped_ptr_impl(T* p, const D& d) : data_(p, d) {} 135 136 // Templated constructor that destructively takes the value from another 137 // scoped_ptr_impl. 138 template <typename U, typename V> 139 scoped_ptr_impl(scoped_ptr_impl<U, V>* other) 140 : data_(other->release(), other->get_deleter()) { 141 // We do not support move-only deleters. We could modify our move 142 // emulation to have base::subtle::move() and base::subtle::forward() 143 // functions that are imperfect emulations of their C++11 equivalents, 144 // but until there's a requirement, just assume deleters are copyable. 145 } 146 147 template <typename U, typename V> 148 void TakeState(scoped_ptr_impl<U, V>* other) { 149 // See comment in templated constructor above regarding lack of support 150 // for move-only deleters. 151 reset(other->release()); 152 get_deleter() = other->get_deleter(); 153 } 154 155 ~scoped_ptr_impl() { 156 // Match libc++, which calls reset() in its destructor. 157 // Use nullptr as the new value for three reasons: 158 // 1. libc++ does it. 159 // 2. Avoids infinitely recursing into destructors if two classes are owned 160 // in a reference cycle (see ScopedPtrTest.ReferenceCycle). 161 // 3. If |this| is accessed in the future, in a use-after-free bug, attempts 162 // to dereference |this|'s pointer should cause either a failure or a 163 // segfault closer to the problem. If |this| wasn't reset to nullptr, 164 // the access would cause the deleted memory to be read or written 165 // leading to other more subtle issues. 166 reset(nullptr); 167 } 168 169 void reset(T* p) { 170 // Match C++11's definition of unique_ptr::reset(), which requires changing 171 // the pointer before invoking the deleter on the old pointer. This prevents 172 // |this| from being accessed after the deleter is run, which may destroy 173 // |this|. 174 T* old = data_.ptr; 175 data_.ptr = p; 176 if (old != nullptr) 177 static_cast<D&>(data_)(old); 178 } 179 180 T* get() const { return data_.ptr; } 181 182 D& get_deleter() { return data_; } 183 const D& get_deleter() const { return data_; } 184 185 void swap(scoped_ptr_impl& p2) { 186 // Standard swap idiom: 'using std::swap' ensures that std::swap is 187 // present in the overload set, but we call swap unqualified so that 188 // any more-specific overloads can be used, if available. 189 using std::swap; 190 swap(static_cast<D&>(data_), static_cast<D&>(p2.data_)); 191 swap(data_.ptr, p2.data_.ptr); 192 } 193 194 T* release() { 195 T* old_ptr = data_.ptr; 196 data_.ptr = nullptr; 197 return old_ptr; 198 } 199 200 private: 201 // Needed to allow type-converting constructor. 202 template <typename U, typename V> friend class scoped_ptr_impl; 203 204 // Use the empty base class optimization to allow us to have a D 205 // member, while avoiding any space overhead for it when D is an 206 // empty class. See e.g. http://www.cantrip.org/emptyopt.html for a good 207 // discussion of this technique. 208 struct Data : public D { 209 explicit Data(T* ptr_in) : ptr(ptr_in) {} 210 Data(T* ptr_in, const D& other) : D(other), ptr(ptr_in) {} 211 T* ptr; 212 }; 213 214 Data data_; 215 216 DISALLOW_COPY_AND_ASSIGN(scoped_ptr_impl); 217 }; 218 219 } // namespace internal 220 221 } // namespace base 222 223 // A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T> 224 // automatically deletes the pointer it holds (if any). 225 // That is, scoped_ptr<T> owns the T object that it points to. 226 // Like a T*, a scoped_ptr<T> may hold either nullptr or a pointer to a T 227 // object. Also like T*, scoped_ptr<T> is thread-compatible, and once you 228 // dereference it, you get the thread safety guarantees of T. 229 // 230 // The size of scoped_ptr is small. On most compilers, when using the 231 // std::default_delete, sizeof(scoped_ptr<T>) == sizeof(T*). Custom deleters 232 // will increase the size proportional to whatever state they need to have. See 233 // comments inside scoped_ptr_impl<> for details. 234 // 235 // Current implementation targets having a strict subset of C++11's 236 // unique_ptr<> features. Known deficiencies include not supporting move-only 237 // deleteres, function pointers as deleters, and deleters with reference 238 // types. 239 template <class T, class D = std::default_delete<T>> 240 class scoped_ptr { 241 DISALLOW_COPY_AND_ASSIGN_WITH_MOVE_FOR_BIND(scoped_ptr) 242 243 static_assert(!std::is_array<T>::value, 244 "scoped_ptr doesn't support array with size"); 245 static_assert(base::internal::IsNotRefCounted<T>::value, 246 "T is a refcounted type and needs a scoped_refptr"); 247 248 public: 249 // The element and deleter types. 250 using element_type = T; 251 using deleter_type = D; 252 253 // Constructor. Defaults to initializing with nullptr. 254 scoped_ptr() : impl_(nullptr) {} 255 256 // Constructor. Takes ownership of p. 257 explicit scoped_ptr(element_type* p) : impl_(p) {} 258 259 // Constructor. Allows initialization of a stateful deleter. 260 scoped_ptr(element_type* p, const D& d) : impl_(p, d) {} 261 262 // Constructor. Allows construction from a nullptr. 263 scoped_ptr(std::nullptr_t) : impl_(nullptr) {} 264 265 // Move constructor. 266 // 267 // IMPLEMENTATION NOTE: Clang requires a move constructor to be defined (and 268 // not just the conversion constructor) in order to warn on pessimizing moves. 269 // The requirements for the move constructor are specified in C++11 270 // 20.7.1.2.1.15-17, which has some subtleties around reference deleters. As 271 // we don't support reference (or move-only) deleters, the post conditions are 272 // trivially true: we always copy construct the deleter from other's deleter. 273 scoped_ptr(scoped_ptr&& other) : impl_(&other.impl_) {} 274 275 // Conversion constructor. Allows construction from a scoped_ptr rvalue for a 276 // convertible type and deleter. 277 // 278 // IMPLEMENTATION NOTE: C++ 20.7.1.2.1.19 requires this constructor to only 279 // participate in overload resolution if all the following are true: 280 // - U is implicitly convertible to T: this is important for 2 reasons: 281 // 1. So type traits don't incorrectly return true, e.g. 282 // std::is_convertible<scoped_ptr<Base>, scoped_ptr<Derived>>::value 283 // should be false. 284 // 2. To make sure code like this compiles: 285 // void F(scoped_ptr<int>); 286 // void F(scoped_ptr<Base>); 287 // // Ambiguous since both conversion constructors match. 288 // F(scoped_ptr<Derived>()); 289 // - U is not an array type: to prevent conversions from scoped_ptr<T[]> to 290 // scoped_ptr<T>. 291 // - D is a reference type and E is the same type, or D is not a reference 292 // type and E is implicitly convertible to D: again, we don't support 293 // reference deleters, so we only worry about the latter requirement. 294 template <typename U, 295 typename E, 296 typename std::enable_if<!std::is_array<U>::value && 297 std::is_convertible<U*, T*>::value && 298 std::is_convertible<E, D>::value>::type* = 299 nullptr> 300 scoped_ptr(scoped_ptr<U, E>&& other) 301 : impl_(&other.impl_) {} 302 303 // operator=. 304 // 305 // IMPLEMENTATION NOTE: Unlike the move constructor, Clang does not appear to 306 // require a move assignment operator to trigger the pessimizing move warning: 307 // in this case, the warning triggers when moving a temporary. For consistency 308 // with the move constructor, we define it anyway. C++11 20.7.1.2.3.1-3 309 // defines several requirements around this: like the move constructor, the 310 // requirements are simplified by the fact that we don't support move-only or 311 // reference deleters. 312 scoped_ptr& operator=(scoped_ptr&& rhs) { 313 impl_.TakeState(&rhs.impl_); 314 return *this; 315 } 316 317 // operator=. Allows assignment from a scoped_ptr rvalue for a convertible 318 // type and deleter. 319 // 320 // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from 321 // the normal move assignment operator. C++11 20.7.1.2.3.4-7 contains the 322 // requirement for this operator, but like the conversion constructor, the 323 // requirements are greatly simplified by not supporting move-only or 324 // reference deleters. 325 template <typename U, 326 typename E, 327 typename std::enable_if<!std::is_array<U>::value && 328 std::is_convertible<U*, T*>::value && 329 // Note that this really should be 330 // std::is_assignable, but <type_traits> 331 // appears to be missing this on some 332 // platforms. This is close enough (though 333 // it's not the same). 334 std::is_convertible<D, E>::value>::type* = 335 nullptr> 336 scoped_ptr& operator=(scoped_ptr<U, E>&& rhs) { 337 impl_.TakeState(&rhs.impl_); 338 return *this; 339 } 340 341 // operator=. Allows assignment from a nullptr. Deletes the currently owned 342 // object, if any. 343 scoped_ptr& operator=(std::nullptr_t) { 344 reset(); 345 return *this; 346 } 347 348 // Reset. Deletes the currently owned object, if any. 349 // Then takes ownership of a new object, if given. 350 void reset(element_type* p = nullptr) { impl_.reset(p); } 351 352 // Accessors to get the owned object. 353 // operator* and operator-> will assert() if there is no current object. 354 element_type& operator*() const { 355 assert(impl_.get() != nullptr); 356 return *impl_.get(); 357 } 358 element_type* operator->() const { 359 assert(impl_.get() != nullptr); 360 return impl_.get(); 361 } 362 element_type* get() const { return impl_.get(); } 363 364 // Access to the deleter. 365 deleter_type& get_deleter() { return impl_.get_deleter(); } 366 const deleter_type& get_deleter() const { return impl_.get_deleter(); } 367 368 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not 369 // implicitly convertible to a real bool (which is dangerous). 370 // 371 // Note that this trick is only safe when the == and != operators 372 // are declared explicitly, as otherwise "scoped_ptr1 == 373 // scoped_ptr2" will compile but do the wrong thing (i.e., convert 374 // to Testable and then do the comparison). 375 private: 376 typedef base::internal::scoped_ptr_impl<element_type, deleter_type> 377 scoped_ptr::*Testable; 378 379 public: 380 operator Testable() const { 381 return impl_.get() ? &scoped_ptr::impl_ : nullptr; 382 } 383 384 // Swap two scoped pointers. 385 void swap(scoped_ptr& p2) { 386 impl_.swap(p2.impl_); 387 } 388 389 // Release a pointer. 390 // The return value is the current pointer held by this object. If this object 391 // holds a nullptr, the return value is nullptr. After this operation, this 392 // object will hold a nullptr, and will not own the object any more. 393 element_type* release() WARN_UNUSED_RESULT { 394 return impl_.release(); 395 } 396 397 private: 398 // Needed to reach into |impl_| in the constructor. 399 template <typename U, typename V> friend class scoped_ptr; 400 base::internal::scoped_ptr_impl<element_type, deleter_type> impl_; 401 402 // Forbidden for API compatibility with std::unique_ptr. 403 explicit scoped_ptr(int disallow_construction_from_null); 404 }; 405 406 template <class T, class D> 407 class scoped_ptr<T[], D> { 408 DISALLOW_COPY_AND_ASSIGN_WITH_MOVE_FOR_BIND(scoped_ptr) 409 410 public: 411 // The element and deleter types. 412 using element_type = T; 413 using deleter_type = D; 414 415 // Constructor. Defaults to initializing with nullptr. 416 scoped_ptr() : impl_(nullptr) {} 417 418 // Constructor. Stores the given array. Note that the argument's type 419 // must exactly match T*. In particular: 420 // - it cannot be a pointer to a type derived from T, because it is 421 // inherently unsafe in the general case to access an array through a 422 // pointer whose dynamic type does not match its static type (eg., if 423 // T and the derived types had different sizes access would be 424 // incorrectly calculated). Deletion is also always undefined 425 // (C++98 [expr.delete]p3). If you're doing this, fix your code. 426 // - it cannot be const-qualified differently from T per unique_ptr spec 427 // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting 428 // to work around this may use const_cast<const T*>(). 429 explicit scoped_ptr(element_type* array) : impl_(array) {} 430 431 // Constructor. Allows construction from a nullptr. 432 scoped_ptr(std::nullptr_t) : impl_(nullptr) {} 433 434 // Constructor. Allows construction from a scoped_ptr rvalue. 435 scoped_ptr(scoped_ptr&& other) : impl_(&other.impl_) {} 436 437 // operator=. Allows assignment from a scoped_ptr rvalue. 438 scoped_ptr& operator=(scoped_ptr&& rhs) { 439 impl_.TakeState(&rhs.impl_); 440 return *this; 441 } 442 443 // operator=. Allows assignment from a nullptr. Deletes the currently owned 444 // array, if any. 445 scoped_ptr& operator=(std::nullptr_t) { 446 reset(); 447 return *this; 448 } 449 450 // Reset. Deletes the currently owned array, if any. 451 // Then takes ownership of a new object, if given. 452 void reset(element_type* array = nullptr) { impl_.reset(array); } 453 454 // Accessors to get the owned array. 455 element_type& operator[](size_t i) const { 456 assert(impl_.get() != nullptr); 457 return impl_.get()[i]; 458 } 459 element_type* get() const { return impl_.get(); } 460 461 // Access to the deleter. 462 deleter_type& get_deleter() { return impl_.get_deleter(); } 463 const deleter_type& get_deleter() const { return impl_.get_deleter(); } 464 465 // Allow scoped_ptr<element_type> to be used in boolean expressions, but not 466 // implicitly convertible to a real bool (which is dangerous). 467 private: 468 typedef base::internal::scoped_ptr_impl<element_type, deleter_type> 469 scoped_ptr::*Testable; 470 471 public: 472 operator Testable() const { 473 return impl_.get() ? &scoped_ptr::impl_ : nullptr; 474 } 475 476 // Swap two scoped pointers. 477 void swap(scoped_ptr& p2) { 478 impl_.swap(p2.impl_); 479 } 480 481 // Release a pointer. 482 // The return value is the current pointer held by this object. If this object 483 // holds a nullptr, the return value is nullptr. After this operation, this 484 // object will hold a nullptr, and will not own the object any more. 485 element_type* release() WARN_UNUSED_RESULT { 486 return impl_.release(); 487 } 488 489 private: 490 // Force element_type to be a complete type. 491 enum { type_must_be_complete = sizeof(element_type) }; 492 493 // Actually hold the data. 494 base::internal::scoped_ptr_impl<element_type, deleter_type> impl_; 495 496 // Disable initialization from any type other than element_type*, by 497 // providing a constructor that matches such an initialization, but is 498 // private and has no definition. This is disabled because it is not safe to 499 // call delete[] on an array whose static type does not match its dynamic 500 // type. 501 template <typename U> explicit scoped_ptr(U* array); 502 explicit scoped_ptr(int disallow_construction_from_null); 503 504 // Disable reset() from any type other than element_type*, for the same 505 // reasons as the constructor above. 506 template <typename U> void reset(U* array); 507 void reset(int disallow_reset_from_null); 508 }; 509 510 // Free functions 511 template <class T, class D> 512 void swap(scoped_ptr<T, D>& p1, scoped_ptr<T, D>& p2) { 513 p1.swap(p2); 514 } 515 516 template <class T1, class D1, class T2, class D2> 517 bool operator==(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) { 518 return p1.get() == p2.get(); 519 } 520 template <class T, class D> 521 bool operator==(const scoped_ptr<T, D>& p, std::nullptr_t) { 522 return p.get() == nullptr; 523 } 524 template <class T, class D> 525 bool operator==(std::nullptr_t, const scoped_ptr<T, D>& p) { 526 return p.get() == nullptr; 527 } 528 529 template <class T1, class D1, class T2, class D2> 530 bool operator!=(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) { 531 return !(p1 == p2); 532 } 533 template <class T, class D> 534 bool operator!=(const scoped_ptr<T, D>& p, std::nullptr_t) { 535 return !(p == nullptr); 536 } 537 template <class T, class D> 538 bool operator!=(std::nullptr_t, const scoped_ptr<T, D>& p) { 539 return !(p == nullptr); 540 } 541 542 template <class T1, class D1, class T2, class D2> 543 bool operator<(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) { 544 return p1.get() < p2.get(); 545 } 546 template <class T, class D> 547 bool operator<(const scoped_ptr<T, D>& p, std::nullptr_t) { 548 auto* ptr = p.get(); 549 return ptr < static_cast<decltype(ptr)>(nullptr); 550 } 551 template <class T, class D> 552 bool operator<(std::nullptr_t, const scoped_ptr<T, D>& p) { 553 auto* ptr = p.get(); 554 return static_cast<decltype(ptr)>(nullptr) < ptr; 555 } 556 557 template <class T1, class D1, class T2, class D2> 558 bool operator>(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) { 559 return p2 < p1; 560 } 561 template <class T, class D> 562 bool operator>(const scoped_ptr<T, D>& p, std::nullptr_t) { 563 return nullptr < p; 564 } 565 template <class T, class D> 566 bool operator>(std::nullptr_t, const scoped_ptr<T, D>& p) { 567 return p < nullptr; 568 } 569 570 template <class T1, class D1, class T2, class D2> 571 bool operator<=(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) { 572 return !(p1 > p2); 573 } 574 template <class T, class D> 575 bool operator<=(const scoped_ptr<T, D>& p, std::nullptr_t) { 576 return !(p > nullptr); 577 } 578 template <class T, class D> 579 bool operator<=(std::nullptr_t, const scoped_ptr<T, D>& p) { 580 return !(nullptr > p); 581 } 582 583 template <class T1, class D1, class T2, class D2> 584 bool operator>=(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) { 585 return !(p1 < p2); 586 } 587 template <class T, class D> 588 bool operator>=(const scoped_ptr<T, D>& p, std::nullptr_t) { 589 return !(p < nullptr); 590 } 591 template <class T, class D> 592 bool operator>=(std::nullptr_t, const scoped_ptr<T, D>& p) { 593 return !(nullptr < p); 594 } 595 596 // A function to convert T* into scoped_ptr<T> 597 // Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation 598 // for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) 599 template <typename T> 600 scoped_ptr<T> make_scoped_ptr(T* ptr) { 601 return scoped_ptr<T>(ptr); 602 } 603 604 template <typename T> 605 std::ostream& operator<<(std::ostream& out, const scoped_ptr<T>& p) { 606 return out << p.get(); 607 } 608 609 #endif // BASE_MEMORY_SCOPED_PTR_H_ 610