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