blob: 238765be899c77b37fe762b0b9f75ad054eda853 [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:
34 virtual ~RefCountedBase() = default;
35
36 private:
37 mutable webrtc::webrtc_impl::RefCounter ref_count_{0};
38
39 RTC_DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
40};
41
Tommi86ee89f2021-04-20 16:58:01 +020042// Template based version of `RefCountedBase` for simple implementations that do
43// not need (or want) destruction via virtual destructor or the overhead of a
44// vtable.
45//
46// To use:
47// struct MyInt : public rtc::RefCountedNonVirtual<MyInt> {
48// int foo_ = 0;
49// };
50//
51// rtc::scoped_refptr<MyInt> my_int(new MyInt());
52//
53// sizeof(MyInt) on a 32 bit system would then be 8, int + refcount and no
54// vtable generated.
55template <typename T>
56class RefCountedNonVirtual {
57 public:
58 RefCountedNonVirtual() = default;
59
60 void AddRef() const { ref_count_.IncRef(); }
61 RefCountReleaseStatus Release() const {
62 // If you run into this assert, T has virtual methods. There are two
63 // options:
64 // 1) The class doesn't actually need virtual methods, the type is complete
65 // so the virtual attribute(s) can be removed.
66 // 2) The virtual methods are a part of the design of the class. In this
67 // case you can consider using `RefCountedBase` instead or alternatively
68 // use `rtc::RefCountedObject`.
69 static_assert(!std::is_polymorphic<T>::value,
70 "T has virtual methods. RefCountedBase is a better fit.");
71 const auto status = ref_count_.DecRef();
72 if (status == RefCountReleaseStatus::kDroppedLastRef) {
73 delete static_cast<const T*>(this);
74 }
75 return status;
76 }
77
78 protected:
79 ~RefCountedNonVirtual() = default;
80
81 private:
82 mutable webrtc::webrtc_impl::RefCounter ref_count_{0};
83
84 RTC_DISALLOW_COPY_AND_ASSIGN(RefCountedNonVirtual);
85};
86
Niels Möller9155e492017-10-23 11:22:30 +020087} // namespace rtc
88
Steve Anton10542f22019-01-11 09:11:00 -080089#endif // API_REF_COUNTED_BASE_H_