diff options
author | 2012-07-27 13:27:35 +0000 | |
---|---|---|
committer | 2012-07-27 13:27:35 +0000 | |
commit | 1448cf8cb6c6cd4866f7c71bf32ad6bca5d683d1 (patch) | |
tree | 25012daa21171d5ee7bdf06043c5ad88010f33e0 /include/core/SkRefCnt.h | |
parent | e5a196f4403529076dfa335facb2122c5768d8aa (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.h | 53 |
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> { |