2 * Copyright (C) 2013 Google, Inc. All Rights Reserved.
3 * Copyright (C) 2015, 2017 Apple Inc. All Rights Reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include <wtf/Noncopyable.h>
31 #include <wtf/ThreadSafeRefCounted.h>
32 #include <wtf/Threading.h>
36 // Testing interface for TestWebKitAPI
37 #ifndef DID_CREATE_WEAK_PTR_IMPL
38 #define DID_CREATE_WEAK_PTR_IMPL(p)
40 #ifndef WILL_DESTROY_WEAK_PTR_IMPL
41 #define WILL_DESTROY_WEAK_PTR_IMPL(p)
44 template<typename> class WeakHashSet;
45 template<typename> class WeakPtr;
46 template<typename> class WeakPtrFactory;
48 class WeakPtrImpl : public ThreadSafeRefCounted<WeakPtrImpl> {
49 WTF_MAKE_NONCOPYABLE(WeakPtrImpl);
50 WTF_MAKE_FAST_ALLOCATED;
52 template<typename T> static Ref<WeakPtrImpl> create(T* ptr)
54 return adoptRef(*new WeakPtrImpl(ptr));
59 WILL_DESTROY_WEAK_PTR_IMPL(m_ptr);
62 template<typename T> typename T::WeakValueType* get()
64 return static_cast<typename T::WeakValueType*>(m_ptr);
67 explicit operator bool() const { return m_ptr; }
68 void clear() { m_ptr = nullptr; }
71 template<typename T> explicit WeakPtrImpl(T* ptr)
72 : m_ptr(static_cast<typename T::WeakValueType*>(ptr))
74 DID_CREATE_WEAK_PTR_IMPL(ptr);
82 WTF_MAKE_FAST_ALLOCATED;
85 WeakPtr(std::nullptr_t) { }
86 template<typename U> WeakPtr(const WeakPtr<U>&);
87 template<typename U> WeakPtr(WeakPtr<U>&&);
89 T* get() const { return m_impl ? static_cast<T*>(m_impl->get<T>()) : nullptr; }
90 explicit operator bool() const { return m_impl && *m_impl; }
92 WeakPtr& operator=(std::nullptr_t) { m_impl = nullptr; return *this; }
93 template<typename U> WeakPtr& operator=(const WeakPtr<U>&);
94 template<typename U> WeakPtr& operator=(WeakPtr<U>&&);
96 T* operator->() const { return get(); }
97 T& operator*() const { return *get(); }
99 void clear() { m_impl = nullptr; }
102 explicit WeakPtr(Ref<WeakPtrImpl>&& ref) : m_impl(WTFMove(ref)) { }
103 template<typename> friend class WeakHashSet;
104 template<typename> friend class WeakPtr;
105 template<typename> friend class WeakPtrFactory;
106 template<typename U> friend WeakPtr<U> makeWeakPtr(U&);
108 RefPtr<WeakPtrImpl> m_impl;
111 // Note: you probably want to inherit from CanMakeWeakPtr rather than use this directly.
113 class WeakPtrFactory {
114 WTF_MAKE_NONCOPYABLE(WeakPtrFactory<T>);
115 WTF_MAKE_FAST_ALLOCATED;
117 WeakPtrFactory() = default;
125 WeakPtr<T> createWeakPtr(T& object) const
128 m_impl = WeakPtrImpl::create(&object);
130 ASSERT(&object == m_impl->get<T>());
131 return WeakPtr<T>(makeRef(*m_impl));
134 WeakPtr<const T> createWeakPtr(const T& object) const
137 m_impl = WeakPtrImpl::create(const_cast<T*>(&object));
139 ASSERT(&object == m_impl->get<T>());
140 return WeakPtr<T>(makeRef(*m_impl));
153 template<typename> friend class WeakHashSet;
155 mutable RefPtr<WeakPtrImpl> m_impl;
158 template<typename T> class CanMakeWeakPtr {
160 typedef T WeakValueType;
162 const WeakPtrFactory<T>& weakPtrFactory() const { return m_weakPtrFactory; }
163 WeakPtrFactory<T>& weakPtrFactory() { return m_weakPtrFactory; }
166 WeakPtrFactory<T> m_weakPtrFactory;
169 template<typename T, typename U> inline WeakPtrImpl* weak_ptr_impl_cast(WeakPtrImpl* impl)
171 static_assert(std::is_same<typename T::WeakValueType, typename U::WeakValueType>::value, "Invalid weak pointer cast");
175 template<typename T> template<typename U> inline WeakPtr<T>::WeakPtr(const WeakPtr<U>& o)
176 : m_impl(weak_ptr_impl_cast<T, U>(o.m_impl.get()))
180 template<typename T> template<typename U> inline WeakPtr<T>::WeakPtr(WeakPtr<U>&& o)
181 : m_impl(adoptRef(weak_ptr_impl_cast<T, U>(o.m_impl.leakRef())))
185 template<typename T> template<typename U> inline WeakPtr<T>& WeakPtr<T>::operator=(const WeakPtr<U>& o)
187 m_impl = weak_ptr_impl_cast<T, U>(o.m_impl.get());
191 template<typename T> template<typename U> inline WeakPtr<T>& WeakPtr<T>::operator=(WeakPtr<U>&& o)
193 m_impl = adoptRef(weak_ptr_impl_cast<T, U>(o.m_impl.leakRef()));
197 template<typename T> inline WeakPtr<T> makeWeakPtr(T& object)
199 return { object.weakPtrFactory().createWeakPtr(object) };
202 template<typename T> inline WeakPtr<T> makeWeakPtr(T* ptr)
206 return makeWeakPtr(*ptr);
209 template<typename T, typename U> inline bool operator==(const WeakPtr<T>& a, const WeakPtr<U>& b)
211 return a.get() == b.get();
214 template<typename T, typename U> inline bool operator==(const WeakPtr<T>& a, U* b)
219 template<typename T, typename U> inline bool operator==(T* a, const WeakPtr<U>& b)
224 template<typename T, typename U> inline bool operator!=(const WeakPtr<T>& a, const WeakPtr<U>& b)
226 return a.get() != b.get();
229 template<typename T, typename U> inline bool operator!=(const WeakPtr<T>& a, U* b)
234 template<typename T, typename U> inline bool operator!=(T* a, const WeakPtr<U>& b)
241 using WTF::CanMakeWeakPtr;
243 using WTF::WeakPtrFactory;
244 using WTF::makeWeakPtr;