diff options
author | bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-07-30 15:03:59 +0000 |
---|---|---|
committer | bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-07-30 15:03:59 +0000 |
commit | 91208922687a33df1d5253928b8d5d7d4685c7ac (patch) | |
tree | e6249206a4d2fce588d13b9ecd343645e2a98afb /include/core | |
parent | 58be682c77c76d9a0caf23337f9b357798179b6c (diff) |
Const correct BlockRef in SkAutoTUnref.
https://codereview.appspot.com/6448066/
git-svn-id: http://skia.googlecode.com/svn/trunk@4829 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include/core')
-rw-r--r-- | include/core/SkRefCnt.h | 54 | ||||
-rw-r--r-- | include/core/SkTemplates.h | 21 |
2 files changed, 35 insertions, 40 deletions
diff --git a/include/core/SkRefCnt.h b/include/core/SkRefCnt.h index eab3c46eb7..32e41dbd6a 100644 --- a/include/core/SkRefCnt.h +++ b/include/core/SkRefCnt.h @@ -12,6 +12,7 @@ #include "SkThread.h" #include "SkInstCnt.h" +#include "SkTemplates.h" /** \class SkRefCnt @@ -135,14 +136,12 @@ template <typename T> static inline void SkSafeUnref(T* obj) { /////////////////////////////////////////////////////////////////////////////// /** - * 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. + * Utility class that simply unref's its argument in the destructor. */ - -template <typename T> class SkAutoTUnrefBase : SkNoncopyable { +template <typename T> class SkAutoTUnref : SkNoncopyable { public: - ~SkAutoTUnrefBase() { SkSafeUnref(fObj); } + explicit SkAutoTUnref(T* obj = NULL) : fObj(obj) {} + ~SkAutoTUnref() { SkSafeUnref(fObj); } T* get() const { return fObj; } @@ -163,11 +162,9 @@ 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: @@ -176,17 +173,8 @@ public: 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) {} + /** If T is const, the type returned from operator-> will also be const. */ + typedef typename SkTConstType<BlockRef<T>, SkTIsConst<T>::value>::type BlockRefType; /** * SkAutoTUnref assumes ownership of the ref. As a result, it is an error @@ -194,27 +182,13 @@ public: * SkAutoTUnref::operator-> returns BlockRef<T>*. This prevents use of * skAutoTUnrefInstance->ref() and skAutoTUnrefInstance->unref(). */ - typedef typename SkAutoTUnrefBase<T>::template BlockRef<T> BlockRefT; - - BlockRefT* operator->() const { - return static_cast<BlockRefT*>(this->fObj); + BlockRefType *operator->() const { + return static_cast<BlockRefType*>(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; + operator T*() { return fObj; } - const BlockRefT* operator->() const { - return static_cast<const BlockRefT*>(this->fObj); - } +private: + T* fObj; }; class SkAutoUnref : public SkAutoTUnref<SkRefCnt> { diff --git a/include/core/SkTemplates.h b/include/core/SkTemplates.h index 03f0892fac..a21a95d48b 100644 --- a/include/core/SkTemplates.h +++ b/include/core/SkTemplates.h @@ -18,6 +18,27 @@ resource management. */ +/** + * SkTIsConst<T>::value is true if the type T is const. + * The type T is constrained not to be an array or reference type. + */ +template <typename T> struct SkTIsConst { + static T* t; + static uint16_t test(const volatile void*); + static uint32_t test(volatile void *); + static const bool value = (sizeof(uint16_t) == sizeof(test(t))); +}; + +///@{ +/** SkTConstType<T, CONST>::type will be 'const T' if CONST is true, 'T' otherwise. */ +template <typename T, bool CONST> struct SkTConstType { + typedef T type; +}; +template <typename T> struct SkTConstType<T, true> { + typedef const T type; +}; +///@} + /** \class SkAutoTCallVProc Call a function when this goes out of scope. The template uses two |