diff options
-rw-r--r-- | base/memory/scoped_ptr.h | 107 | ||||
-rw-r--r-- | base/memory/scoped_ptr_unittest.cc | 54 |
2 files changed, 39 insertions, 122 deletions
diff --git a/base/memory/scoped_ptr.h b/base/memory/scoped_ptr.h index 81b4a62..bf2e0b6 100644 --- a/base/memory/scoped_ptr.h +++ b/base/memory/scoped_ptr.h @@ -58,7 +58,7 @@ // TakesOwnership(ptr.Pass()); // ptr no longer owns Foo("yay"). // scoped_ptr<Foo> ptr2 = CreateFoo(); // ptr2 owns the return Foo. // scoped_ptr<Foo> ptr3 = // ptr3 now owns what was in ptr2. -// PassThru(ptr2.Pass()); // ptr2 is correspondingly nullptr. +// PassThru(ptr2.Pass()); // ptr2 is correspondingly NULL. // } // // Notice that if you do not call Pass() when returning from PassThru(), or @@ -189,7 +189,7 @@ template <typename T> struct IsNotRefCounted { template <class T, class D> class scoped_ptr_impl { public: - explicit scoped_ptr_impl(T* p) : data_(p) {} + explicit scoped_ptr_impl(T* p) : data_(p) { } // Initializer for deleters that have data parameters. scoped_ptr_impl(T* p, const D& d) : data_(p, d) {} @@ -214,7 +214,7 @@ class scoped_ptr_impl { } ~scoped_ptr_impl() { - if (data_.ptr != nullptr) { + if (data_.ptr != NULL) { // Not using get_deleter() saves one function call in non-optimized // builds. static_cast<D&>(data_)(data_.ptr); @@ -223,7 +223,7 @@ class scoped_ptr_impl { void reset(T* p) { // This is a self-reset, which is no longer allowed: http://crbug.com/162971 - if (p != nullptr && p == data_.ptr) + if (p != NULL && p == data_.ptr) abort(); // Note that running data_.ptr = p can lead to undefined behavior if @@ -236,13 +236,13 @@ class scoped_ptr_impl { // then it will incorrectly dispatch calls to |p| rather than the original // value of |data_.ptr|. // - // During the transition period, set the stored pointer to nullptr while + // During the transition period, set the stored pointer to NULL while // deleting the object. Eventually, this safety check will be removed to // prevent the scenario initially described from occuring and // http://crbug.com/176091 can be closed. T* old = data_.ptr; - data_.ptr = nullptr; - if (old != nullptr) + data_.ptr = NULL; + if (old != NULL) static_cast<D&>(data_)(old); data_.ptr = p; } @@ -263,7 +263,7 @@ class scoped_ptr_impl { T* release() { T* old_ptr = data_.ptr; - data_.ptr = nullptr; + data_.ptr = NULL; return old_ptr; } @@ -293,8 +293,8 @@ class scoped_ptr_impl { // A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T> // automatically deletes the pointer it holds (if any). // That is, scoped_ptr<T> owns the T object that it points to. -// Like a T*, a scoped_ptr<T> may hold either nullptr or a pointer to a T -// object. Also like T*, scoped_ptr<T> is thread-compatible, and once you +// Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object. +// Also like T*, scoped_ptr<T> is thread-compatible, and once you // dereference it, you get the thread safety guarantees of T. // // The size of scoped_ptr is small. On most compilers, when using the @@ -318,17 +318,14 @@ class scoped_ptr { typedef T element_type; typedef D deleter_type; - // Constructor. Defaults to initializing with nullptr. - scoped_ptr() : impl_(nullptr) {} + // Constructor. Defaults to initializing with NULL. + scoped_ptr() : impl_(NULL) { } // Constructor. Takes ownership of p. - explicit scoped_ptr(element_type* p) : impl_(p) {} + explicit scoped_ptr(element_type* p) : impl_(p) { } // Constructor. Allows initialization of a stateful deleter. - scoped_ptr(element_type* p, const D& d) : impl_(p, d) {} - - // Constructor. Allows construction from a nullptr. - scoped_ptr(decltype(nullptr)) : impl_(nullptr) {} + scoped_ptr(element_type* p, const D& d) : impl_(p, d) { } // Constructor. Allows construction from a scoped_ptr rvalue for a // convertible type and deleter. @@ -341,13 +338,12 @@ class scoped_ptr { // use of SFINAE. You only need to care about this if you modify the // implementation of scoped_ptr. template <typename U, typename V> - scoped_ptr(scoped_ptr<U, V>&& other) - : impl_(&other.impl_) { + scoped_ptr(scoped_ptr<U, V> other) : impl_(&other.impl_) { COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); } // Constructor. Move constructor for C++03 move emulation of this type. - scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) {} + scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { } // operator=. Allows assignment from a scoped_ptr rvalue for a convertible // type and deleter. @@ -360,31 +356,24 @@ class scoped_ptr { // You only need to care about this if you modify the implementation of // scoped_ptr. template <typename U, typename V> - scoped_ptr& operator=(scoped_ptr<U, V>&& rhs) { + scoped_ptr& operator=(scoped_ptr<U, V> rhs) { COMPILE_ASSERT(!base::is_array<U>::value, U_cannot_be_an_array); impl_.TakeState(&rhs.impl_); return *this; } - // operator=. Allows assignment from a nullptr. Deletes the currently owned - // object, if any. - scoped_ptr& operator=(decltype(nullptr)) { - reset(); - return *this; - } - // Reset. Deletes the currently owned object, if any. // Then takes ownership of a new object, if given. - void reset(element_type* p = nullptr) { impl_.reset(p); } + void reset(element_type* p = NULL) { impl_.reset(p); } // Accessors to get the owned object. // operator* and operator-> will assert() if there is no current object. element_type& operator*() const { - assert(impl_.get() != nullptr); + assert(impl_.get() != NULL); return *impl_.get(); } element_type* operator->() const { - assert(impl_.get() != nullptr); + assert(impl_.get() != NULL); return impl_.get(); } element_type* get() const { return impl_.get(); } @@ -405,9 +394,7 @@ class scoped_ptr { scoped_ptr::*Testable; public: - operator Testable() const { - return impl_.get() ? &scoped_ptr::impl_ : nullptr; - } + operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; } // Comparison operators. // These return whether two scoped_ptr refer to the same object, not just to @@ -421,9 +408,10 @@ class scoped_ptr { } // Release a pointer. - // The return value is the current pointer held by this object. If this object - // holds a nullptr, the return value is nullptr. After this operation, this - // object will hold a nullptr, and will not own the object any more. + // The return value is the current pointer held by this object. + // If this object holds a NULL pointer, the return value is NULL. + // After this operation, this object will hold a NULL pointer, + // and will not own the object any more. element_type* release() WARN_UNUSED_RESULT { return impl_.release(); } @@ -464,8 +452,8 @@ class scoped_ptr<T[], D> { typedef T element_type; typedef D deleter_type; - // Constructor. Defaults to initializing with nullptr. - scoped_ptr() : impl_(nullptr) {} + // Constructor. Defaults to initializing with NULL. + scoped_ptr() : impl_(NULL) { } // Constructor. Stores the given array. Note that the argument's type // must exactly match T*. In particular: @@ -475,27 +463,18 @@ class scoped_ptr<T[], D> { // T and the derived types had different sizes access would be // incorrectly calculated). Deletion is also always undefined // (C++98 [expr.delete]p3). If you're doing this, fix your code. + // - it cannot be NULL, because NULL is an integral expression, not a + // pointer to T. Use the no-argument version instead of explicitly + // passing NULL. // - it cannot be const-qualified differently from T per unique_ptr spec // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting // to work around this may use implicit_cast<const T*>(). // However, because of the first bullet in this comment, users MUST // NOT use implicit_cast<Base*>() to upcast the static type of the array. - explicit scoped_ptr(element_type* array) : impl_(array) {} - - // Constructor. Allows construction from a nullptr. - scoped_ptr(decltype(nullptr)) : impl_(nullptr) {} - - // Constructor. Allows construction from a scoped_ptr rvalue. - scoped_ptr(scoped_ptr&& other) : impl_(&other.impl_) {} + explicit scoped_ptr(element_type* array) : impl_(array) { } // Constructor. Move constructor for C++03 move emulation of this type. - scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) {} - - // operator=. Allows assignment from a scoped_ptr rvalue. - scoped_ptr& operator=(scoped_ptr&& rhs) { - impl_.TakeState(&rhs.impl_); - return *this; - } + scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { } // operator=. Move operator= for C++03 move emulation of this type. scoped_ptr& operator=(RValue rhs) { @@ -503,20 +482,13 @@ class scoped_ptr<T[], D> { return *this; } - // operator=. Allows assignment from a nullptr. Deletes the currently owned - // array, if any. - scoped_ptr& operator=(decltype(nullptr)) { - reset(); - return *this; - } - // Reset. Deletes the currently owned array, if any. // Then takes ownership of a new object, if given. - void reset(element_type* array = nullptr) { impl_.reset(array); } + void reset(element_type* array = NULL) { impl_.reset(array); } // Accessors to get the owned array. element_type& operator[](size_t i) const { - assert(impl_.get() != nullptr); + assert(impl_.get() != NULL); return impl_.get()[i]; } element_type* get() const { return impl_.get(); } @@ -532,9 +504,7 @@ class scoped_ptr<T[], D> { scoped_ptr::*Testable; public: - operator Testable() const { - return impl_.get() ? &scoped_ptr::impl_ : nullptr; - } + operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; } // Comparison operators. // These return whether two scoped_ptr refer to the same object, not just to @@ -548,9 +518,10 @@ class scoped_ptr<T[], D> { } // Release a pointer. - // The return value is the current pointer held by this object. If this object - // holds a nullptr, the return value is nullptr. After this operation, this - // object will hold a nullptr, and will not own the object any more. + // The return value is the current pointer held by this object. + // If this object holds a NULL pointer, the return value is NULL. + // After this operation, this object will hold a NULL pointer, + // and will not own the object any more. element_type* release() WARN_UNUSED_RESULT { return impl_.release(); } diff --git a/base/memory/scoped_ptr_unittest.cc b/base/memory/scoped_ptr_unittest.cc index 7cec70e..e0c1548 100644 --- a/base/memory/scoped_ptr_unittest.cc +++ b/base/memory/scoped_ptr_unittest.cc @@ -406,8 +406,6 @@ TEST(ScopedPtrTest, PassBehavior) { // Should auto-destruct logger by end of scope. scoper.Pass(); - // This differs from unique_ptr, as Pass() has side effects but std::move() - // does not. EXPECT_FALSE(scoper.get()); } EXPECT_EQ(0, constructed); @@ -604,55 +602,3 @@ TEST(ScopedPtrTest, OverloadedNewAndDelete) { EXPECT_EQ(1, OverloadedNewAndDelete::delete_count()); EXPECT_EQ(1, OverloadedNewAndDelete::new_count()); } - -scoped_ptr<int> NullIntReturn() { - return nullptr; -} - -TEST(ScopedPtrTest, Nullptr) { - scoped_ptr<int> scoper1(nullptr); - scoped_ptr<int> scoper2(new int); - scoper2 = nullptr; - scoped_ptr<int> scoper3(NullIntReturn()); - scoped_ptr<int> scoper4 = NullIntReturn(); - EXPECT_EQ(nullptr, scoper1.get()); - EXPECT_EQ(nullptr, scoper2.get()); - EXPECT_EQ(nullptr, scoper3.get()); - EXPECT_EQ(nullptr, scoper4.get()); -} - -scoped_ptr<int[]> NullIntArrayReturn() { - return nullptr; -} - -TEST(ScopedPtrTest, NullptrArray) { - scoped_ptr<int[]> scoper1(nullptr); - scoped_ptr<int[]> scoper2(new int); - scoper2 = nullptr; - scoped_ptr<int[]> scoper3(NullIntArrayReturn()); - scoped_ptr<int[]> scoper4 = NullIntArrayReturn(); - EXPECT_EQ(nullptr, scoper1.get()); - EXPECT_EQ(nullptr, scoper2.get()); - EXPECT_EQ(nullptr, scoper3.get()); - EXPECT_EQ(nullptr, scoper4.get()); -} - -class Super {}; -class Sub : public Super {}; - -scoped_ptr<Sub> SubClassReturn() { - return make_scoped_ptr(new Sub); -} - -TEST(ScopedPtrTest, Conversion) { - scoped_ptr<Sub> sub1(new Sub); - scoped_ptr<Sub> sub2(new Sub); - - // Upcast with Pass() works. - scoped_ptr<Super> super1 = sub1.Pass(); - super1 = sub2.Pass(); - - // Upcast with an rvalue works. - scoped_ptr<Super> super2 = SubClassReturn(); - super2 = SubClassReturn(); -} |