| 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 #ifndef BASE_MEMORY_SCOPED_NSOBJECT_H_ | 5 #ifndef BASE_MEMORY_SCOPED_NSOBJECT_H_ |
| 6 #define BASE_MEMORY_SCOPED_NSOBJECT_H_ | 6 #define BASE_MEMORY_SCOPED_NSOBJECT_H_ |
| 7 | 7 |
| 8 #import <Foundation/Foundation.h> | 8 #import <Foundation/Foundation.h> |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| 11 #include "base/memory/scoped_policy.h" | |
| 12 | 11 |
| 13 // scoped_nsobject<> is patterned after scoped_ptr<>, but maintains ownership | 12 // scoped_nsobject<> is patterned after scoped_ptr<>, but maintains ownership |
| 14 // of an NSObject subclass object. Style deviations here are solely for | 13 // of an NSObject subclass object. Style deviations here are solely for |
| 15 // compatibility with scoped_ptr<>'s interface, with which everyone is already | 14 // compatibility with scoped_ptr<>'s interface, with which everyone is already |
| 16 // familiar. | 15 // familiar. |
| 17 // | 16 // |
| 18 // By default, scoped_nsobject<> takes ownership of an object (in the | 17 // scoped_nsobject<> takes ownership of an object (in the constructor or in |
| 19 // constructor or in reset()) by taking over the caller's existing ownership | 18 // reset()) by taking over the caller's existing ownership claim. The caller |
| 20 // claim. The caller must own the object it gives to scoped_nsobject<>, and | 19 // must own the object it gives to scoped_nsobject<>, and relinquishes an |
| 21 // relinquishes an ownership claim to that object. scoped_nsobject<> does not | 20 // ownership claim to that object. scoped_nsobject<> does not call -retain, |
| 22 // call -retain. This behavior is parametrized by the |OwnershipPolicy| enum. | 21 // callers have to call this manually if appropriate. |
| 23 // If the value |RETAIN| is passed (in the constructor or in reset()), then | |
| 24 // scoped_nsobject<> will call -retain on the object, and the initial | |
| 25 // ownership is not changed. | |
| 26 // | 22 // |
| 27 // scoped_nsprotocol<> has the same behavior as scoped_nsobject, but can be used | 23 // scoped_nsprotocol<> has the same behavior as scoped_nsobject, but can be used |
| 28 // with protocols. | 24 // with protocols. |
| 29 // | 25 // |
| 30 // scoped_nsobject<> is not to be used for NSAutoreleasePools. For | 26 // scoped_nsobject<> is not to be used for NSAutoreleasePools. For |
| 31 // NSAutoreleasePools use ScopedNSAutoreleasePool from | 27 // NSAutoreleasePools use ScopedNSAutoreleasePool from |
| 32 // scoped_nsautorelease_pool.h instead. | 28 // scoped_nsautorelease_pool.h instead. |
| 33 // We check for bad uses of scoped_nsobject and NSAutoreleasePool at compile | 29 // We check for bad uses of scoped_nsobject and NSAutoreleasePool at compile |
| 34 // time with a template specialization (see below). | 30 // time with a template specialization (see below). |
| 35 | 31 |
| 36 template<typename NST> | 32 template<typename NST> |
| 37 class scoped_nsprotocol { | 33 class scoped_nsprotocol { |
| 38 public: | 34 public: |
| 39 explicit scoped_nsprotocol( | 35 explicit scoped_nsprotocol(NST object = nil) : object_(object) {} |
| 40 NST object = nil, | |
| 41 base::scoped_policy::OwnershipPolicy policy = base::scoped_policy::ASSUME) | |
| 42 : object_(object) { | |
| 43 if (policy == base::scoped_policy::RETAIN) | |
| 44 [object retain]; | |
| 45 } | |
| 46 | 36 |
| 47 scoped_nsprotocol(const scoped_nsprotocol<NST>& that) | 37 scoped_nsprotocol(const scoped_nsprotocol<NST>& that) |
| 48 : object_([that.object_ retain]) { | 38 : object_([that.object_ retain]) { |
| 49 } | 39 } |
| 50 | 40 |
| 51 ~scoped_nsprotocol() { | 41 ~scoped_nsprotocol() { |
| 52 [object_ release]; | 42 [object_ release]; |
| 53 } | 43 } |
| 54 | 44 |
| 55 scoped_nsprotocol& operator=(const scoped_nsprotocol<NST>& that) { | 45 scoped_nsprotocol& operator=(const scoped_nsprotocol<NST>& that) { |
| 56 reset(that.get(), base::scoped_policy::RETAIN); | 46 reset([that.get() retain]); |
| 57 return *this; | 47 return *this; |
| 58 } | 48 } |
| 59 | 49 |
| 60 void reset(NST object = nil, | 50 void reset(NST object = nil) { |
| 61 base::scoped_policy::OwnershipPolicy policy = | |
| 62 base::scoped_policy::ASSUME) { | |
| 63 if (policy == base::scoped_policy::RETAIN) | |
| 64 [object retain]; | |
| 65 // We intentionally do not check that object != object_ as the caller must | 51 // We intentionally do not check that object != object_ as the caller must |
| 66 // either already have an ownership claim over whatever it passes to this | 52 // either already have an ownership claim over whatever it passes to this |
| 67 // method, or call it with the |RETAIN| policy which will have ensured that | 53 // method, or call it with the |RETAIN| policy which will have ensured that |
| 68 // the object is retained once more when reaching this point. | 54 // the object is retained once more when reaching this point. |
| 69 [object_ release]; | 55 [object_ release]; |
| 70 object_ = object; | 56 object_ = object; |
| 71 } | 57 } |
| 72 | 58 |
| 73 bool operator==(NST that) const { return object_ == that; } | 59 bool operator==(NST that) const { return object_ == that; } |
| 74 bool operator!=(NST that) const { return object_ != that; } | 60 bool operator!=(NST that) const { return object_ != that; } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 } | 103 } |
| 118 | 104 |
| 119 template <class C> | 105 template <class C> |
| 120 bool operator!=(C p1, const scoped_nsprotocol<C>& p2) { | 106 bool operator!=(C p1, const scoped_nsprotocol<C>& p2) { |
| 121 return p1 != p2.get(); | 107 return p1 != p2.get(); |
| 122 } | 108 } |
| 123 | 109 |
| 124 template<typename NST> | 110 template<typename NST> |
| 125 class scoped_nsobject : public scoped_nsprotocol<NST*> { | 111 class scoped_nsobject : public scoped_nsprotocol<NST*> { |
| 126 public: | 112 public: |
| 127 explicit scoped_nsobject( | 113 explicit scoped_nsobject(NST* object = nil) |
| 128 NST* object = nil, | 114 : scoped_nsprotocol<NST*>(object) {} |
| 129 base::scoped_policy::OwnershipPolicy policy = base::scoped_policy::ASSUME) | |
| 130 : scoped_nsprotocol<NST*>(object, policy) { | |
| 131 } | |
| 132 | 115 |
| 133 scoped_nsobject(const scoped_nsobject<NST>& that) | 116 scoped_nsobject(const scoped_nsobject<NST>& that) |
| 134 : scoped_nsprotocol<NST*>(that) { | 117 : scoped_nsprotocol<NST*>(that) { |
| 135 } | 118 } |
| 136 | 119 |
| 137 scoped_nsobject& operator=(const scoped_nsobject<NST>& that) { | 120 scoped_nsobject& operator=(const scoped_nsobject<NST>& that) { |
| 138 scoped_nsprotocol<NST*>::operator=(that); | 121 scoped_nsprotocol<NST*>::operator=(that); |
| 139 return *this; | 122 return *this; |
| 140 } | 123 } |
| 141 }; | 124 }; |
| 142 | 125 |
| 143 // Specialization to make scoped_nsobject<id> work. | 126 // Specialization to make scoped_nsobject<id> work. |
| 144 template<> | 127 template<> |
| 145 class scoped_nsobject<id> : public scoped_nsprotocol<id> { | 128 class scoped_nsobject<id> : public scoped_nsprotocol<id> { |
| 146 public: | 129 public: |
| 147 explicit scoped_nsobject( | 130 explicit scoped_nsobject(id object = nil) : scoped_nsprotocol<id>(object) {} |
| 148 id object = nil, | |
| 149 base::scoped_policy::OwnershipPolicy policy = base::scoped_policy::ASSUME) | |
| 150 : scoped_nsprotocol<id>(object, policy) { | |
| 151 } | |
| 152 | 131 |
| 153 scoped_nsobject(const scoped_nsobject<id>& that) | 132 scoped_nsobject(const scoped_nsobject<id>& that) |
| 154 : scoped_nsprotocol<id>(that) { | 133 : scoped_nsprotocol<id>(that) { |
| 155 } | 134 } |
| 156 | 135 |
| 157 scoped_nsobject& operator=(const scoped_nsobject<id>& that) { | 136 scoped_nsobject& operator=(const scoped_nsobject<id>& that) { |
| 158 scoped_nsprotocol<id>::operator=(that); | 137 scoped_nsprotocol<id>::operator=(that); |
| 159 return *this; | 138 return *this; |
| 160 } | 139 } |
| 161 }; | 140 }; |
| 162 | 141 |
| 163 // Do not use scoped_nsobject for NSAutoreleasePools, use | 142 // Do not use scoped_nsobject for NSAutoreleasePools, use |
| 164 // ScopedNSAutoreleasePool instead. This is a compile time check. See details | 143 // ScopedNSAutoreleasePool instead. This is a compile time check. See details |
| 165 // at top of header. | 144 // at top of header. |
| 166 template<> | 145 template<> |
| 167 class scoped_nsobject<NSAutoreleasePool> { | 146 class scoped_nsobject<NSAutoreleasePool> { |
| 168 private: | 147 private: |
| 169 explicit scoped_nsobject(NSAutoreleasePool* object = nil, | 148 explicit scoped_nsobject(NSAutoreleasePool* object = nil); |
| 170 base::scoped_policy::OwnershipPolicy policy = | |
| 171 base::scoped_policy::ASSUME); | |
| 172 DISALLOW_COPY_AND_ASSIGN(scoped_nsobject); | 149 DISALLOW_COPY_AND_ASSIGN(scoped_nsobject); |
| 173 }; | 150 }; |
| 174 #endif // BASE_MEMORY_SCOPED_NSOBJECT_H_ | 151 #endif // BASE_MEMORY_SCOPED_NSOBJECT_H_ |
| OLD | NEW |