1*6777b538SAndroid Build Coastguard Worker // Copyright 2017 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_MEMORY_SCOPED_REFPTR_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_MEMORY_SCOPED_REFPTR_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <stddef.h> 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #include <compare> 11*6777b538SAndroid Build Coastguard Worker #include <concepts> 12*6777b538SAndroid Build Coastguard Worker #include <iosfwd> 13*6777b538SAndroid Build Coastguard Worker #include <type_traits> 14*6777b538SAndroid Build Coastguard Worker #include <utility> 15*6777b538SAndroid Build Coastguard Worker 16*6777b538SAndroid Build Coastguard Worker #include "base/check.h" 17*6777b538SAndroid Build Coastguard Worker #include "base/compiler_specific.h" 18*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr_exclusion.h" 19*6777b538SAndroid Build Coastguard Worker 20*6777b538SAndroid Build Coastguard Worker template <class T> 21*6777b538SAndroid Build Coastguard Worker class scoped_refptr; 22*6777b538SAndroid Build Coastguard Worker 23*6777b538SAndroid Build Coastguard Worker namespace base { 24*6777b538SAndroid Build Coastguard Worker 25*6777b538SAndroid Build Coastguard Worker template <class, typename> 26*6777b538SAndroid Build Coastguard Worker class RefCounted; 27*6777b538SAndroid Build Coastguard Worker template <class, typename> 28*6777b538SAndroid Build Coastguard Worker class RefCountedThreadSafe; 29*6777b538SAndroid Build Coastguard Worker template <class> 30*6777b538SAndroid Build Coastguard Worker class RefCountedDeleteOnSequence; 31*6777b538SAndroid Build Coastguard Worker class SequencedTaskRunner; 32*6777b538SAndroid Build Coastguard Worker 33*6777b538SAndroid Build Coastguard Worker template <typename T> 34*6777b538SAndroid Build Coastguard Worker scoped_refptr<T> AdoptRef(T* t); 35*6777b538SAndroid Build Coastguard Worker 36*6777b538SAndroid Build Coastguard Worker namespace subtle { 37*6777b538SAndroid Build Coastguard Worker 38*6777b538SAndroid Build Coastguard Worker enum AdoptRefTag { kAdoptRefTag }; 39*6777b538SAndroid Build Coastguard Worker enum StartRefCountFromZeroTag { kStartRefCountFromZeroTag }; 40*6777b538SAndroid Build Coastguard Worker enum StartRefCountFromOneTag { kStartRefCountFromOneTag }; 41*6777b538SAndroid Build Coastguard Worker 42*6777b538SAndroid Build Coastguard Worker template <typename TagType> 43*6777b538SAndroid Build Coastguard Worker struct RefCountPreferenceTagTraits; 44*6777b538SAndroid Build Coastguard Worker 45*6777b538SAndroid Build Coastguard Worker template <> 46*6777b538SAndroid Build Coastguard Worker struct RefCountPreferenceTagTraits<StartRefCountFromZeroTag> { 47*6777b538SAndroid Build Coastguard Worker static constexpr StartRefCountFromZeroTag kTag = kStartRefCountFromZeroTag; 48*6777b538SAndroid Build Coastguard Worker }; 49*6777b538SAndroid Build Coastguard Worker 50*6777b538SAndroid Build Coastguard Worker template <> 51*6777b538SAndroid Build Coastguard Worker struct RefCountPreferenceTagTraits<StartRefCountFromOneTag> { 52*6777b538SAndroid Build Coastguard Worker static constexpr StartRefCountFromOneTag kTag = kStartRefCountFromOneTag; 53*6777b538SAndroid Build Coastguard Worker }; 54*6777b538SAndroid Build Coastguard Worker 55*6777b538SAndroid Build Coastguard Worker template <typename T, typename Tag = typename T::RefCountPreferenceTag> 56*6777b538SAndroid Build Coastguard Worker constexpr Tag GetRefCountPreference() { 57*6777b538SAndroid Build Coastguard Worker return RefCountPreferenceTagTraits<Tag>::kTag; 58*6777b538SAndroid Build Coastguard Worker } 59*6777b538SAndroid Build Coastguard Worker 60*6777b538SAndroid Build Coastguard Worker // scoped_refptr<T> is typically used with one of several RefCounted<T> base 61*6777b538SAndroid Build Coastguard Worker // classes or with custom AddRef and Release methods. These overloads dispatch 62*6777b538SAndroid Build Coastguard Worker // on which was used. 63*6777b538SAndroid Build Coastguard Worker 64*6777b538SAndroid Build Coastguard Worker template <typename T, typename U, typename V> 65*6777b538SAndroid Build Coastguard Worker constexpr bool IsRefCountPreferenceOverridden(const T*, 66*6777b538SAndroid Build Coastguard Worker const RefCounted<U, V>*) { 67*6777b538SAndroid Build Coastguard Worker return !std::same_as<std::decay_t<decltype(GetRefCountPreference<T>())>, 68*6777b538SAndroid Build Coastguard Worker std::decay_t<decltype(GetRefCountPreference<U>())>>; 69*6777b538SAndroid Build Coastguard Worker } 70*6777b538SAndroid Build Coastguard Worker 71*6777b538SAndroid Build Coastguard Worker template <typename T, typename U, typename V> 72*6777b538SAndroid Build Coastguard Worker constexpr bool IsRefCountPreferenceOverridden( 73*6777b538SAndroid Build Coastguard Worker const T*, 74*6777b538SAndroid Build Coastguard Worker const RefCountedThreadSafe<U, V>*) { 75*6777b538SAndroid Build Coastguard Worker return !std::same_as<std::decay_t<decltype(GetRefCountPreference<T>())>, 76*6777b538SAndroid Build Coastguard Worker std::decay_t<decltype(GetRefCountPreference<U>())>>; 77*6777b538SAndroid Build Coastguard Worker } 78*6777b538SAndroid Build Coastguard Worker 79*6777b538SAndroid Build Coastguard Worker template <typename T, typename U> 80*6777b538SAndroid Build Coastguard Worker constexpr bool IsRefCountPreferenceOverridden( 81*6777b538SAndroid Build Coastguard Worker const T*, 82*6777b538SAndroid Build Coastguard Worker const RefCountedDeleteOnSequence<U>*) { 83*6777b538SAndroid Build Coastguard Worker return !std::same_as<std::decay_t<decltype(GetRefCountPreference<T>())>, 84*6777b538SAndroid Build Coastguard Worker std::decay_t<decltype(GetRefCountPreference<U>())>>; 85*6777b538SAndroid Build Coastguard Worker } 86*6777b538SAndroid Build Coastguard Worker 87*6777b538SAndroid Build Coastguard Worker constexpr bool IsRefCountPreferenceOverridden(...) { 88*6777b538SAndroid Build Coastguard Worker return false; 89*6777b538SAndroid Build Coastguard Worker } 90*6777b538SAndroid Build Coastguard Worker 91*6777b538SAndroid Build Coastguard Worker template <typename T, typename U, typename V> 92*6777b538SAndroid Build Coastguard Worker constexpr void AssertRefCountBaseMatches(const T*, const RefCounted<U, V>*) { 93*6777b538SAndroid Build Coastguard Worker static_assert(std::derived_from<T, U>, 94*6777b538SAndroid Build Coastguard Worker "T implements RefCounted<U>, but U is not a base of T."); 95*6777b538SAndroid Build Coastguard Worker } 96*6777b538SAndroid Build Coastguard Worker 97*6777b538SAndroid Build Coastguard Worker template <typename T, typename U, typename V> 98*6777b538SAndroid Build Coastguard Worker constexpr void AssertRefCountBaseMatches(const T*, 99*6777b538SAndroid Build Coastguard Worker const RefCountedThreadSafe<U, V>*) { 100*6777b538SAndroid Build Coastguard Worker static_assert( 101*6777b538SAndroid Build Coastguard Worker std::derived_from<T, U>, 102*6777b538SAndroid Build Coastguard Worker "T implements RefCountedThreadSafe<U>, but U is not a base of T."); 103*6777b538SAndroid Build Coastguard Worker } 104*6777b538SAndroid Build Coastguard Worker 105*6777b538SAndroid Build Coastguard Worker template <typename T, typename U> 106*6777b538SAndroid Build Coastguard Worker constexpr void AssertRefCountBaseMatches(const T*, 107*6777b538SAndroid Build Coastguard Worker const RefCountedDeleteOnSequence<U>*) { 108*6777b538SAndroid Build Coastguard Worker static_assert( 109*6777b538SAndroid Build Coastguard Worker std::derived_from<T, U>, 110*6777b538SAndroid Build Coastguard Worker "T implements RefCountedDeleteOnSequence<U>, but U is not a base of T."); 111*6777b538SAndroid Build Coastguard Worker } 112*6777b538SAndroid Build Coastguard Worker 113*6777b538SAndroid Build Coastguard Worker constexpr void AssertRefCountBaseMatches(...) {} 114*6777b538SAndroid Build Coastguard Worker 115*6777b538SAndroid Build Coastguard Worker } // namespace subtle 116*6777b538SAndroid Build Coastguard Worker 117*6777b538SAndroid Build Coastguard Worker // Creates a scoped_refptr from a raw pointer without incrementing the reference 118*6777b538SAndroid Build Coastguard Worker // count. Use this only for a newly created object whose reference count starts 119*6777b538SAndroid Build Coastguard Worker // from 1 instead of 0. 120*6777b538SAndroid Build Coastguard Worker template <typename T> 121*6777b538SAndroid Build Coastguard Worker scoped_refptr<T> AdoptRef(T* obj) { 122*6777b538SAndroid Build Coastguard Worker using Tag = std::decay_t<decltype(subtle::GetRefCountPreference<T>())>; 123*6777b538SAndroid Build Coastguard Worker static_assert(std::same_as<subtle::StartRefCountFromOneTag, Tag>, 124*6777b538SAndroid Build Coastguard Worker "Use AdoptRef only if the reference count starts from one."); 125*6777b538SAndroid Build Coastguard Worker 126*6777b538SAndroid Build Coastguard Worker DCHECK(obj); 127*6777b538SAndroid Build Coastguard Worker DCHECK(obj->HasOneRef()); 128*6777b538SAndroid Build Coastguard Worker obj->Adopted(); 129*6777b538SAndroid Build Coastguard Worker return scoped_refptr<T>(obj, subtle::kAdoptRefTag); 130*6777b538SAndroid Build Coastguard Worker } 131*6777b538SAndroid Build Coastguard Worker 132*6777b538SAndroid Build Coastguard Worker namespace subtle { 133*6777b538SAndroid Build Coastguard Worker 134*6777b538SAndroid Build Coastguard Worker template <typename T> 135*6777b538SAndroid Build Coastguard Worker scoped_refptr<T> AdoptRefIfNeeded(T* obj, StartRefCountFromZeroTag) { 136*6777b538SAndroid Build Coastguard Worker return scoped_refptr<T>(obj); 137*6777b538SAndroid Build Coastguard Worker } 138*6777b538SAndroid Build Coastguard Worker 139*6777b538SAndroid Build Coastguard Worker template <typename T> 140*6777b538SAndroid Build Coastguard Worker scoped_refptr<T> AdoptRefIfNeeded(T* obj, StartRefCountFromOneTag) { 141*6777b538SAndroid Build Coastguard Worker return AdoptRef(obj); 142*6777b538SAndroid Build Coastguard Worker } 143*6777b538SAndroid Build Coastguard Worker 144*6777b538SAndroid Build Coastguard Worker } // namespace subtle 145*6777b538SAndroid Build Coastguard Worker 146*6777b538SAndroid Build Coastguard Worker // Constructs an instance of T, which is a ref counted type, and wraps the 147*6777b538SAndroid Build Coastguard Worker // object into a scoped_refptr<T>. 148*6777b538SAndroid Build Coastguard Worker template <typename T, typename... Args> 149*6777b538SAndroid Build Coastguard Worker scoped_refptr<T> MakeRefCounted(Args&&... args) { 150*6777b538SAndroid Build Coastguard Worker T* obj = new T(std::forward<Args>(args)...); 151*6777b538SAndroid Build Coastguard Worker return subtle::AdoptRefIfNeeded(obj, subtle::GetRefCountPreference<T>()); 152*6777b538SAndroid Build Coastguard Worker } 153*6777b538SAndroid Build Coastguard Worker 154*6777b538SAndroid Build Coastguard Worker // Takes an instance of T, which is a ref counted type, and wraps the object 155*6777b538SAndroid Build Coastguard Worker // into a scoped_refptr<T>. 156*6777b538SAndroid Build Coastguard Worker template <typename T> 157*6777b538SAndroid Build Coastguard Worker scoped_refptr<T> WrapRefCounted(T* t) { 158*6777b538SAndroid Build Coastguard Worker return scoped_refptr<T>(t); 159*6777b538SAndroid Build Coastguard Worker } 160*6777b538SAndroid Build Coastguard Worker 161*6777b538SAndroid Build Coastguard Worker } // namespace base 162*6777b538SAndroid Build Coastguard Worker 163*6777b538SAndroid Build Coastguard Worker // 164*6777b538SAndroid Build Coastguard Worker // A smart pointer class for reference counted objects. Use this class instead 165*6777b538SAndroid Build Coastguard Worker // of calling AddRef and Release manually on a reference counted object to 166*6777b538SAndroid Build Coastguard Worker // avoid common memory leaks caused by forgetting to Release an object 167*6777b538SAndroid Build Coastguard Worker // reference. Sample usage: 168*6777b538SAndroid Build Coastguard Worker // 169*6777b538SAndroid Build Coastguard Worker // class MyFoo : public RefCounted<MyFoo> { 170*6777b538SAndroid Build Coastguard Worker // ... 171*6777b538SAndroid Build Coastguard Worker // private: 172*6777b538SAndroid Build Coastguard Worker // friend class RefCounted<MyFoo>; // Allow destruction by RefCounted<>. 173*6777b538SAndroid Build Coastguard Worker // ~MyFoo(); // Destructor must be private/protected. 174*6777b538SAndroid Build Coastguard Worker // }; 175*6777b538SAndroid Build Coastguard Worker // 176*6777b538SAndroid Build Coastguard Worker // void some_function() { 177*6777b538SAndroid Build Coastguard Worker // scoped_refptr<MyFoo> foo = MakeRefCounted<MyFoo>(); 178*6777b538SAndroid Build Coastguard Worker // foo->Method(param); 179*6777b538SAndroid Build Coastguard Worker // // |foo| is released when this function returns 180*6777b538SAndroid Build Coastguard Worker // } 181*6777b538SAndroid Build Coastguard Worker // 182*6777b538SAndroid Build Coastguard Worker // void some_other_function() { 183*6777b538SAndroid Build Coastguard Worker // scoped_refptr<MyFoo> foo = MakeRefCounted<MyFoo>(); 184*6777b538SAndroid Build Coastguard Worker // ... 185*6777b538SAndroid Build Coastguard Worker // foo.reset(); // explicitly releases |foo| 186*6777b538SAndroid Build Coastguard Worker // ... 187*6777b538SAndroid Build Coastguard Worker // if (foo) 188*6777b538SAndroid Build Coastguard Worker // foo->Method(param); 189*6777b538SAndroid Build Coastguard Worker // } 190*6777b538SAndroid Build Coastguard Worker // 191*6777b538SAndroid Build Coastguard Worker // The above examples show how scoped_refptr<T> acts like a pointer to T. 192*6777b538SAndroid Build Coastguard Worker // Given two scoped_refptr<T> classes, it is also possible to exchange 193*6777b538SAndroid Build Coastguard Worker // references between the two objects, like so: 194*6777b538SAndroid Build Coastguard Worker // 195*6777b538SAndroid Build Coastguard Worker // { 196*6777b538SAndroid Build Coastguard Worker // scoped_refptr<MyFoo> a = MakeRefCounted<MyFoo>(); 197*6777b538SAndroid Build Coastguard Worker // scoped_refptr<MyFoo> b; 198*6777b538SAndroid Build Coastguard Worker // 199*6777b538SAndroid Build Coastguard Worker // b.swap(a); 200*6777b538SAndroid Build Coastguard Worker // // now, |b| references the MyFoo object, and |a| references nullptr. 201*6777b538SAndroid Build Coastguard Worker // } 202*6777b538SAndroid Build Coastguard Worker // 203*6777b538SAndroid Build Coastguard Worker // To make both |a| and |b| in the above example reference the same MyFoo 204*6777b538SAndroid Build Coastguard Worker // object, simply use the assignment operator: 205*6777b538SAndroid Build Coastguard Worker // 206*6777b538SAndroid Build Coastguard Worker // { 207*6777b538SAndroid Build Coastguard Worker // scoped_refptr<MyFoo> a = MakeRefCounted<MyFoo>(); 208*6777b538SAndroid Build Coastguard Worker // scoped_refptr<MyFoo> b; 209*6777b538SAndroid Build Coastguard Worker // 210*6777b538SAndroid Build Coastguard Worker // b = a; 211*6777b538SAndroid Build Coastguard Worker // // now, |a| and |b| each own a reference to the same MyFoo object. 212*6777b538SAndroid Build Coastguard Worker // } 213*6777b538SAndroid Build Coastguard Worker // 214*6777b538SAndroid Build Coastguard Worker // Also see Chromium's ownership and calling conventions: 215*6777b538SAndroid Build Coastguard Worker // https://chromium.googlesource.com/chromium/src/+/lkgr/styleguide/c++/c++.md#object-ownership-and-calling-conventions 216*6777b538SAndroid Build Coastguard Worker // Specifically: 217*6777b538SAndroid Build Coastguard Worker // If the function (at least sometimes) takes a ref on a refcounted object, 218*6777b538SAndroid Build Coastguard Worker // declare the param as scoped_refptr<T>. The caller can decide whether it 219*6777b538SAndroid Build Coastguard Worker // wishes to transfer ownership (by calling std::move(t) when passing t) or 220*6777b538SAndroid Build Coastguard Worker // retain its ref (by simply passing t directly). 221*6777b538SAndroid Build Coastguard Worker // In other words, use scoped_refptr like you would a std::unique_ptr except 222*6777b538SAndroid Build Coastguard Worker // in the odd case where it's required to hold on to a ref while handing one 223*6777b538SAndroid Build Coastguard Worker // to another component (if a component merely needs to use t on the stack 224*6777b538SAndroid Build Coastguard Worker // without keeping a ref: pass t as a raw T*). 225*6777b538SAndroid Build Coastguard Worker template <class T> 226*6777b538SAndroid Build Coastguard Worker class TRIVIAL_ABI scoped_refptr { 227*6777b538SAndroid Build Coastguard Worker public: 228*6777b538SAndroid Build Coastguard Worker typedef T element_type; 229*6777b538SAndroid Build Coastguard Worker 230*6777b538SAndroid Build Coastguard Worker constexpr scoped_refptr() = default; 231*6777b538SAndroid Build Coastguard Worker 232*6777b538SAndroid Build Coastguard Worker // Allow implicit construction from nullptr. 233*6777b538SAndroid Build Coastguard Worker constexpr scoped_refptr(std::nullptr_t) {} 234*6777b538SAndroid Build Coastguard Worker 235*6777b538SAndroid Build Coastguard Worker // Constructs from a raw pointer. Note that this constructor allows implicit 236*6777b538SAndroid Build Coastguard Worker // conversion from T* to scoped_refptr<T> which is strongly discouraged. If 237*6777b538SAndroid Build Coastguard Worker // you are creating a new ref-counted object please use 238*6777b538SAndroid Build Coastguard Worker // base::MakeRefCounted<T>() or base::WrapRefCounted<T>(). Otherwise you 239*6777b538SAndroid Build Coastguard Worker // should move or copy construct from an existing scoped_refptr<T> to the 240*6777b538SAndroid Build Coastguard Worker // ref-counted object. 241*6777b538SAndroid Build Coastguard Worker scoped_refptr(T* p) : ptr_(p) { 242*6777b538SAndroid Build Coastguard Worker if (ptr_) 243*6777b538SAndroid Build Coastguard Worker AddRef(ptr_); 244*6777b538SAndroid Build Coastguard Worker } 245*6777b538SAndroid Build Coastguard Worker 246*6777b538SAndroid Build Coastguard Worker // Copy constructor. This is required in addition to the copy conversion 247*6777b538SAndroid Build Coastguard Worker // constructor below. 248*6777b538SAndroid Build Coastguard Worker scoped_refptr(const scoped_refptr& r) : scoped_refptr(r.ptr_) {} 249*6777b538SAndroid Build Coastguard Worker 250*6777b538SAndroid Build Coastguard Worker // Copy conversion constructor. 251*6777b538SAndroid Build Coastguard Worker template <typename U> 252*6777b538SAndroid Build Coastguard Worker requires(std::convertible_to<U*, T*>) 253*6777b538SAndroid Build Coastguard Worker scoped_refptr(const scoped_refptr<U>& r) : scoped_refptr(r.ptr_) {} 254*6777b538SAndroid Build Coastguard Worker 255*6777b538SAndroid Build Coastguard Worker // Move constructor. This is required in addition to the move conversion 256*6777b538SAndroid Build Coastguard Worker // constructor below. 257*6777b538SAndroid Build Coastguard Worker scoped_refptr(scoped_refptr&& r) noexcept : ptr_(r.ptr_) { r.ptr_ = nullptr; } 258*6777b538SAndroid Build Coastguard Worker 259*6777b538SAndroid Build Coastguard Worker // Move conversion constructor. 260*6777b538SAndroid Build Coastguard Worker template <typename U> 261*6777b538SAndroid Build Coastguard Worker requires(std::convertible_to<U*, T*>) 262*6777b538SAndroid Build Coastguard Worker scoped_refptr(scoped_refptr<U>&& r) noexcept : ptr_(r.ptr_) { 263*6777b538SAndroid Build Coastguard Worker r.ptr_ = nullptr; 264*6777b538SAndroid Build Coastguard Worker } 265*6777b538SAndroid Build Coastguard Worker 266*6777b538SAndroid Build Coastguard Worker ~scoped_refptr() { 267*6777b538SAndroid Build Coastguard Worker static_assert(!base::subtle::IsRefCountPreferenceOverridden( 268*6777b538SAndroid Build Coastguard Worker static_cast<T*>(nullptr), static_cast<T*>(nullptr)), 269*6777b538SAndroid Build Coastguard Worker "It's unsafe to override the ref count preference." 270*6777b538SAndroid Build Coastguard Worker " Please remove REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE" 271*6777b538SAndroid Build Coastguard Worker " from subclasses."); 272*6777b538SAndroid Build Coastguard Worker if (ptr_) 273*6777b538SAndroid Build Coastguard Worker Release(ptr_); 274*6777b538SAndroid Build Coastguard Worker } 275*6777b538SAndroid Build Coastguard Worker 276*6777b538SAndroid Build Coastguard Worker T* get() const { return ptr_; } 277*6777b538SAndroid Build Coastguard Worker 278*6777b538SAndroid Build Coastguard Worker T& operator*() const { 279*6777b538SAndroid Build Coastguard Worker DCHECK(ptr_); 280*6777b538SAndroid Build Coastguard Worker return *ptr_; 281*6777b538SAndroid Build Coastguard Worker } 282*6777b538SAndroid Build Coastguard Worker 283*6777b538SAndroid Build Coastguard Worker T* operator->() const { 284*6777b538SAndroid Build Coastguard Worker DCHECK(ptr_); 285*6777b538SAndroid Build Coastguard Worker return ptr_; 286*6777b538SAndroid Build Coastguard Worker } 287*6777b538SAndroid Build Coastguard Worker 288*6777b538SAndroid Build Coastguard Worker scoped_refptr& operator=(std::nullptr_t) { 289*6777b538SAndroid Build Coastguard Worker reset(); 290*6777b538SAndroid Build Coastguard Worker return *this; 291*6777b538SAndroid Build Coastguard Worker } 292*6777b538SAndroid Build Coastguard Worker 293*6777b538SAndroid Build Coastguard Worker scoped_refptr& operator=(T* p) { return *this = scoped_refptr(p); } 294*6777b538SAndroid Build Coastguard Worker 295*6777b538SAndroid Build Coastguard Worker // Unified assignment operator. 296*6777b538SAndroid Build Coastguard Worker scoped_refptr& operator=(scoped_refptr r) noexcept { 297*6777b538SAndroid Build Coastguard Worker swap(r); 298*6777b538SAndroid Build Coastguard Worker return *this; 299*6777b538SAndroid Build Coastguard Worker } 300*6777b538SAndroid Build Coastguard Worker 301*6777b538SAndroid Build Coastguard Worker // Sets managed object to null and releases reference to the previous managed 302*6777b538SAndroid Build Coastguard Worker // object, if it existed. 303*6777b538SAndroid Build Coastguard Worker void reset() { scoped_refptr().swap(*this); } 304*6777b538SAndroid Build Coastguard Worker 305*6777b538SAndroid Build Coastguard Worker // Returns the owned pointer (if any), releasing ownership to the caller. The 306*6777b538SAndroid Build Coastguard Worker // caller is responsible for managing the lifetime of the reference. 307*6777b538SAndroid Build Coastguard Worker [[nodiscard]] T* release(); 308*6777b538SAndroid Build Coastguard Worker 309*6777b538SAndroid Build Coastguard Worker void swap(scoped_refptr& r) noexcept { std::swap(ptr_, r.ptr_); } 310*6777b538SAndroid Build Coastguard Worker 311*6777b538SAndroid Build Coastguard Worker explicit operator bool() const { return ptr_ != nullptr; } 312*6777b538SAndroid Build Coastguard Worker 313*6777b538SAndroid Build Coastguard Worker template <typename U> 314*6777b538SAndroid Build Coastguard Worker friend bool operator==(const scoped_refptr<T>& lhs, 315*6777b538SAndroid Build Coastguard Worker const scoped_refptr<U>& rhs) { 316*6777b538SAndroid Build Coastguard Worker return lhs.ptr_ == rhs.ptr_; 317*6777b538SAndroid Build Coastguard Worker } 318*6777b538SAndroid Build Coastguard Worker 319*6777b538SAndroid Build Coastguard Worker // This operator is an optimization to avoid implicitly constructing a 320*6777b538SAndroid Build Coastguard Worker // scoped_refptr<U> when comparing scoped_refptr against raw pointer. If the 321*6777b538SAndroid Build Coastguard Worker // implicit conversion is ever removed this operator can also be removed. 322*6777b538SAndroid Build Coastguard Worker template <typename U> 323*6777b538SAndroid Build Coastguard Worker friend bool operator==(const scoped_refptr<T>& lhs, const U* rhs) { 324*6777b538SAndroid Build Coastguard Worker return lhs.ptr_ == rhs; 325*6777b538SAndroid Build Coastguard Worker } 326*6777b538SAndroid Build Coastguard Worker 327*6777b538SAndroid Build Coastguard Worker friend bool operator==(const scoped_refptr<T>& lhs, std::nullptr_t null) { 328*6777b538SAndroid Build Coastguard Worker return !static_cast<bool>(lhs); 329*6777b538SAndroid Build Coastguard Worker } 330*6777b538SAndroid Build Coastguard Worker 331*6777b538SAndroid Build Coastguard Worker template <typename U> 332*6777b538SAndroid Build Coastguard Worker friend auto operator<=>(const scoped_refptr<T>& lhs, 333*6777b538SAndroid Build Coastguard Worker const scoped_refptr<U>& rhs) { 334*6777b538SAndroid Build Coastguard Worker return lhs.ptr_ <=> rhs.ptr_; 335*6777b538SAndroid Build Coastguard Worker } 336*6777b538SAndroid Build Coastguard Worker 337*6777b538SAndroid Build Coastguard Worker friend auto operator<=>(const scoped_refptr<T>& lhs, std::nullptr_t null) { 338*6777b538SAndroid Build Coastguard Worker return lhs.ptr_ <=> static_cast<T*>(nullptr); 339*6777b538SAndroid Build Coastguard Worker } 340*6777b538SAndroid Build Coastguard Worker 341*6777b538SAndroid Build Coastguard Worker protected: 342*6777b538SAndroid Build Coastguard Worker // RAW_PTR_EXCLUSION: scoped_refptr<> has its own UaF prevention mechanism. 343*6777b538SAndroid Build Coastguard Worker // Given how widespread it is, we it'll likely a perf regression for no 344*6777b538SAndroid Build Coastguard Worker // additional security benefit. 345*6777b538SAndroid Build Coastguard Worker RAW_PTR_EXCLUSION T* ptr_ = nullptr; 346*6777b538SAndroid Build Coastguard Worker 347*6777b538SAndroid Build Coastguard Worker private: 348*6777b538SAndroid Build Coastguard Worker template <typename U> 349*6777b538SAndroid Build Coastguard Worker friend scoped_refptr<U> base::AdoptRef(U*); 350*6777b538SAndroid Build Coastguard Worker friend class ::base::SequencedTaskRunner; 351*6777b538SAndroid Build Coastguard Worker 352*6777b538SAndroid Build Coastguard Worker scoped_refptr(T* p, base::subtle::AdoptRefTag) : ptr_(p) {} 353*6777b538SAndroid Build Coastguard Worker 354*6777b538SAndroid Build Coastguard Worker // Friend required for move constructors that set r.ptr_ to null. 355*6777b538SAndroid Build Coastguard Worker template <typename U> 356*6777b538SAndroid Build Coastguard Worker friend class scoped_refptr; 357*6777b538SAndroid Build Coastguard Worker 358*6777b538SAndroid Build Coastguard Worker // Non-inline helpers to allow: 359*6777b538SAndroid Build Coastguard Worker // class Opaque; 360*6777b538SAndroid Build Coastguard Worker // extern template class scoped_refptr<Opaque>; 361*6777b538SAndroid Build Coastguard Worker // Otherwise the compiler will complain that Opaque is an incomplete type. 362*6777b538SAndroid Build Coastguard Worker static void AddRef(T* ptr); 363*6777b538SAndroid Build Coastguard Worker static void Release(T* ptr); 364*6777b538SAndroid Build Coastguard Worker }; 365*6777b538SAndroid Build Coastguard Worker 366*6777b538SAndroid Build Coastguard Worker template <typename T> 367*6777b538SAndroid Build Coastguard Worker T* scoped_refptr<T>::release() { 368*6777b538SAndroid Build Coastguard Worker T* ptr = ptr_; 369*6777b538SAndroid Build Coastguard Worker ptr_ = nullptr; 370*6777b538SAndroid Build Coastguard Worker return ptr; 371*6777b538SAndroid Build Coastguard Worker } 372*6777b538SAndroid Build Coastguard Worker 373*6777b538SAndroid Build Coastguard Worker // static 374*6777b538SAndroid Build Coastguard Worker template <typename T> 375*6777b538SAndroid Build Coastguard Worker void scoped_refptr<T>::AddRef(T* ptr) { 376*6777b538SAndroid Build Coastguard Worker base::subtle::AssertRefCountBaseMatches(ptr, ptr); 377*6777b538SAndroid Build Coastguard Worker ptr->AddRef(); 378*6777b538SAndroid Build Coastguard Worker } 379*6777b538SAndroid Build Coastguard Worker 380*6777b538SAndroid Build Coastguard Worker // static 381*6777b538SAndroid Build Coastguard Worker template <typename T> 382*6777b538SAndroid Build Coastguard Worker void scoped_refptr<T>::Release(T* ptr) { 383*6777b538SAndroid Build Coastguard Worker base::subtle::AssertRefCountBaseMatches(ptr, ptr); 384*6777b538SAndroid Build Coastguard Worker ptr->Release(); 385*6777b538SAndroid Build Coastguard Worker } 386*6777b538SAndroid Build Coastguard Worker 387*6777b538SAndroid Build Coastguard Worker template <typename T> 388*6777b538SAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& out, const scoped_refptr<T>& p) { 389*6777b538SAndroid Build Coastguard Worker return out << p.get(); 390*6777b538SAndroid Build Coastguard Worker } 391*6777b538SAndroid Build Coastguard Worker 392*6777b538SAndroid Build Coastguard Worker template <typename T> 393*6777b538SAndroid Build Coastguard Worker void swap(scoped_refptr<T>& lhs, scoped_refptr<T>& rhs) noexcept { 394*6777b538SAndroid Build Coastguard Worker lhs.swap(rhs); 395*6777b538SAndroid Build Coastguard Worker } 396*6777b538SAndroid Build Coastguard Worker 397*6777b538SAndroid Build Coastguard Worker #endif // BASE_MEMORY_SCOPED_REFPTR_H_ 398