blob: 931cb207625de453ea6d052455ec2bdcbce04f64 [file] [log] [blame]
Niels Möller9155e492017-10-23 11:22:30 +02001/*
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 */
Steve Anton10542f22019-01-11 09:11:00 -080010#ifndef API_REF_COUNTED_BASE_H_
11#define API_REF_COUNTED_BASE_H_
Niels Möller9155e492017-10-23 11:22:30 +020012
Tommi86ee89f2021-04-20 16:58:01 +020013#include <type_traits>
14
Steve Anton10542f22019-01-11 09:11:00 -080015#include "rtc_base/constructor_magic.h"
Steve Anton10542f22019-01-11 09:11:00 -080016#include "rtc_base/ref_counter.h"
Niels Möller9155e492017-10-23 11:22:30 +020017
18namespace rtc {
19
20class RefCountedBase {
21 public:
22 RefCountedBase() = default;
23
24 void AddRef() const { ref_count_.IncRef(); }
25 RefCountReleaseStatus Release() const {
26 const auto status = ref_count_.DecRef();
27 if (status == RefCountReleaseStatus::kDroppedLastRef) {
28 delete this;
29 }
30 return status;
31 }
32
33 protected:
Tomas Gunnarssone249d192021-04-26 11:46:54 +020034 // Provided for internal webrtc subclasses for corner cases where it's
35 // necessary to know whether or not a reference is exclusively held.
36 bool HasOneRef() const { return ref_count_.HasOneRef(); }
37
Niels Möller9155e492017-10-23 11:22:30 +020038 virtual ~RefCountedBase() = default;
39
40 private:
41 mutable webrtc::webrtc_impl::RefCounter ref_count_{0};
42
43 RTC_DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
44};
45
Tommi86ee89f2021-04-20 16:58:01 +020046// 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.
59template <typename T>
60class RefCountedNonVirtual {
61 public:
62 RefCountedNonVirtual() = default;
63
64 void AddRef() const { ref_count_.IncRef(); }
65 RefCountReleaseStatus Release() const {
66 // If you run into this assert, T has virtual methods. There are two
67 // options:
68 // 1) The class doesn't actually need virtual methods, the type is complete
69 // so the virtual attribute(s) can be removed.
70 // 2) The virtual methods are a part of the design of the class. In this
71 // case you can consider using `RefCountedBase` instead or alternatively
72 // use `rtc::RefCountedObject`.
73 static_assert(!std::is_polymorphic<T>::value,
74 "T has virtual methods. RefCountedBase is a better fit.");
75 const auto status = ref_count_.DecRef();
76 if (status == RefCountReleaseStatus::kDroppedLastRef) {
77 delete static_cast<const T*>(this);
78 }
79 return status;
80 }
81
82 protected:
Tomas Gunnarssone249d192021-04-26 11:46:54 +020083 // Provided for internal webrtc subclasses for corner cases where it's
84 // necessary to know whether or not a reference is exclusively held.
85 bool HasOneRef() const { return ref_count_.HasOneRef(); }
86
Tommi86ee89f2021-04-20 16:58:01 +020087 ~RefCountedNonVirtual() = default;
88
89 private:
90 mutable webrtc::webrtc_impl::RefCounter ref_count_{0};
91
92 RTC_DISALLOW_COPY_AND_ASSIGN(RefCountedNonVirtual);
93};
94
Niels Möller9155e492017-10-23 11:22:30 +020095} // namespace rtc
96
Steve Anton10542f22019-01-11 09:11:00 -080097#endif // API_REF_COUNTED_BASE_H_