diff options
author | Steve Block <steveblock@google.com> | 2009-10-08 17:19:54 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2009-10-20 00:41:58 +0100 |
commit | 231d4e3152a9c27a73b6ac7badbe6be673aa3ddf (patch) | |
tree | a6c7e2d6cd7bfa7011cc39abbb436142d7a4a7c8 /JavaScriptCore/wtf/PassRefPtr.h | |
parent | e196732677050bd463301566a68a643b6d14b907 (diff) | |
download | external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.zip external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.tar.gz external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.tar.bz2 |
Merge webkit.org at R49305 : Automatic merge by git.
Change-Id: I8968561bc1bfd72b8923b7118d3728579c6dbcc7
Diffstat (limited to 'JavaScriptCore/wtf/PassRefPtr.h')
-rw-r--r-- | JavaScriptCore/wtf/PassRefPtr.h | 81 |
1 files changed, 74 insertions, 7 deletions
diff --git a/JavaScriptCore/wtf/PassRefPtr.h b/JavaScriptCore/wtf/PassRefPtr.h index d80ed62..36ba78e 100644 --- a/JavaScriptCore/wtf/PassRefPtr.h +++ b/JavaScriptCore/wtf/PassRefPtr.h @@ -28,6 +28,19 @@ namespace WTF { template<typename T> class RefPtr; template<typename T> class PassRefPtr; template <typename T> PassRefPtr<T> adoptRef(T*); + + // Remove inline for winscw compiler to prevent the compiler agressively resolving + // T::deref(), which will fail compiling when PassRefPtr<T> is used as class member + // or function arguments before T is defined. + template<typename T> +#if !COMPILER(WINSCW) + inline +#endif + void derefIfNotNull(T* ptr) + { + if (UNLIKELY(ptr != 0)) + ptr->deref(); + } template<typename T> class PassRefPtr { public: @@ -40,8 +53,8 @@ namespace WTF { PassRefPtr(const PassRefPtr& o) : m_ptr(o.releaseRef()) {} template <typename U> PassRefPtr(const PassRefPtr<U>& o) : m_ptr(o.releaseRef()) { } - ALWAYS_INLINE ~PassRefPtr() { if (UNLIKELY(m_ptr != 0)) m_ptr->deref(); } - + ALWAYS_INLINE ~PassRefPtr() { derefIfNotNull<T>(m_ptr); } + template <class U> PassRefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) ptr->ref(); } @@ -56,12 +69,9 @@ namespace WTF { bool operator!() const { return !m_ptr; } // This conversion operator allows implicit conversion to bool but not to other integer types. -#if COMPILER(WINSCW) - operator bool() const { return m_ptr; } -#else - typedef T* PassRefPtr::*UnspecifiedBoolType; + typedef T* (PassRefPtr::*UnspecifiedBoolType); operator UnspecifiedBoolType() const { return m_ptr ? &PassRefPtr::m_ptr : 0; } -#endif + PassRefPtr& operator=(T*); PassRefPtr& operator=(const PassRefPtr&); template <typename U> PassRefPtr& operator=(const PassRefPtr<U>&); @@ -74,6 +84,62 @@ namespace WTF { mutable T* m_ptr; }; + // NonNullPassRefPtr: Optimized for passing non-null pointers. A NonNullPassRefPtr + // begins life non-null, and can only become null through a call to releaseRef() + // or clear(). + + // FIXME: NonNullPassRefPtr could just inherit from PassRefPtr. However, + // if we use inheritance, GCC's optimizer fails to realize that destruction + // of a released NonNullPassRefPtr is a no-op. So, for now, just copy the + // most important code from PassRefPtr. + template <typename T> class NonNullPassRefPtr { + public: + NonNullPassRefPtr(T* ptr) + : m_ptr(ptr) + { + ASSERT(m_ptr); + m_ptr->ref(); + } + + template <class U> NonNullPassRefPtr(const RefPtr<U>& o) + : m_ptr(o.get()) + { + ASSERT(m_ptr); + m_ptr->ref(); + } + + NonNullPassRefPtr(const NonNullPassRefPtr& o) + : m_ptr(o.releaseRef()) + { + ASSERT(m_ptr); + } + + template <class U> NonNullPassRefPtr(const NonNullPassRefPtr<U>& o) + : m_ptr(o.releaseRef()) + { + ASSERT(m_ptr); + } + + template <class U> NonNullPassRefPtr(const PassRefPtr<U>& o) + : m_ptr(o.releaseRef()) + { + ASSERT(m_ptr); + } + + ALWAYS_INLINE ~NonNullPassRefPtr() { derefIfNotNull(m_ptr); } + + T* get() const { return m_ptr; } + + void clear() { derefIfNotNull(m_ptr); m_ptr = 0; } + T* releaseRef() const { T* tmp = m_ptr; m_ptr = 0; return tmp; } + + T& operator*() const { return *m_ptr; } + T* operator->() const { return m_ptr; } + + private: + mutable T* m_ptr; + }; + template <typename T> template <typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const RefPtr<U>& o) { T* optr = o.get(); @@ -188,6 +254,7 @@ namespace WTF { } // namespace WTF using WTF::PassRefPtr; +using WTF::NonNullPassRefPtr; using WTF::adoptRef; using WTF::static_pointer_cast; using WTF::const_pointer_cast; |