xref: /aosp_15_r20/external/webrtc/api/ref_counted_base.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright 2017 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 #ifndef API_REF_COUNTED_BASE_H_
11 #define API_REF_COUNTED_BASE_H_
12 
13 #include <type_traits>
14 
15 #include "rtc_base/ref_counter.h"
16 
17 namespace rtc {
18 
19 class RefCountedBase {
20  public:
21   RefCountedBase() = default;
22 
23   RefCountedBase(const RefCountedBase&) = delete;
24   RefCountedBase& operator=(const RefCountedBase&) = delete;
25 
AddRef()26   void AddRef() const { ref_count_.IncRef(); }
Release()27   RefCountReleaseStatus Release() const {
28     const auto status = ref_count_.DecRef();
29     if (status == RefCountReleaseStatus::kDroppedLastRef) {
30       delete this;
31     }
32     return status;
33   }
34 
35  protected:
36   // Provided for internal webrtc subclasses for corner cases where it's
37   // necessary to know whether or not a reference is exclusively held.
HasOneRef()38   bool HasOneRef() const { return ref_count_.HasOneRef(); }
39 
40   virtual ~RefCountedBase() = default;
41 
42  private:
43   mutable webrtc::webrtc_impl::RefCounter ref_count_{0};
44 };
45 
46 // Template based version of `RefCountedBase` for simple implementations that do
47 // not need (or want) destruction via virtual destructor or the overhead of a
48 // vtable.
49 //
50 // To use:
51 //   struct MyInt : public rtc::RefCountedNonVirtual<MyInt>  {
52 //     int foo_ = 0;
53 //   };
54 //
55 //   rtc::scoped_refptr<MyInt> my_int(new MyInt());
56 //
57 // sizeof(MyInt) on a 32 bit system would then be 8, int + refcount and no
58 // vtable generated.
59 template <typename T>
60 class RefCountedNonVirtual {
61  public:
62   RefCountedNonVirtual() = default;
63 
64   RefCountedNonVirtual(const RefCountedNonVirtual&) = delete;
65   RefCountedNonVirtual& operator=(const RefCountedNonVirtual&) = delete;
66 
AddRef()67   void AddRef() const { ref_count_.IncRef(); }
Release()68   RefCountReleaseStatus Release() const {
69     // If you run into this assert, T has virtual methods. There are two
70     // options:
71     // 1) The class doesn't actually need virtual methods, the type is complete
72     //    so the virtual attribute(s) can be removed.
73     // 2) The virtual methods are a part of the design of the class. In this
74     //    case you can consider using `RefCountedBase` instead or alternatively
75     //    use `rtc::RefCountedObject`.
76     static_assert(!std::is_polymorphic<T>::value,
77                   "T has virtual methods. RefCountedBase is a better fit.");
78     const auto status = ref_count_.DecRef();
79     if (status == RefCountReleaseStatus::kDroppedLastRef) {
80       delete static_cast<const T*>(this);
81     }
82     return status;
83   }
84 
85  protected:
86   // Provided for internal webrtc subclasses for corner cases where it's
87   // necessary to know whether or not a reference is exclusively held.
HasOneRef()88   bool HasOneRef() const { return ref_count_.HasOneRef(); }
89 
90   ~RefCountedNonVirtual() = default;
91 
92  private:
93   mutable webrtc::webrtc_impl::RefCounter ref_count_{0};
94 };
95 
96 }  // namespace rtc
97 
98 #endif  // API_REF_COUNTED_BASE_H_
99