Index: base/mac/scoped_typeref.h |
diff --git a/base/mac/scoped_typeref.h b/base/mac/scoped_typeref.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d86ad4cf74f675e7afb489d7837650dad6cb58d2 |
--- /dev/null |
+++ b/base/mac/scoped_typeref.h |
@@ -0,0 +1,116 @@ |
+// Copyright (c) 2014 The Chromium Authors. All rights reserved. |
Avi (use Gerrit)
2014/02/07 01:45:29
no (c)
ccameron
2014/02/07 06:57:49
Done.
|
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef BASE_MAC_SCOPED_TYPEREF_H_ |
+#define BASE_MAC_SCOPED_TYPEREF_H_ |
+ |
+#include "base/basictypes.h" |
+#include "base/compiler_specific.h" |
+#include "base/logging.h" |
+#include "base/memory/scoped_policy.h" |
+ |
+namespace base { |
+ |
+// ScopedTypeRef<> is a generalized form of ScopedCFTypeRef<>, for use with |
Avi (use Gerrit)
2014/02/07 01:45:29
OTOH, you could look at ScopedCFTypeRef as being a
ccameron
2014/02/07 06:57:49
Good call. Change ScopedCFTypeRef to be a subclass
|
+// types that have have type-specific retain and release functions (e.g, |
+// CGLContextObj, which requires use of CGLReleaseContext instead of CFRelease). |
+// |
+// This type may be initialized in the same ways as ScopedCFTypeRef<>, with |
+// parameterized ownership. |
+// |
+// Additionally, for the many types that have pass-by-pointer constructor |
+// functions, the operator& is overloaded, to allow direct initialization |
+// and assumption of ownership of the object, e.g: |
+// |
+// base::ScopedTypeRef<CGLContextObj, CGLRetainContext, CGLReleaseContext> |
+// context; |
+// CGLCreateContext(pixel_format, share_group, &context); |
+ |
+template<typename T, T Retain(T), void Release(T)> |
+class ScopedTypeRef { |
+ public: |
+ typedef T element_type; |
+ |
+ ScopedTypeRef() : object_(NULL) {} |
+ |
+ explicit ScopedTypeRef( |
+ T object, |
+ base::scoped_policy::OwnershipPolicy policy) |
+ : object_(object) { |
+ if (object_ && policy == base::scoped_policy::RETAIN) |
+ Retain(object_); |
+ } |
+ |
+ ScopedTypeRef(const ScopedTypeRef<T, Retain, Release>& that) |
+ : object_(that.object_) { |
+ if (object_) |
+ Retain(object_); |
+ } |
+ |
+ ~ScopedTypeRef() { |
+ if (object_) |
+ Release(object_); |
+ } |
+ |
+ // This is to be used only to take ownership of objects that are created |
+ // by pass-by-pointer constructor functions. To enforce this, require that |
+ // the object be reset to NULL before this may be used. |
+ T* operator&() WARN_UNUSED_RESULT { |
+ DCHECK(!object_); |
+ return &object_; |
+ } |
+ |
+ ScopedTypeRef& operator=(const ScopedTypeRef<T, Retain, Release>& that) { |
+ reset(that.get(), base::scoped_policy::RETAIN); |
+ return *this; |
+ } |
+ |
+ void reset(T object = NULL, |
+ base::scoped_policy::OwnershipPolicy policy = |
+ base::scoped_policy::ASSUME) { |
+ if (object && policy == base::scoped_policy::RETAIN) |
+ Retain(object); |
+ if (object_) |
+ Release(object_); |
+ object_ = object; |
+ } |
+ |
+ bool operator==(T that) const { |
+ return object_ == that; |
+ } |
+ |
+ bool operator!=(T that) const { |
+ return object_ != that; |
+ } |
+ |
+ operator T() const { |
+ return object_; |
+ } |
+ |
+ T get() const { |
+ return object_; |
+ } |
+ |
+ void swap(ScopedTypeRef& that) { |
+ T temp = that.object_; |
+ that.object_ = object_; |
+ object_ = temp; |
+ } |
+ |
+ // ScopedTypeRef<>::release() is like scoped_ptr<>::release. It is NOT |
+ // a wrapper for Release(). To force a ScopedTypeRef<> object to call |
+ // Release(), use ScopedTypeRef<>::reset(). |
+ T release() WARN_UNUSED_RESULT { |
+ T temp = object_; |
+ object_ = NULL; |
+ return temp; |
+ } |
+ |
+ private: |
+ T object_; |
+}; |
+ |
+} // namespace base |
+ |
+#endif // BASE_MAC_SCOPED_TYPEREF_H_ |