xref: /aosp_15_r20/external/cronet/base/memory/scoped_refptr.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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