diff options
Diffstat (limited to 'JavaScriptCore/wtf/PassRefPtr.h')
| -rw-r--r-- | JavaScriptCore/wtf/PassRefPtr.h | 162 |
1 files changed, 103 insertions, 59 deletions
diff --git a/JavaScriptCore/wtf/PassRefPtr.h b/JavaScriptCore/wtf/PassRefPtr.h index 9c6e44f..b179cef 100644 --- a/JavaScriptCore/wtf/PassRefPtr.h +++ b/JavaScriptCore/wtf/PassRefPtr.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -22,61 +22,67 @@ #define WTF_PassRefPtr_h #include "AlwaysInline.h" +#include "NullPtr.h" namespace WTF { template<typename T> class RefPtr; template<typename T> class PassRefPtr; - template <typename T> PassRefPtr<T> adoptRef(T*); + template<typename T> PassRefPtr<T> adoptRef(T*); + inline void adopted(const void*) { } - // Remove inline for WINSCW compiler to prevent the compiler agressively resolving +#if !COMPILER(WINSCW) +#if !PLATFORM(QT) + #define REF_DEREF_INLINE ALWAYS_INLINE +#else + // Using ALWAYS_INLINE broke the Qt build. This may be a GCC bug. + // See https://bugs.webkit.org/show_bug.cgi?id=37253 for details. + #define REF_DEREF_INLINE inline +#endif +#else + // No inlining for WINSCW compiler to prevent the compiler agressively resolving // T::ref() and T::deref(), which will fail compiling when PassRefPtr<T> is used as // a class member or function arguments before T is defined. - template<typename T> -#if !COMPILER(WINSCW) - inline + #define REF_DEREF_INLINE #endif - void refIfNotNull(T* ptr) + + template<typename T> REF_DEREF_INLINE void refIfNotNull(T* ptr) { - if (UNLIKELY(ptr != 0)) + if (LIKELY(ptr != 0)) ptr->ref(); } - template<typename T> -#if !COMPILER(WINSCW) - inline -#endif - void derefIfNotNull(T* ptr) + template<typename T> REF_DEREF_INLINE void derefIfNotNull(T* ptr) { - if (UNLIKELY(ptr != 0)) + if (LIKELY(ptr != 0)) ptr->deref(); } + #undef REF_DEREF_INLINE + template<typename T> class PassRefPtr { public: - PassRefPtr() : m_ptr(0) {} + PassRefPtr() : m_ptr(0) { } PassRefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); } // It somewhat breaks the type system to allow transfer of ownership out of // a const PassRefPtr. However, it makes it much easier to work with PassRefPtr - // temporaries, and we don't really have a need to use real const PassRefPtrs - // anyway. - PassRefPtr(const PassRefPtr& o) : m_ptr(o.releaseRef()) {} - template <typename U> PassRefPtr(const PassRefPtr<U>& o) : m_ptr(o.releaseRef()) { } + // temporaries, and we don't have a need to use real const PassRefPtrs anyway. + PassRefPtr(const PassRefPtr& o) : m_ptr(o.leakRef()) { } + template<typename U> PassRefPtr(const PassRefPtr<U>& o) : m_ptr(o.leakRef()) { } ALWAYS_INLINE ~PassRefPtr() { derefIfNotNull(m_ptr); } - template <class U> - PassRefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { T* ptr = m_ptr; refIfNotNull(ptr); } + template<typename U> PassRefPtr(const RefPtr<U>&); T* get() const { return m_ptr; } - void clear() { T* ptr = m_ptr; derefIfNotNull(ptr); m_ptr = 0; } - T* releaseRef() const { T* tmp = m_ptr; m_ptr = 0; return tmp; } + void clear(); + T* leakRef() const WARN_UNUSED_RETURN; T& operator*() const { return *m_ptr; } T* operator->() const { return m_ptr; } - + bool operator!() const { return !m_ptr; } // This conversion operator allows implicit conversion to bool but not to other integer types. @@ -85,25 +91,31 @@ namespace WTF { PassRefPtr& operator=(T*); PassRefPtr& operator=(const PassRefPtr&); - template <typename U> PassRefPtr& operator=(const PassRefPtr<U>&); - template <typename U> PassRefPtr& operator=(const RefPtr<U>&); + PassRefPtr& operator=(std::nullptr_t) { clear(); return *this; } + template<typename U> PassRefPtr& operator=(const PassRefPtr<U>&); + template<typename U> PassRefPtr& operator=(const RefPtr<U>&); friend PassRefPtr adoptRef<T>(T*); + + // FIXME: Remove releaseRef once we change all callers to call leakRef instead. + T* releaseRef() const WARN_UNUSED_RETURN { return leakRef(); } + private: // adopting constructor - PassRefPtr(T* ptr, bool) : m_ptr(ptr) {} + PassRefPtr(T* ptr, bool) : m_ptr(ptr) { } + 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() + // begins life non-null, and can only become null through a call to leakRef() // 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 { + template<typename T> class NonNullPassRefPtr { public: NonNullPassRefPtr(T* ptr) : m_ptr(ptr) @@ -112,7 +124,7 @@ namespace WTF { m_ptr->ref(); } - template <class U> NonNullPassRefPtr(const RefPtr<U>& o) + template<typename U> NonNullPassRefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { ASSERT(m_ptr); @@ -120,19 +132,19 @@ namespace WTF { } NonNullPassRefPtr(const NonNullPassRefPtr& o) - : m_ptr(o.releaseRef()) + : m_ptr(o.leakRef()) { ASSERT(m_ptr); } - template <class U> NonNullPassRefPtr(const NonNullPassRefPtr<U>& o) - : m_ptr(o.releaseRef()) + template<typename U> NonNullPassRefPtr(const NonNullPassRefPtr<U>& o) + : m_ptr(o.leakRef()) { ASSERT(m_ptr); } - template <class U> NonNullPassRefPtr(const PassRefPtr<U>& o) - : m_ptr(o.releaseRef()) + template<typename U> NonNullPassRefPtr(const PassRefPtr<U>& o) + : m_ptr(o.leakRef()) { ASSERT(m_ptr); } @@ -141,17 +153,41 @@ namespace WTF { 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; } + void clear(); + T* leakRef() const WARN_UNUSED_RETURN { T* tmp = m_ptr; m_ptr = 0; return tmp; } T& operator*() const { return *m_ptr; } T* operator->() const { return m_ptr; } + // FIXME: Remove releaseRef once we change all callers to call leakRef instead. + T* releaseRef() const WARN_UNUSED_RETURN { return leakRef(); } + private: mutable T* m_ptr; }; - template <typename T> template <typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const RefPtr<U>& o) + template<typename T> template<typename U> inline PassRefPtr<T>::PassRefPtr(const RefPtr<U>& o) + : m_ptr(o.get()) + { + T* ptr = m_ptr; + refIfNotNull(ptr); + } + + template<typename T> inline void PassRefPtr<T>::clear() + { + T* ptr = m_ptr; + m_ptr = 0; + derefIfNotNull(ptr); + } + + template<typename T> inline T* PassRefPtr<T>::leakRef() const + { + T* ptr = m_ptr; + m_ptr = 0; + return ptr; + } + + template<typename T> template<typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const RefPtr<U>& o) { T* optr = o.get(); refIfNotNull(optr); @@ -161,7 +197,7 @@ namespace WTF { return *this; } - template <typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(T* optr) + template<typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(T* optr) { refIfNotNull(optr); T* ptr = m_ptr; @@ -170,92 +206,100 @@ namespace WTF { return *this; } - template <typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<T>& ref) + template<typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<T>& ref) { T* ptr = m_ptr; - m_ptr = ref.releaseRef(); + m_ptr = ref.leakRef(); derefIfNotNull(ptr); return *this; } - template <typename T> template <typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<U>& ref) + template<typename T> template<typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<U>& ref) { T* ptr = m_ptr; - m_ptr = ref.releaseRef(); + m_ptr = ref.leakRef(); derefIfNotNull(ptr); return *this; } - template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, const PassRefPtr<U>& b) + template<typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, const PassRefPtr<U>& b) { return a.get() == b.get(); } - template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, const RefPtr<U>& b) + template<typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, const RefPtr<U>& b) { return a.get() == b.get(); } - template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, const PassRefPtr<U>& b) + template<typename T, typename U> inline bool operator==(const RefPtr<T>& a, const PassRefPtr<U>& b) { return a.get() == b.get(); } - template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, U* b) + template<typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, U* b) { return a.get() == b; } - template <typename T, typename U> inline bool operator==(T* a, const PassRefPtr<U>& b) + template<typename T, typename U> inline bool operator==(T* a, const PassRefPtr<U>& b) { return a == b.get(); } - template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, const PassRefPtr<U>& b) + template<typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, const PassRefPtr<U>& b) { return a.get() != b.get(); } - template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, const RefPtr<U>& b) + template<typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, const RefPtr<U>& b) { return a.get() != b.get(); } - template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const PassRefPtr<U>& b) + template<typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const PassRefPtr<U>& b) { return a.get() != b.get(); } - template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, U* b) + template<typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, U* b) { return a.get() != b; } - template <typename T, typename U> inline bool operator!=(T* a, const PassRefPtr<U>& b) + template<typename T, typename U> inline bool operator!=(T* a, const PassRefPtr<U>& b) { return a != b.get(); } - template <typename T> inline PassRefPtr<T> adoptRef(T* p) + template<typename T> inline PassRefPtr<T> adoptRef(T* p) { + adopted(p); return PassRefPtr<T>(p, true); } - template <typename T, typename U> inline PassRefPtr<T> static_pointer_cast(const PassRefPtr<U>& p) + template<typename T, typename U> inline PassRefPtr<T> static_pointer_cast(const PassRefPtr<U>& p) { - return adoptRef(static_cast<T*>(p.releaseRef())); + return adoptRef(static_cast<T*>(p.leakRef())); } - template <typename T, typename U> inline PassRefPtr<T> const_pointer_cast(const PassRefPtr<U>& p) + template<typename T, typename U> inline PassRefPtr<T> const_pointer_cast(const PassRefPtr<U>& p) { - return adoptRef(const_cast<T*>(p.releaseRef())); + return adoptRef(const_cast<T*>(p.leakRef())); } - template <typename T> inline T* getPtr(const PassRefPtr<T>& p) + template<typename T> inline T* getPtr(const PassRefPtr<T>& p) { return p.get(); } + template<typename T> inline void NonNullPassRefPtr<T>::clear() + { + T* ptr = m_ptr; + m_ptr = 0; + derefIfNotNull(ptr); + } + } // namespace WTF using WTF::PassRefPtr; |
