diff options
Diffstat (limited to 'Source/WTF/wtf/WeakPtr.h')
-rw-r--r-- | Source/WTF/wtf/WeakPtr.h | 84 |
1 files changed, 55 insertions, 29 deletions
diff --git a/Source/WTF/wtf/WeakPtr.h b/Source/WTF/wtf/WeakPtr.h index 97da507aa..f15160bec 100644 --- a/Source/WTF/wtf/WeakPtr.h +++ b/Source/WTF/wtf/WeakPtr.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 Google, Inc. All Rights Reserved. + * Copyright (C) 2015 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,8 +28,7 @@ #define WTF_WeakPtr_h #include <wtf/Noncopyable.h> -#include <wtf/PassRefPtr.h> -#include <wtf/RefPtr.h> +#include <wtf/Ref.h> #include <wtf/ThreadSafeRefCounted.h> #include <wtf/Threading.h> @@ -38,14 +38,15 @@ namespace WTF { +template<typename T> class WeakPtr; +template<typename T> class WeakPtrFactory; + +// Note: WeakReference is an implementation detail, and should not be used directly. template<typename T> class WeakReference : public ThreadSafeRefCounted<WeakReference<T>> { WTF_MAKE_NONCOPYABLE(WeakReference<T>); WTF_MAKE_FAST_ALLOCATED; public: - static PassRefPtr<WeakReference<T>> create(T* ptr) { return adoptRef(new WeakReference(ptr)); } - static PassRefPtr<WeakReference<T>> createUnbound() { return adoptRef(new WeakReference()); } - T* get() const { #if USE(WEB_THREAD) @@ -63,20 +64,14 @@ public: #else ASSERT(m_boundThread == currentThread()); #endif - m_ptr = 0; - } - - void bindTo(T* ptr) - { - ASSERT(!m_ptr); -#ifndef NDEBUG - m_boundThread = currentThread(); -#endif - m_ptr = ptr; + m_ptr = nullptr; } private: - WeakReference() : m_ptr(0) { } + friend class WeakPtr<T>; + friend class WeakPtrFactory<T>; + + static Ref<WeakReference<T>> create(T* ptr) { return adoptRef(*new WeakReference(ptr)); } explicit WeakReference(T* ptr) : m_ptr(ptr) @@ -96,18 +91,25 @@ template<typename T> class WeakPtr { WTF_MAKE_FAST_ALLOCATED; public: - WeakPtr() { } - WeakPtr(PassRefPtr<WeakReference<T>> ref) : m_ref(ref) { } + WeakPtr() : m_ref(WeakReference<T>::create(nullptr)) { } + WeakPtr(const WeakPtr& o) : m_ref(o.m_ref.copyRef()) { } + template<typename U> WeakPtr(const WeakPtr<U>& o) : m_ref(o.m_ref.copyRef()) { } T* get() const { return m_ref->get(); } - explicit operator bool() const { return m_ref->get(); } + operator bool() const { return m_ref->get(); } + + WeakPtr& operator=(const WeakPtr& o) { m_ref = o.m_ref.copyRef(); return *this; } + WeakPtr& operator=(std::nullptr_t) { m_ref = WeakReference<T>::create(nullptr); return *this; } T* operator->() const { return m_ref->get(); } - WeakPtr& operator=(std::nullptr_t) { m_ref = WeakReference<T>::create(nullptr); return *this; } + void clear() { m_ref = WeakReference<T>::create(nullptr); } private: - RefPtr<WeakReference<T>> m_ref; + friend class WeakPtrFactory<T>; + WeakPtr(Ref<WeakReference<T>>&& ref) : m_ref(std::forward<Ref<WeakReference<T>>>(ref)) { } + + Ref<WeakReference<T>> m_ref; }; template<typename T> @@ -117,16 +119,10 @@ class WeakPtrFactory { public: explicit WeakPtrFactory(T* ptr) : m_ref(WeakReference<T>::create(ptr)) { } - WeakPtrFactory(PassRefPtr<WeakReference<T>> ref, T* ptr) - : m_ref(ref) - { - m_ref->bindTo(ptr); - } - ~WeakPtrFactory() { m_ref->clear(); } // We should consider having createWeakPtr populate m_ref the first time createWeakPtr is called. - WeakPtr<T> createWeakPtr() { return WeakPtr<T>(m_ref); } + WeakPtr<T> createWeakPtr() const { return WeakPtr<T>(m_ref.copyRef()); } void revokeAll() { @@ -137,9 +133,39 @@ public: } private: - RefPtr<WeakReference<T>> m_ref; + Ref<WeakReference<T>> m_ref; }; +template<typename T, typename U> inline bool operator==(const WeakPtr<T>& a, const WeakPtr<U>& b) +{ + return a.get() == b.get(); +} + +template<typename T, typename U> inline bool operator==(const WeakPtr<T>& a, U* b) +{ + return a.get() == b; +} + +template<typename T, typename U> inline bool operator==(T* a, const WeakPtr<U>& b) +{ + return a == b.get(); +} + +template<typename T, typename U> inline bool operator!=(const WeakPtr<T>& a, const WeakPtr<U>& b) +{ + return a.get() != b.get(); +} + +template<typename T, typename U> inline bool operator!=(const WeakPtr<T>& a, U* b) +{ + return a.get() != b; +} + +template<typename T, typename U> inline bool operator!=(T* a, const WeakPtr<U>& b) +{ + return a != b.get(); +} + } // namespace WTF using WTF::WeakPtr; |