From 91208922687a33df1d5253928b8d5d7d4685c7ac Mon Sep 17 00:00:00 2001 From: "bungeman@google.com" Date: Mon, 30 Jul 2012 15:03:59 +0000 Subject: [PATCH] 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 --- include/core/SkRefCnt.h | 54 ++++++++++---------------------------- 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 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 class SkAutoTUnrefBase : SkNoncopyable { +template 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 is a type which inherits from B, cannot be created, and makes - * ref and unref private. + * BlockRef is a type which inherits from B, cannot be created, + * and makes ref and unref private. */ template 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 class SkAutoTUnref : public SkAutoTUnrefBase { -public: - explicit SkAutoTUnref(T* obj = NULL) : SkAutoTUnrefBase(obj) {} + /** If T is const, the type returned from operator-> will also be const. */ + typedef typename SkTConstType, SkTIsConst::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*. This prevents use of * skAutoTUnrefInstance->ref() and skAutoTUnrefInstance->unref(). */ - typedef typename SkAutoTUnrefBase::template BlockRef BlockRefT; - - BlockRefT* operator->() const { - return static_cast(this->fObj); + BlockRefType *operator->() const { + return static_cast(fObj); } -}; - -template class SkAutoTUnref : public SkAutoTUnrefBase { -public: - explicit SkAutoTUnref(const T* obj = NULL) : SkAutoTUnrefBase(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*. This prevents use of - * skAutoTUnrefInstance->ref() and skAutoTUnrefInstance->unref(). - */ - typedef typename SkAutoTUnrefBase::template BlockRef BlockRefT; + operator T*() { return fObj; } - const BlockRefT* operator->() const { - return static_cast(this->fObj); - } +private: + T* fObj; }; class SkAutoUnref : public SkAutoTUnref { 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::value is true if the type T is const. + * The type T is constrained not to be an array or reference type. + */ +template 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::type will be 'const T' if CONST is true, 'T' otherwise. */ +template struct SkTConstType { + typedef T type; +}; +template struct SkTConstType { + typedef const T type; +}; +///@} + /** \class SkAutoTCallVProc Call a function when this goes out of scope. The template uses two -- 2.34.1