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