blob: f20228b74046389bbf5b3ab95d1409414bad002b [file] [log] [blame]
Niels Möller9155e492017-10-23 09:22:301/*
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 17:11:0010#ifndef API_REF_COUNTED_BASE_H_
11#define API_REF_COUNTED_BASE_H_
Niels Möller9155e492017-10-23 09:22:3012
Tommi86ee89f2021-04-20 14:58:0113#include <type_traits>
14
Steve Anton10542f22019-01-11 17:11:0015#include "rtc_base/ref_counter.h"
Niels Möller9155e492017-10-23 09:22:3016
17namespace rtc {
18
19class RefCountedBase {
20 public:
21 RefCountedBase() = default;
22
Byoungchan Leec065e732022-01-18 00:35:4823 RefCountedBase(const RefCountedBase&) = delete;
24 RefCountedBase& operator=(const RefCountedBase&) = delete;
25
Niels Möller9155e492017-10-23 09:22:3026 void AddRef() const { ref_count_.IncRef(); }
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:
Tomas Gunnarssone249d192021-04-26 09:46:5436 // Provided for internal webrtc subclasses for corner cases where it's
37 // necessary to know whether or not a reference is exclusively held.
38 bool HasOneRef() const { return ref_count_.HasOneRef(); }
39
Niels Möller9155e492017-10-23 09:22:3040 virtual ~RefCountedBase() = default;
41
42 private:
43 mutable webrtc::webrtc_impl::RefCounter ref_count_{0};
Niels Möller9155e492017-10-23 09:22:3044};
45
Tommi86ee89f2021-04-20 14:58:0146// 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
Byoungchan Leec065e732022-01-18 00:35:4864 RefCountedNonVirtual(const RefCountedNonVirtual&) = delete;
65 RefCountedNonVirtual& operator=(const RefCountedNonVirtual&) = delete;
66
Tommi86ee89f2021-04-20 14:58:0167 void AddRef() const { ref_count_.IncRef(); }
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:
Tomas Gunnarssone249d192021-04-26 09:46:5486 // Provided for internal webrtc subclasses for corner cases where it's
87 // necessary to know whether or not a reference is exclusively held.
88 bool HasOneRef() const { return ref_count_.HasOneRef(); }
89
Tommi86ee89f2021-04-20 14:58:0190 ~RefCountedNonVirtual() = default;
91
92 private:
93 mutable webrtc::webrtc_impl::RefCounter ref_count_{0};
Tommi86ee89f2021-04-20 14:58:0194};
95
Niels Möller9155e492017-10-23 09:22:3096} // namespace rtc
97
Steve Anton10542f22019-01-11 17:11:0098#endif // API_REF_COUNTED_BASE_H_