diff options
author | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-20 22:42:11 +0000 |
---|---|---|
committer | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-20 22:42:11 +0000 |
commit | 974282583d003c569aca7a22b72cc2ca94264af1 (patch) | |
tree | 768c0ba11cce6835e54ce39b567a9e0f98c94ff5 /base | |
parent | 1a5f6eacc2e704970d566b236c196645eab7d2aa (diff) | |
download | chromium_src-974282583d003c569aca7a22b72cc2ca94264af1.zip chromium_src-974282583d003c569aca7a22b72cc2ca94264af1.tar.gz chromium_src-974282583d003c569aca7a22b72cc2ca94264af1.tar.bz2 |
Move scoped_nsobject from base/memory to base/mac.
So it's next to scoped_cftyperef.h. Also move both scoped_nsobject and
ScopedCFTypeRef to namespace base.
BUG=251957
R=mark@chromium.org
Review URL: https://codereview.chromium.org/17500005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@207616 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/base.gyp | 2 | ||||
-rw-r--r-- | base/base.gypi | 1 | ||||
-rw-r--r-- | base/mac/scoped_cftyperef.h | 6 | ||||
-rw-r--r-- | base/mac/scoped_nsobject.h | 156 | ||||
-rw-r--r-- | base/mac/scoped_nsobject_unittest.mm (renamed from base/memory/scoped_nsobject_unittest.mm) | 24 | ||||
-rw-r--r-- | base/memory/scoped_nsobject.h | 148 |
6 files changed, 181 insertions, 156 deletions
diff --git a/base/base.gyp b/base/base.gyp index b11642f..381540a 100644 --- a/base/base.gyp +++ b/base/base.gyp @@ -512,6 +512,7 @@ 'mac/libdispatch_task_runner_unittest.cc', 'mac/mac_util_unittest.mm', 'mac/objc_property_releaser_unittest.mm', + 'mac/scoped_nsobject_unittest.mm', 'mac/scoped_sending_event_unittest.mm', 'md5_unittest.cc', 'memory/aligned_memory_unittest.cc', @@ -519,7 +520,6 @@ 'memory/linked_ptr_unittest.cc', 'memory/ref_counted_memory_unittest.cc', 'memory/ref_counted_unittest.cc', - 'memory/scoped_nsobject_unittest.mm', 'memory/scoped_ptr_unittest.cc', 'memory/scoped_ptr_unittest.nc', 'memory/scoped_vector_unittest.cc', diff --git a/base/base.gypi b/base/base.gypi index 67cdfe4..b28efd2 100644 --- a/base/base.gypi +++ b/base/base.gypi @@ -267,6 +267,7 @@ 'mac/scoped_nsautorelease_pool.mm', 'mac/scoped_nsexception_enabler.h', 'mac/scoped_nsexception_enabler.mm', + 'mac/scoped_nsobject.h', 'mac/scoped_sending_event.h', 'mac/scoped_sending_event.mm', 'mac/sdk_forward_declarations.h', diff --git a/base/mac/scoped_cftyperef.h b/base/mac/scoped_cftyperef.h index c6ca46a..f09fcbf 100644 --- a/base/mac/scoped_cftyperef.h +++ b/base/mac/scoped_cftyperef.h @@ -12,7 +12,6 @@ #include "base/memory/scoped_policy.h" namespace base { -namespace mac { // ScopedCFTypeRef<> is patterned after scoped_ptr<>, but maintains ownership // of a CoreFoundation object: any object that can be represented as a @@ -102,7 +101,12 @@ class ScopedCFTypeRef { CFT object_; }; +// TODO(thakis): Remove this once all clients use base::ScopedCFTypeRef +// directly. +namespace mac { +using base::ScopedCFTypeRef; } // namespace mac + } // namespace base #endif // BASE_MAC_SCOPED_CFTYPEREF_H_ diff --git a/base/mac/scoped_nsobject.h b/base/mac/scoped_nsobject.h new file mode 100644 index 0000000..8d7bd4a --- /dev/null +++ b/base/mac/scoped_nsobject.h @@ -0,0 +1,156 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_MAC_SCOPED_NSOBJECT_H_ +#define BASE_MAC_SCOPED_NSOBJECT_H_ + +#import <Foundation/Foundation.h> +#include "base/basictypes.h" +#include "base/compiler_specific.h" + +namespace base { + +// scoped_nsobject<> is patterned after scoped_ptr<>, but maintains ownership +// of an NSObject subclass object. Style deviations here are solely for +// compatibility with scoped_ptr<>'s interface, with which everyone is already +// familiar. +// +// scoped_nsobject<> takes ownership of an object (in the constructor or in +// reset()) by taking over the caller's existing ownership claim. The caller +// must own the object it gives to scoped_nsobject<>, and relinquishes an +// ownership claim to that object. scoped_nsobject<> does not call -retain, +// callers have to call this manually if appropriate. +// +// scoped_nsprotocol<> has the same behavior as scoped_nsobject, but can be used +// with protocols. +// +// scoped_nsobject<> is not to be used for NSAutoreleasePools. For +// NSAutoreleasePools use ScopedNSAutoreleasePool from +// scoped_nsautorelease_pool.h instead. +// We check for bad uses of scoped_nsobject and NSAutoreleasePool at compile +// time with a template specialization (see below). + +template<typename NST> +class scoped_nsprotocol { + public: + explicit scoped_nsprotocol(NST object = nil) : object_(object) {} + + scoped_nsprotocol(const scoped_nsprotocol<NST>& that) + : object_([that.object_ retain]) { + } + + ~scoped_nsprotocol() { + [object_ release]; + } + + scoped_nsprotocol& operator=(const scoped_nsprotocol<NST>& that) { + reset([that.get() retain]); + return *this; + } + + void reset(NST object = nil) { + // We intentionally do not check that object != object_ as the caller must + // either already have an ownership claim over whatever it passes to this + // method, or call it with the |RETAIN| policy which will have ensured that + // the object is retained once more when reaching this point. + [object_ release]; + object_ = object; + } + + bool operator==(NST that) const { return object_ == that; } + bool operator!=(NST that) const { return object_ != that; } + + operator NST() const { + return object_; + } + + NST get() const { + return object_; + } + + void swap(scoped_nsprotocol& that) { + NST temp = that.object_; + that.object_ = object_; + object_ = temp; + } + + // scoped_nsprotocol<>::release() is like scoped_ptr<>::release. It is NOT a + // wrapper for [object_ release]. To force a scoped_nsprotocol<> to call + // [object_ release], use scoped_nsprotocol<>::reset(). + NST release() WARN_UNUSED_RESULT { + NST temp = object_; + object_ = nil; + return temp; + } + + // Shift reference to the autorelease pool to be released later. + NST autorelease() { + return [release() autorelease]; + } + + private: + NST object_; +}; + +// Free functions +template <class C> +void swap(scoped_nsprotocol<C>& p1, scoped_nsprotocol<C>& p2) { + p1.swap(p2); +} + +template <class C> +bool operator==(C p1, const scoped_nsprotocol<C>& p2) { + return p1 == p2.get(); +} + +template <class C> +bool operator!=(C p1, const scoped_nsprotocol<C>& p2) { + return p1 != p2.get(); +} + +template<typename NST> +class scoped_nsobject : public scoped_nsprotocol<NST*> { + public: + explicit scoped_nsobject(NST* object = nil) + : scoped_nsprotocol<NST*>(object) {} + + scoped_nsobject(const scoped_nsobject<NST>& that) + : scoped_nsprotocol<NST*>(that) { + } + + scoped_nsobject& operator=(const scoped_nsobject<NST>& that) { + scoped_nsprotocol<NST*>::operator=(that); + return *this; + } +}; + +// Specialization to make scoped_nsobject<id> work. +template<> +class scoped_nsobject<id> : public scoped_nsprotocol<id> { + public: + explicit scoped_nsobject(id object = nil) : scoped_nsprotocol<id>(object) {} + + scoped_nsobject(const scoped_nsobject<id>& that) + : scoped_nsprotocol<id>(that) { + } + + scoped_nsobject& operator=(const scoped_nsobject<id>& that) { + scoped_nsprotocol<id>::operator=(that); + return *this; + } +}; + +// Do not use scoped_nsobject for NSAutoreleasePools, use +// ScopedNSAutoreleasePool instead. This is a compile time check. See details +// at top of header. +template<> +class scoped_nsobject<NSAutoreleasePool> { + private: + explicit scoped_nsobject(NSAutoreleasePool* object = nil); + DISALLOW_COPY_AND_ASSIGN(scoped_nsobject); +}; + +} // namespace base + +#endif // BASE_MAC_SCOPED_NSOBJECT_H_ diff --git a/base/memory/scoped_nsobject_unittest.mm b/base/mac/scoped_nsobject_unittest.mm index 8c3f5ec..f290c3a 100644 --- a/base/memory/scoped_nsobject_unittest.mm +++ b/base/mac/scoped_nsobject_unittest.mm @@ -6,23 +6,23 @@ #include "base/basictypes.h" #include "base/mac/scoped_nsautorelease_pool.h" -#include "base/memory/scoped_nsobject.h" +#include "base/mac/scoped_nsobject.h" #include "testing/gtest/include/gtest/gtest.h" namespace { TEST(ScopedNSObjectTest, ScopedNSObject) { - scoped_nsobject<NSObject> p1([[NSObject alloc] init]); + base::scoped_nsobject<NSObject> p1([[NSObject alloc] init]); ASSERT_TRUE(p1.get()); ASSERT_EQ(1u, [p1 retainCount]); - scoped_nsobject<NSObject> p2(p1); + base::scoped_nsobject<NSObject> p2(p1); ASSERT_EQ(p1.get(), p2.get()); ASSERT_EQ(2u, [p1 retainCount]); p2.reset(); ASSERT_EQ(nil, p2.get()); ASSERT_EQ(1u, [p1 retainCount]); { - scoped_nsobject<NSObject> p3 = p1; + base::scoped_nsobject<NSObject> p3 = p1; ASSERT_EQ(p1.get(), p3.get()); ASSERT_EQ(2u, [p1 retainCount]); p3 = p1; @@ -30,19 +30,19 @@ TEST(ScopedNSObjectTest, ScopedNSObject) { ASSERT_EQ(2u, [p1 retainCount]); } ASSERT_EQ(1u, [p1 retainCount]); - scoped_nsobject<NSObject> p4([p1.get() retain]); + base::scoped_nsobject<NSObject> p4([p1.get() retain]); ASSERT_EQ(2u, [p1 retainCount]); ASSERT_TRUE(p1 == p1.get()); ASSERT_TRUE(p1 == p1); ASSERT_FALSE(p1 != p1); ASSERT_FALSE(p1 != p1.get()); - scoped_nsobject<NSObject> p5([[NSObject alloc] init]); + base::scoped_nsobject<NSObject> p5([[NSObject alloc] init]); ASSERT_TRUE(p1 != p5); ASSERT_TRUE(p1 != p5.get()); ASSERT_FALSE(p1 == p5); ASSERT_FALSE(p1 == p5.get()); - scoped_nsobject<NSObject> p6 = p1; + base::scoped_nsobject<NSObject> p6 = p1; ASSERT_EQ(3u, [p6 retainCount]); { base::mac::ScopedNSAutoreleasePool pool; @@ -54,15 +54,15 @@ TEST(ScopedNSObjectTest, ScopedNSObject) { } TEST(ScopedNSObjectTest, ScopedNSObjectInContainer) { - scoped_nsobject<id> p([[NSObject alloc] init]); + base::scoped_nsobject<id> p([[NSObject alloc] init]); ASSERT_TRUE(p.get()); ASSERT_EQ(1u, [p retainCount]); { - std::vector<scoped_nsobject<id> > objects; + std::vector<base::scoped_nsobject<id>> objects; objects.push_back(p); ASSERT_EQ(2u, [p retainCount]); ASSERT_EQ(p.get(), objects[0].get()); - objects.push_back(scoped_nsobject<id>([[NSObject alloc] init])); + objects.push_back(base::scoped_nsobject<id>([[NSObject alloc] init])); ASSERT_TRUE(objects[1].get()); ASSERT_EQ(1u, [objects[1] retainCount]); } @@ -70,11 +70,11 @@ TEST(ScopedNSObjectTest, ScopedNSObjectInContainer) { } TEST(ScopedNSObjectTest, ScopedNSObjectFreeFunctions) { - scoped_nsobject<id> p1([[NSObject alloc] init]); + base::scoped_nsobject<id> p1([[NSObject alloc] init]); id o1 = p1.get(); ASSERT_TRUE(o1 == p1); ASSERT_FALSE(o1 != p1); - scoped_nsobject<id> p2([[NSObject alloc] init]); + base::scoped_nsobject<id> p2([[NSObject alloc] init]); ASSERT_TRUE(o1 != p2); ASSERT_FALSE(o1 == p2); id o2 = p2.get(); diff --git a/base/memory/scoped_nsobject.h b/base/memory/scoped_nsobject.h index a5b6dbf..db8020a 100644 --- a/base/memory/scoped_nsobject.h +++ b/base/memory/scoped_nsobject.h @@ -1,151 +1,15 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef BASE_MEMORY_SCOPED_NSOBJECT_H_ #define BASE_MEMORY_SCOPED_NSOBJECT_H_ -#import <Foundation/Foundation.h> -#include "base/basictypes.h" -#include "base/compiler_specific.h" +// TODO(thakis): Update all clients to include base/mac/scoped_nsobject.h and +// get rid of this forwarding header. +#include "base/mac/scoped_nsobject.h" -// scoped_nsobject<> is patterned after scoped_ptr<>, but maintains ownership -// of an NSObject subclass object. Style deviations here are solely for -// compatibility with scoped_ptr<>'s interface, with which everyone is already -// familiar. -// -// scoped_nsobject<> takes ownership of an object (in the constructor or in -// reset()) by taking over the caller's existing ownership claim. The caller -// must own the object it gives to scoped_nsobject<>, and relinquishes an -// ownership claim to that object. scoped_nsobject<> does not call -retain, -// callers have to call this manually if appropriate. -// -// scoped_nsprotocol<> has the same behavior as scoped_nsobject, but can be used -// with protocols. -// -// scoped_nsobject<> is not to be used for NSAutoreleasePools. For -// NSAutoreleasePools use ScopedNSAutoreleasePool from -// scoped_nsautorelease_pool.h instead. -// We check for bad uses of scoped_nsobject and NSAutoreleasePool at compile -// time with a template specialization (see below). +using base::scoped_nsobject; +using base::scoped_nsprotocol; -template<typename NST> -class scoped_nsprotocol { - public: - explicit scoped_nsprotocol(NST object = nil) : object_(object) {} - - scoped_nsprotocol(const scoped_nsprotocol<NST>& that) - : object_([that.object_ retain]) { - } - - ~scoped_nsprotocol() { - [object_ release]; - } - - scoped_nsprotocol& operator=(const scoped_nsprotocol<NST>& that) { - reset([that.get() retain]); - return *this; - } - - void reset(NST object = nil) { - // We intentionally do not check that object != object_ as the caller must - // either already have an ownership claim over whatever it passes to this - // method, or call it with the |RETAIN| policy which will have ensured that - // the object is retained once more when reaching this point. - [object_ release]; - object_ = object; - } - - bool operator==(NST that) const { return object_ == that; } - bool operator!=(NST that) const { return object_ != that; } - - operator NST() const { - return object_; - } - - NST get() const { - return object_; - } - - void swap(scoped_nsprotocol& that) { - NST temp = that.object_; - that.object_ = object_; - object_ = temp; - } - - // scoped_nsprotocol<>::release() is like scoped_ptr<>::release. It is NOT a - // wrapper for [object_ release]. To force a scoped_nsprotocol<> to call - // [object_ release], use scoped_nsprotocol<>::reset(). - NST release() WARN_UNUSED_RESULT { - NST temp = object_; - object_ = nil; - return temp; - } - - // Shift reference to the autorelease pool to be released later. - NST autorelease() { - return [release() autorelease]; - } - - private: - NST object_; -}; - -// Free functions -template <class C> -void swap(scoped_nsprotocol<C>& p1, scoped_nsprotocol<C>& p2) { - p1.swap(p2); -} - -template <class C> -bool operator==(C p1, const scoped_nsprotocol<C>& p2) { - return p1 == p2.get(); -} - -template <class C> -bool operator!=(C p1, const scoped_nsprotocol<C>& p2) { - return p1 != p2.get(); -} - -template<typename NST> -class scoped_nsobject : public scoped_nsprotocol<NST*> { - public: - explicit scoped_nsobject(NST* object = nil) - : scoped_nsprotocol<NST*>(object) {} - - scoped_nsobject(const scoped_nsobject<NST>& that) - : scoped_nsprotocol<NST*>(that) { - } - - scoped_nsobject& operator=(const scoped_nsobject<NST>& that) { - scoped_nsprotocol<NST*>::operator=(that); - return *this; - } -}; - -// Specialization to make scoped_nsobject<id> work. -template<> -class scoped_nsobject<id> : public scoped_nsprotocol<id> { - public: - explicit scoped_nsobject(id object = nil) : scoped_nsprotocol<id>(object) {} - - scoped_nsobject(const scoped_nsobject<id>& that) - : scoped_nsprotocol<id>(that) { - } - - scoped_nsobject& operator=(const scoped_nsobject<id>& that) { - scoped_nsprotocol<id>::operator=(that); - return *this; - } -}; - -// Do not use scoped_nsobject for NSAutoreleasePools, use -// ScopedNSAutoreleasePool instead. This is a compile time check. See details -// at top of header. -template<> -class scoped_nsobject<NSAutoreleasePool> { - private: - explicit scoped_nsobject(NSAutoreleasePool* object = nil); - DISALLOW_COPY_AND_ASSIGN(scoped_nsobject); -}; #endif // BASE_MEMORY_SCOPED_NSOBJECT_H_ |