namespace WTF {
-template<class T> class RefCounted : Noncopyable {
+// This base class holds the non-template methods and attributes.
+// The RefCounted class inherits from it reducing the template bloat
+// generated by the compiler (technique called template hoisting).
+class RefCountedBase : Noncopyable {
public:
- RefCounted(int initialRefCount = 0)
+ void ref()
+ {
+ ASSERT(!m_deletionHasBegun);
+ ++m_refCount;
+ }
+
+ bool hasOneRef() const
+ {
+ ASSERT(!m_deletionHasBegun);
+ return m_refCount == 1;
+ }
+
+ int refCount() const
+ {
+ return m_refCount;
+ }
+
+protected:
+ RefCountedBase(int initialRefCount)
: m_refCount(initialRefCount)
#ifndef NDEBUG
, m_deletionHasBegun(false)
{
}
- void ref()
- {
- ASSERT(!m_deletionHasBegun);
- ++m_refCount;
- }
+ ~RefCountedBase() {}
- void deref()
+ // Returns whether the pointer should be freed or not.
+ bool derefBase()
{
ASSERT(!m_deletionHasBegun);
ASSERT(m_refCount > 0);
#ifndef NDEBUG
m_deletionHasBegun = true;
#endif
- delete static_cast<T*>(this);
- } else
- --m_refCount;
+ return true;
+ }
+
+ --m_refCount;
+ return false;
}
- bool hasOneRef()
+protected:
+ int m_refCount;
+#ifndef NDEBUG
+ bool m_deletionHasBegun;
+#endif
+};
+
+
+template<class T> class RefCounted : public RefCountedBase {
+public:
+ RefCounted(int initialRefCount = 1)
+ : RefCountedBase(initialRefCount)
{
- ASSERT(!m_deletionHasBegun);
- return m_refCount == 1;
}
- int refCount() const
+ void deref()
{
- return m_refCount;
+ if (derefBase())
+ delete static_cast<T*>(this);
}
-private:
- int m_refCount;
-#ifndef NDEBUG
- bool m_deletionHasBegun;
-#endif
+protected:
+ ~RefCounted() {}
};
} // namespace WTF