webrtc/rtc_base/ref_counted_object.h
Danil Chapovalov 8df643b387 Introduce FinalRefCountedObject template class
To add ref counting to any class while avoiding
virtual functions for reference counting.
This template can both slightly reduce binary size
and slightly improve performance.

Bug: webrtc:11308
Change-Id: I90ac735f6c220ee2a1a991a71039acdb0ca86453
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/198845
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33058}
2021-01-22 16:20:22 +00:00

95 lines
3.1 KiB
C++

/*
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef RTC_BASE_REF_COUNTED_OBJECT_H_
#define RTC_BASE_REF_COUNTED_OBJECT_H_
#include <type_traits>
#include <utility>
#include "rtc_base/constructor_magic.h"
#include "rtc_base/ref_count.h"
#include "rtc_base/ref_counter.h"
namespace rtc {
template <class T>
class RefCountedObject : public T {
public:
RefCountedObject() {}
template <class P0>
explicit RefCountedObject(P0&& p0) : T(std::forward<P0>(p0)) {}
template <class P0, class P1, class... Args>
RefCountedObject(P0&& p0, P1&& p1, Args&&... args)
: T(std::forward<P0>(p0),
std::forward<P1>(p1),
std::forward<Args>(args)...) {}
virtual void AddRef() const { ref_count_.IncRef(); }
virtual RefCountReleaseStatus Release() const {
const auto status = ref_count_.DecRef();
if (status == RefCountReleaseStatus::kDroppedLastRef) {
delete this;
}
return status;
}
// Return whether the reference count is one. If the reference count is used
// in the conventional way, a reference count of 1 implies that the current
// thread owns the reference and no other thread shares it. This call
// performs the test for a reference count of one, and performs the memory
// barrier needed for the owning thread to act on the object, knowing that it
// has exclusive access to the object.
virtual bool HasOneRef() const { return ref_count_.HasOneRef(); }
protected:
virtual ~RefCountedObject() {}
mutable webrtc::webrtc_impl::RefCounter ref_count_{0};
RTC_DISALLOW_COPY_AND_ASSIGN(RefCountedObject);
};
template <class T>
class FinalRefCountedObject final : public T {
public:
using T::T;
// Until c++17 compilers are allowed not to inherit the default constructor,
// and msvc doesn't. Thus the default constructor is forwarded explicitly.
FinalRefCountedObject() = default;
FinalRefCountedObject(const FinalRefCountedObject&) = delete;
FinalRefCountedObject& operator=(const FinalRefCountedObject&) = delete;
void AddRef() const { ref_count_.IncRef(); }
void Release() const {
if (ref_count_.DecRef() == RefCountReleaseStatus::kDroppedLastRef) {
delete this;
}
}
bool HasOneRef() const { return ref_count_.HasOneRef(); }
private:
~FinalRefCountedObject() = default;
// gcc v7.1 requires default contructors for members of
// `FinalRefCountedObject` to be able to use inherited constructors.
// TODO(danilchap): Replace with simpler braced initialization when
// bot support for that version of gcc is dropped.
class ZeroBasedRefCounter : public webrtc::webrtc_impl::RefCounter {
public:
ZeroBasedRefCounter() : RefCounter(0) {}
} mutable ref_count_;
};
} // namespace rtc
#endif // RTC_BASE_REF_COUNTED_OBJECT_H_