aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/core/SkRefCnt.h
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-07-27 13:27:35 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-07-27 13:27:35 +0000
commit1448cf8cb6c6cd4866f7c71bf32ad6bca5d683d1 (patch)
tree25012daa21171d5ee7bdf06043c5ad88010f33e0 /include/core/SkRefCnt.h
parente5a196f4403529076dfa335facb2122c5768d8aa (diff)
Specialize SkAutoTUnref on const T so that operator -> works.
Review URL: http://codereview.appspot.com/6450054/ git-svn-id: http://skia.googlecode.com/svn/trunk@4802 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include/core/SkRefCnt.h')
-rw-r--r--include/core/SkRefCnt.h53
1 files changed, 42 insertions, 11 deletions
diff --git a/include/core/SkRefCnt.h b/include/core/SkRefCnt.h
index 79a28efeea..eab3c46eb7 100644
--- a/include/core/SkRefCnt.h
+++ b/include/core/SkRefCnt.h
@@ -135,12 +135,14 @@ template <typename T> static inline void SkSafeUnref(T* obj) {
///////////////////////////////////////////////////////////////////////////////
/**
- * Utility class that simply unref's its argument in the destructor.
+ * SkAutoTUnref is a utility class that simply unref's its argument in the
+ * destructor. For implementation detail reasons there is a base class, a
+ * derived general class, and a const-specialized derived class.
*/
-template <typename T> class SkAutoTUnref : SkNoncopyable {
+
+template <typename T> class SkAutoTUnrefBase : SkNoncopyable {
public:
- explicit SkAutoTUnref(T* obj = NULL) : fObj(obj) {}
- ~SkAutoTUnref() { SkSafeUnref(fObj); }
+ ~SkAutoTUnrefBase() { SkSafeUnref(fObj); }
T* get() const { return fObj; }
@@ -161,9 +163,11 @@ public:
return obj;
}
+ operator T*() { return fObj; }
+
/**
- * BlockRef<B> is a type which inherits from B, cannot be created,
- * and makes ref and unref private.
+ * BlockRef<B> is a type which inherits from B, cannot be created, and makes
+ * ref and unref private.
*/
template<typename B> class BlockRef : public B {
private:
@@ -171,19 +175,46 @@ public:
void ref() const;
void unref() const;
};
+
+protected:
+ explicit SkAutoTUnrefBase(T* obj) : fObj(obj) {}
+ T* fObj;
+
+private:
+ SkAutoTUnrefBase();
+};
+
+template <typename T> class SkAutoTUnref : public SkAutoTUnrefBase<T> {
+public:
+ explicit SkAutoTUnref(T* obj = NULL) : SkAutoTUnrefBase<T>(obj) {}
+
/**
* SkAutoTUnref assumes ownership of the ref. As a result, it is an error
* for the user to ref or unref through SkAutoTUnref. Therefore
* SkAutoTUnref::operator-> returns BlockRef<T>*. This prevents use of
* skAutoTUnrefInstance->ref() and skAutoTUnrefInstance->unref().
*/
- BlockRef<T> *operator->() const {
- return static_cast<BlockRef<T>*>(fObj);
+ typedef typename SkAutoTUnrefBase<T>::template BlockRef<T> BlockRefT;
+
+ BlockRefT* operator->() const {
+ return static_cast<BlockRefT*>(this->fObj);
}
- operator T*() { return fObj; }
+};
-private:
- T* fObj;
+template <typename T> class SkAutoTUnref<const T> : public SkAutoTUnrefBase<const T> {
+public:
+ explicit SkAutoTUnref(const T* obj = NULL) : SkAutoTUnrefBase<const T>(obj) {}
+ /**
+ * SkAutoTUnref assumes ownership of the ref. As a result, it is an error
+ * for the user to ref or unref through SkAutoTUnref. Therefore
+ * SkAutoTUnref::operator-> returns BlockRef<T>*. This prevents use of
+ * skAutoTUnrefInstance->ref() and skAutoTUnrefInstance->unref().
+ */
+ typedef typename SkAutoTUnrefBase<const T>::template BlockRef<T> BlockRefT;
+
+ const BlockRefT* operator->() const {
+ return static_cast<const BlockRefT*>(this->fObj);
+ }
};
class SkAutoUnref : public SkAutoTUnref<SkRefCnt> {