Extend make_ref_counted to interoperate with RefCountedNonVirtual
Update RtpPacketInfos internals to use rtc::make_ref_counted, and a Data class with no virtual methods. Bug: webrtc:13464, webrtc:12701 Change-Id: I03f6bee69a9f060dcf287284fc779268d5eb433e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/244505 Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org> Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/main@{#35660}
This commit is contained in:
parent
b82193cec8
commit
bb57de2959
3
api/DEPS
3
api/DEPS
@ -168,6 +168,9 @@ specific_include_rules = {
|
|||||||
# For private member and constructor.
|
# For private member and constructor.
|
||||||
"+rtc_base/system/file_wrapper.h",
|
"+rtc_base/system/file_wrapper.h",
|
||||||
],
|
],
|
||||||
|
"rtp_packet_infos\.h": [
|
||||||
|
"+rtc_base/ref_counted_object.h",
|
||||||
|
],
|
||||||
"rtp_receiver_interface\.h": [
|
"rtp_receiver_interface\.h": [
|
||||||
"+rtc_base/ref_count.h",
|
"+rtc_base/ref_count.h",
|
||||||
],
|
],
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
#include "api/ref_counted_base.h"
|
#include "api/ref_counted_base.h"
|
||||||
#include "api/rtp_packet_info.h"
|
#include "api/rtp_packet_info.h"
|
||||||
#include "api/scoped_refptr.h"
|
#include "api/scoped_refptr.h"
|
||||||
|
#include "rtc_base/ref_counted_object.h"
|
||||||
#include "rtc_base/system/rtc_export.h"
|
#include "rtc_base/system/rtc_export.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -79,7 +80,7 @@ class RTC_EXPORT RtpPacketInfos {
|
|||||||
size_type size() const { return entries().size(); }
|
size_type size() const { return entries().size(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Data : public rtc::RefCountedBase {
|
class Data final : public rtc::RefCountedNonVirtual<Data> {
|
||||||
public:
|
public:
|
||||||
static rtc::scoped_refptr<Data> Create(const vector_type& entries) {
|
static rtc::scoped_refptr<Data> Create(const vector_type& entries) {
|
||||||
// Performance optimization for the empty case.
|
// Performance optimization for the empty case.
|
||||||
@ -87,7 +88,7 @@ class RTC_EXPORT RtpPacketInfos {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Data(entries);
|
return rtc::make_ref_counted<Data>(entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
static rtc::scoped_refptr<Data> Create(vector_type&& entries) {
|
static rtc::scoped_refptr<Data> Create(vector_type&& entries) {
|
||||||
@ -96,16 +97,16 @@ class RTC_EXPORT RtpPacketInfos {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Data(std::move(entries));
|
return rtc::make_ref_counted<Data>(std::move(entries));
|
||||||
}
|
}
|
||||||
|
|
||||||
const vector_type& entries() const { return entries_; }
|
const vector_type& entries() const { return entries_; }
|
||||||
|
|
||||||
private:
|
|
||||||
explicit Data(const vector_type& entries) : entries_(entries) {}
|
explicit Data(const vector_type& entries) : entries_(entries) {}
|
||||||
explicit Data(vector_type&& entries) : entries_(std::move(entries)) {}
|
explicit Data(vector_type&& entries) : entries_(std::move(entries)) {}
|
||||||
~Data() override {}
|
~Data() = default;
|
||||||
|
|
||||||
|
private:
|
||||||
const vector_type entries_;
|
const vector_type entries_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,23 @@
|
|||||||
|
|
||||||
namespace rtc {
|
namespace rtc {
|
||||||
|
|
||||||
|
namespace webrtc_make_ref_counted_internal {
|
||||||
|
// Determines if the given class has AddRef and Release methods.
|
||||||
|
template <typename T>
|
||||||
|
class HasAddRefAndRelease {
|
||||||
|
private:
|
||||||
|
template <typename C,
|
||||||
|
decltype(std::declval<C>().AddRef())* = nullptr,
|
||||||
|
decltype(std::declval<C>().Release())* = nullptr>
|
||||||
|
static int Test(int);
|
||||||
|
template <typename>
|
||||||
|
static char Test(...);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr bool value = std::is_same_v<decltype(Test<T>(0)), int>;
|
||||||
|
};
|
||||||
|
} // namespace webrtc_make_ref_counted_internal
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class RefCountedObject : public T {
|
class RefCountedObject : public T {
|
||||||
public:
|
public:
|
||||||
@ -64,10 +81,9 @@ template <class T>
|
|||||||
class FinalRefCountedObject final : public T {
|
class FinalRefCountedObject final : public T {
|
||||||
public:
|
public:
|
||||||
using T::T;
|
using T::T;
|
||||||
// Until c++17 compilers are allowed not to inherit the default constructors.
|
// Above using declaration propagates a default move constructor
|
||||||
// Thus the default constructors are forwarded explicitly.
|
// FinalRefCountedObject(FinalRefCountedObject&& other), but we also need
|
||||||
FinalRefCountedObject() = default;
|
// move construction from T.
|
||||||
explicit FinalRefCountedObject(const T& other) : T(other) {}
|
|
||||||
explicit FinalRefCountedObject(T&& other) : T(std::move(other)) {}
|
explicit FinalRefCountedObject(T&& other) : T(std::move(other)) {}
|
||||||
FinalRefCountedObject(const FinalRefCountedObject&) = delete;
|
FinalRefCountedObject(const FinalRefCountedObject&) = delete;
|
||||||
FinalRefCountedObject& operator=(const FinalRefCountedObject&) = delete;
|
FinalRefCountedObject& operator=(const FinalRefCountedObject&) = delete;
|
||||||
@ -106,8 +122,13 @@ class FinalRefCountedObject final : public T {
|
|||||||
//
|
//
|
||||||
// auto p = scoped_refptr<Foo>(new RefCountedObject<Foo>("bar", 123));
|
// auto p = scoped_refptr<Foo>(new RefCountedObject<Foo>("bar", 123));
|
||||||
//
|
//
|
||||||
// If the class does not inherit from RefCountInterface, the example is
|
// If the class does not inherit from RefCountInterface, but does have
|
||||||
// equivalent to:
|
// AddRef/Release methods (so a T* is convertible to rtc::scoped_refptr), this
|
||||||
|
// is equivalent to just
|
||||||
|
//
|
||||||
|
// auto p = scoped_refptr<Foo>(new Foo("bar", 123));
|
||||||
|
//
|
||||||
|
// Otherwise, the example is equivalent to:
|
||||||
//
|
//
|
||||||
// auto p = scoped_refptr<FinalRefCountedObject<Foo>>(
|
// auto p = scoped_refptr<FinalRefCountedObject<Foo>>(
|
||||||
// new FinalRefCountedObject<Foo>("bar", 123));
|
// new FinalRefCountedObject<Foo>("bar", 123));
|
||||||
@ -122,22 +143,37 @@ class FinalRefCountedObject final : public T {
|
|||||||
// needed.
|
// needed.
|
||||||
|
|
||||||
// `make_ref_counted` for classes that are convertible to RefCountInterface.
|
// `make_ref_counted` for classes that are convertible to RefCountInterface.
|
||||||
template <
|
template <typename T,
|
||||||
typename T,
|
typename... Args,
|
||||||
typename... Args,
|
typename std::enable_if<std::is_convertible_v<T*, RefCountInterface*>,
|
||||||
typename std::enable_if<std::is_convertible<T*, RefCountInterface*>::value,
|
T>::type* = nullptr>
|
||||||
T>::type* = nullptr>
|
|
||||||
scoped_refptr<T> make_ref_counted(Args&&... args) {
|
scoped_refptr<T> make_ref_counted(Args&&... args) {
|
||||||
return new RefCountedObject<T>(std::forward<Args>(args)...);
|
return new RefCountedObject<T>(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
// `make_ref_counted` for complete classes that are not convertible to
|
// `make_ref_counted` for complete classes that are not convertible to
|
||||||
// RefCountInterface.
|
// RefCountInterface and already carry a ref count.
|
||||||
template <
|
template <
|
||||||
typename T,
|
typename T,
|
||||||
typename... Args,
|
typename... Args,
|
||||||
typename std::enable_if<!std::is_convertible<T*, RefCountInterface*>::value,
|
typename std::enable_if<
|
||||||
T>::type* = nullptr>
|
!std::is_convertible_v<T*, RefCountInterface*> &&
|
||||||
|
webrtc_make_ref_counted_internal::HasAddRefAndRelease<T>::value,
|
||||||
|
T>::type* = nullptr>
|
||||||
|
scoped_refptr<T> make_ref_counted(Args&&... args) {
|
||||||
|
return scoped_refptr<T>(new T(std::forward<Args>(args)...));
|
||||||
|
}
|
||||||
|
|
||||||
|
// `make_ref_counted` for complete classes that are not convertible to
|
||||||
|
// RefCountInterface and have no ref count of their own.
|
||||||
|
template <
|
||||||
|
typename T,
|
||||||
|
typename... Args,
|
||||||
|
typename std::enable_if<
|
||||||
|
!std::is_convertible_v<T*, RefCountInterface*> &&
|
||||||
|
!webrtc_make_ref_counted_internal::HasAddRefAndRelease<T>::value,
|
||||||
|
|
||||||
|
T>::type* = nullptr>
|
||||||
scoped_refptr<FinalRefCountedObject<T>> make_ref_counted(Args&&... args) {
|
scoped_refptr<FinalRefCountedObject<T>> make_ref_counted(Args&&... args) {
|
||||||
return new FinalRefCountedObject<T>(std::forward<Args>(args)...);
|
return new FinalRefCountedObject<T>(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
@ -188,7 +224,7 @@ scoped_refptr<FinalRefCountedObject<T>> make_ref_counted(Args&&... args) {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct Ref {
|
struct Ref {
|
||||||
typedef typename std::conditional<
|
typedef typename std::conditional<
|
||||||
std::is_convertible<T*, RefCountInterface*>::value,
|
webrtc_make_ref_counted_internal::HasAddRefAndRelease<T>::value,
|
||||||
T,
|
T,
|
||||||
FinalRefCountedObject<T>>::type Type;
|
FinalRefCountedObject<T>>::type Type;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user