scoped_cftyperef.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
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 3// found in the LICENSE file. 4 5#ifndef BASE_MAC_SCOPED_CFTYPEREF_H_ 6#define BASE_MAC_SCOPED_CFTYPEREF_H_ 7 8#include <CoreFoundation/CoreFoundation.h> 9 10#include "base/basictypes.h" 11#include "base/compiler_specific.h" 12#include "base/memory/scoped_policy.h" 13 14namespace base { 15namespace mac { 16 17// ScopedCFTypeRef<> is patterned after scoped_ptr<>, but maintains ownership 18// of a CoreFoundation object: any object that can be represented as a 19// CFTypeRef. Style deviations here are solely for compatibility with 20// scoped_ptr<>'s interface, with which everyone is already familiar. 21// 22// By default, ScopedCFTypeRef<> takes ownership of an object (in the 23// constructor or in reset()) by taking over the caller's existing ownership 24// claim. The caller must own the object it gives to ScopedCFTypeRef<>, and 25// relinquishes an ownership claim to that object. ScopedCFTypeRef<> does not 26// call CFRetain(). This behavior is parameterized by the |OwnershipPolicy| 27// enum. If the value |RETAIN| is passed (in the constructor or in reset()), 28// then ScopedCFTypeRef<> will call CFRetain() on the object, and the initial 29// ownership is not changed. 30 31template<typename CFT> 32class ScopedCFTypeRef { 33 public: 34 typedef CFT element_type; 35 36 explicit ScopedCFTypeRef( 37 CFT object = NULL, 38 base::scoped_policy::OwnershipPolicy policy = base::scoped_policy::ASSUME) 39 : object_(object) { 40 if (object_ && policy == base::scoped_policy::RETAIN) 41 CFRetain(object_); 42 } 43 44 ScopedCFTypeRef(const ScopedCFTypeRef<CFT>& that) 45 : object_(that.object_) { 46 if (object_) 47 CFRetain(object_); 48 } 49 50 ~ScopedCFTypeRef() { 51 if (object_) 52 CFRelease(object_); 53 } 54 55 ScopedCFTypeRef& operator=(const ScopedCFTypeRef<CFT>& that) { 56 reset(that.get(), base::scoped_policy::RETAIN); 57 return *this; 58 } 59 60 void reset(CFT object = NULL, 61 base::scoped_policy::OwnershipPolicy policy = 62 base::scoped_policy::ASSUME) { 63 if (object && policy == base::scoped_policy::RETAIN) 64 CFRetain(object); 65 if (object_) 66 CFRelease(object_); 67 object_ = object; 68 } 69 70 bool operator==(CFT that) const { 71 return object_ == that; 72 } 73 74 bool operator!=(CFT that) const { 75 return object_ != that; 76 } 77 78 operator CFT() const { 79 return object_; 80 } 81 82 CFT get() const { 83 return object_; 84 } 85 86 void swap(ScopedCFTypeRef& that) { 87 CFT temp = that.object_; 88 that.object_ = object_; 89 object_ = temp; 90 } 91 92 // ScopedCFTypeRef<>::release() is like scoped_ptr<>::release. It is NOT 93 // a wrapper for CFRelease(). To force a ScopedCFTypeRef<> object to call 94 // CFRelease(), use ScopedCFTypeRef<>::reset(). 95 CFT release() WARN_UNUSED_RESULT { 96 CFT temp = object_; 97 object_ = NULL; 98 return temp; 99 } 100 101 private: 102 CFT object_; 103}; 104 105} // namespace mac 106} // namespace base 107 108#endif // BASE_MAC_SCOPED_CFTYPEREF_H_ 109