1 // Copyright 2014 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_TYPEREF_H_ 6 #define BASE_MAC_SCOPED_TYPEREF_H_ 7 8 #include "base/basictypes.h" 9 #include "base/compiler_specific.h" 10 #include "base/logging.h" 11 #include "base/memory/scoped_policy.h" 12 13 namespace base { 14 15 // ScopedTypeRef<> is patterned after scoped_ptr<>, but maintains a ownership 16 // of a reference to any type that is maintained by Retain and Release methods. 17 // 18 // The Traits structure must provide the Retain and Release methods for type T. 19 // A default ScopedTypeRefTraits is used but not defined, and should be defined 20 // for each type to use this interface. For example, an appropriate definition 21 // of ScopedTypeRefTraits for CGLContextObj would be: 22 // 23 // template<> 24 // struct ScopedTypeRefTraits<CGLContextObj> { 25 // void Retain(CGLContextObj object) { CGLContextRetain(object); } 26 // void Release(CGLContextObj object) { CGLContextRelease(object); } 27 // }; 28 // 29 // For the many types that have pass-by-pointer create functions, the function 30 // InitializeInto() is provided to allow direct initialization and assumption 31 // of ownership of the object. For example, continuing to use the above 32 // CGLContextObj specialization: 33 // 34 // base::ScopedTypeRef<CGLContextObj> context; 35 // CGLCreateContext(pixel_format, share_group, context.InitializeInto()); 36 // 37 // For initialization with an existing object, the caller may specify whether 38 // the ScopedTypeRef<> being initialized is assuming the caller's existing 39 // ownership of the object (and should not call Retain in initialization) or if 40 // it should not assume this ownership and must create its own (by calling 41 // Retain in initialization). This behavior is based on the |policy| parameter, 42 // with |ASSUME| for the former and |RETAIN| for the latter. The default policy 43 // is to |ASSUME|. 44 45 template<typename T> 46 struct ScopedTypeRefTraits; 47 48 template<typename T, typename Traits = ScopedTypeRefTraits<T>> 49 class ScopedTypeRef { 50 public: 51 typedef T element_type; 52 53 ScopedTypeRef( 54 T object = NULL, 55 base::scoped_policy::OwnershipPolicy policy = base::scoped_policy::ASSUME) 56 : object_(object) { 57 if (object_ && policy == base::scoped_policy::RETAIN) 58 Traits::Retain(object_); 59 } 60 61 ScopedTypeRef(const ScopedTypeRef<T, Traits>& that) 62 : object_(that.object_) { 63 if (object_) 64 Traits::Retain(object_); 65 } 66 67 ~ScopedTypeRef() { 68 if (object_) 69 Traits::Release(object_); 70 } 71 72 ScopedTypeRef& operator=(const ScopedTypeRef<T, Traits>& that) { 73 reset(that.get(), base::scoped_policy::RETAIN); 74 return *this; 75 } 76 77 // This is to be used only to take ownership of objects that are created 78 // by pass-by-pointer create functions. To enforce this, require that the 79 // object be reset to NULL before this may be used. 80 T* InitializeInto() WARN_UNUSED_RESULT { 81 DCHECK(!object_); 82 return &object_; 83 } 84 85 void reset(T object = NULL, 86 base::scoped_policy::OwnershipPolicy policy = 87 base::scoped_policy::ASSUME) { 88 if (object && policy == base::scoped_policy::RETAIN) 89 Traits::Retain(object); 90 if (object_) 91 Traits::Release(object_); 92 object_ = object; 93 } 94 95 bool operator==(T that) const { 96 return object_ == that; 97 } 98 99 bool operator!=(T that) const { 100 return object_ != that; 101 } 102 103 operator T() const { 104 return object_; 105 } 106 107 T get() const { 108 return object_; 109 } 110 111 void swap(ScopedTypeRef& that) { 112 T temp = that.object_; 113 that.object_ = object_; 114 object_ = temp; 115 } 116 117 // ScopedTypeRef<>::release() is like scoped_ptr<>::release. It is NOT 118 // a wrapper for Release(). To force a ScopedTypeRef<> object to call 119 // Release(), use ScopedTypeRef<>::reset(). 120 T release() WARN_UNUSED_RESULT { 121 T temp = object_; 122 object_ = NULL; 123 return temp; 124 } 125 126 private: 127 T object_; 128 }; 129 130 } // namespace base 131 132 #endif // BASE_MAC_SCOPED_TYPEREF_H_ 133