Skip to content

Commit cdf0e8a

Browse files
committed
Weak ref smart pointer check should be smarter
https://bugs.webkit.org/show_bug.cgi?id=273594 rdar://127395924 Reviewed by Chris Dumez. Improved the SFINAE usage to account for const/non-const overload. Moved the static_assert to dereference operations so that WeakPtr<T> can be more like T* in its support for forward declaration. Now you don't need the full type definition available in order to destroy a WeakPtr<T>; only to dereference one. * Source/WTF/wtf/TypeTraits.h: * Source/WTF/wtf/WeakPtr.h: (WTF::WeakPtr::releaseImpl): (WTF::WeakPtr::get const): (WTF::WeakPtr::operator-> const): (WTF::WeakPtr::operator* const): (WTF::WeakPtr::~WeakPtr): Deleted. * Source/WTF/wtf/WeakRef.h: (WTF::WeakRef::ptrAllowingHashTableEmptyValue const): (WTF::WeakRef::ptr const): (WTF::WeakRef::get const): (WTF::WeakRef::~WeakRef): Deleted. Canonical link: https://commits.webkit.org/278249@main
1 parent 75ca801 commit cdf0e8a

3 files changed

Lines changed: 27 additions & 16 deletions

File tree

Source/WTF/wtf/TypeTraits.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ template<typename>
107107
struct SFINAE1True : std::true_type { };
108108

109109
template<class T>
110-
static auto HasRefPtrMethodsTest(SFINAE_OVERLOAD_PREFERRED) -> SFINAE1True<decltype(&T::ref, &T::deref)>;
110+
static auto HasRefPtrMethodsTest(SFINAE_OVERLOAD_PREFERRED) -> SFINAE1True<decltype(static_cast<std::remove_cv_t<T>*>(nullptr)->ref(), static_cast<std::remove_cv_t<T>*>(nullptr)->deref())>;
111111
template<class>
112112
static auto HasRefPtrMethodsTest(SFINAE_OVERLOAD_DEFAULT) -> std::false_type;
113113

@@ -120,7 +120,7 @@ struct HasRefPtrMethods : decltype(detail::HasRefPtrMethodsTest<T>(SFINAE_OVERLO
120120
namespace detail {
121121

122122
template<class T>
123-
static auto HasCheckedPtrMethodsTest(SFINAE_OVERLOAD_PREFERRED) -> SFINAE1True<decltype(&T::incrementPtrCount, &T::decrementPtrCount)>;
123+
static auto HasCheckedPtrMethodsTest(SFINAE_OVERLOAD_PREFERRED) -> SFINAE1True<decltype(static_cast<std::remove_cv_t<T>*>(nullptr)->incrementPtrCount(), static_cast<std::remove_cv_t<T>*>(nullptr)->decrementPtrCount())>;
124124
template<class>
125125
static auto HasCheckedPtrMethodsTest(SFINAE_OVERLOAD_DEFAULT) -> std::false_type;
126126

Source/WTF/wtf/WeakPtr.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,14 @@ template<typename T, typename WeakPtrImpl, typename PtrTraits> class WeakPtr {
8383
{
8484
}
8585

86-
~WeakPtr()
87-
{
88-
static_assert(
89-
HasRefPtrMethods<T>::value || HasCheckedPtrMethods<T>::value || IsDeprecatedWeakRefSmartPointerException<std::remove_const_t<T>>::value,
90-
"Classes that offer weak pointers should also offer RefPtr or CheckedPtr.");
91-
}
92-
9386
RefPtr<WeakPtrImpl, PtrTraits> releaseImpl() { return WTFMove(m_impl); }
9487

9588
T* get() const
9689
{
90+
static_assert(
91+
HasRefPtrMethods<T>::value || HasCheckedPtrMethods<T>::value || IsDeprecatedWeakRefSmartPointerException<std::remove_cv_t<T>>::value,
92+
"Classes that offer weak pointers should also offer RefPtr or CheckedPtr. Please do not add new exceptions.");
93+
9794
ASSERT(canSafelyBeUsed());
9895
return m_impl ? static_cast<T*>(m_impl->template get<T>()) : nullptr;
9996
}
@@ -114,12 +111,20 @@ template<typename T, typename WeakPtrImpl, typename PtrTraits> class WeakPtr {
114111

115112
T* operator->() const
116113
{
114+
static_assert(
115+
HasRefPtrMethods<T>::value || HasCheckedPtrMethods<T>::value || IsDeprecatedWeakRefSmartPointerException<std::remove_cv_t<T>>::value,
116+
"Classes that offer weak pointers should also offer RefPtr or CheckedPtr. Please do not add new exceptions.");
117+
117118
ASSERT(canSafelyBeUsed());
118119
return get();
119120
}
120121

121122
T& operator*() const
122123
{
124+
static_assert(
125+
HasRefPtrMethods<T>::value || HasCheckedPtrMethods<T>::value || IsDeprecatedWeakRefSmartPointerException<std::remove_cv_t<T>>::value,
126+
"Classes that offer weak pointers should also offer RefPtr or CheckedPtr. Please do not add new exceptions.");
127+
123128
ASSERT(canSafelyBeUsed());
124129
return *get();
125130
}

Source/WTF/wtf/WeakRef.h

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,6 @@ class WeakRef {
6767
WeakRef(HashTableDeletedValueType) : m_impl(HashTableDeletedValue) { }
6868
WeakRef(HashTableEmptyValueType) : m_impl(HashTableEmptyValue) { }
6969

70-
~WeakRef()
71-
{
72-
static_assert(
73-
HasRefPtrMethods<T>::value || HasCheckedPtrMethods<T>::value || IsDeprecatedWeakRefSmartPointerException<std::remove_const_t<T>>::value,
74-
"Classes that offer weak pointers should also offer RefPtr or CheckedPtr. Please do not add new exceptions.");
75-
}
76-
7770
bool isHashTableDeletedValue() const { return m_impl.isHashTableDeletedValue(); }
7871
bool isHashTableEmptyValue() const { return m_impl.isHashTableEmptyValue(); }
7972

@@ -82,22 +75,35 @@ class WeakRef {
8275

8376
T* ptrAllowingHashTableEmptyValue() const
8477
{
78+
static_assert(
79+
HasRefPtrMethods<T>::value || HasCheckedPtrMethods<T>::value || IsDeprecatedWeakRefSmartPointerException<std::remove_cv_t<T>>::value,
80+
"Classes that offer weak pointers should also offer RefPtr or CheckedPtr. Please do not add new exceptions.");
81+
8582
return !m_impl.isHashTableEmptyValue() ? static_cast<T*>(m_impl->template get<T>()) : nullptr;
8683
}
8784

8885
T* ptr() const
8986
{
87+
static_assert(
88+
HasRefPtrMethods<T>::value || HasCheckedPtrMethods<T>::value || IsDeprecatedWeakRefSmartPointerException<std::remove_cv_t<T>>::value,
89+
"Classes that offer weak pointers should also offer RefPtr or CheckedPtr. Please do not add new exceptions.");
90+
9091
auto* ptr = static_cast<T*>(m_impl->template get<T>());
9192
ASSERT(ptr);
9293
return ptr;
9394
}
9495

9596
T& get() const
9697
{
98+
static_assert(
99+
HasRefPtrMethods<T>::value || HasCheckedPtrMethods<T>::value || IsDeprecatedWeakRefSmartPointerException<std::remove_cv_t<T>>::value,
100+
"Classes that offer weak pointers should also offer RefPtr or CheckedPtr. Please do not add new exceptions.");
101+
97102
auto* ptr = static_cast<T*>(m_impl->template get<T>());
98103
ASSERT(ptr);
99104
return *ptr;
100105
}
106+
101107
operator T&() const { return get(); }
102108

103109
T* operator->() const

0 commit comments

Comments
 (0)