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