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