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