Allow scoped_refptr to be used with absl nullability annotation

Bug: None
Change-Id: I6529e85b69e2430b8e57d7ac5f7842a4a74307b0
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/363821
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43094}
This commit is contained in:
Danil Chapovalov 2024-09-26 20:46:17 +02:00 committed by WebRTC LUCI CQ
parent 0af0c059f2
commit 3ae9578f4d
3 changed files with 24 additions and 62 deletions

View File

@ -464,6 +464,7 @@ rtc_source_set("ref_count") {
rtc_source_set("scoped_refptr") {
visibility = [ "*" ]
sources = [ "scoped_refptr.h" ]
deps = [ "//third_party/abseil-cpp/absl/base:nullability" ]
}
rtc_source_set("make_ref_counted") {
@ -473,6 +474,7 @@ rtc_source_set("make_ref_counted") {
":ref_count",
":scoped_refptr",
"../rtc_base:refcount",
"//third_party/abseil-cpp/absl/base:nullability",
]
}

View File

@ -13,6 +13,7 @@
#include <type_traits>
#include <utility>
#include "absl/base/nullability.h"
#include "api/ref_count.h"
#include "api/scoped_refptr.h"
#include "rtc_base/ref_counted_object.h"
@ -85,7 +86,7 @@ template <
typename std::enable_if<std::is_convertible_v<T*, RefCountInterface*> &&
std::is_abstract_v<T>,
T>::type* = nullptr>
scoped_refptr<T> make_ref_counted(Args&&... args) {
absl::Nonnull<scoped_refptr<T>> make_ref_counted(Args&&... args) {
return scoped_refptr<T>(new RefCountedObject<T>(std::forward<Args>(args)...));
}
@ -98,7 +99,7 @@ template <
!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) {
absl::Nonnull<scoped_refptr<T>> make_ref_counted(Args&&... args) {
return scoped_refptr<T>(new T(std::forward<Args>(args)...));
}
@ -112,61 +113,18 @@ template <
!webrtc_make_ref_counted_internal::HasAddRefAndRelease<T>::value,
T>::type* = nullptr>
scoped_refptr<FinalRefCountedObject<T>> make_ref_counted(Args&&... args) {
absl::Nonnull<scoped_refptr<FinalRefCountedObject<T>>> make_ref_counted(
Args&&... args) {
return scoped_refptr<FinalRefCountedObject<T>>(
new FinalRefCountedObject<T>(std::forward<Args>(args)...));
}
} // namespace webrtc
// Backwards compatibe aliases.
// TODO: https://issues.webrtc.org/42225969 - deprecate and remove.
namespace rtc {
// This doesn't work:
// template <typename T, typename... Args>
// using make_ref_counted(Args&&... args) =
// webrtc::make_ref_counted<T>(Args&&... args);
// Instead, reproduce the templates.
template <typename T,
typename... Args,
typename std::enable_if<
std::is_convertible_v<T*, webrtc::RefCountInterface*> &&
std::is_abstract_v<T>,
T>::type* = nullptr>
scoped_refptr<T> make_ref_counted(Args&&... args) {
return webrtc::scoped_refptr<T>(
new webrtc::RefCountedObject<T>(std::forward<Args>(args)...));
}
// `make_ref_counted` for complete classes that are not convertible to
// RefCountInterface and already carry a ref count.
template <typename T,
typename... Args,
typename std::enable_if<
!std::is_convertible_v<T*, webrtc::RefCountInterface*> &&
webrtc::webrtc_make_ref_counted_internal::HasAddRefAndRelease<
T>::value,
T>::type* = nullptr>
scoped_refptr<T> make_ref_counted(Args&&... args) {
return webrtc::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*, webrtc::RefCountInterface*> &&
!webrtc::webrtc_make_ref_counted_internal::
HasAddRefAndRelease<T>::value,
T>::type* = nullptr>
scoped_refptr<webrtc::FinalRefCountedObject<T>> make_ref_counted(
Args&&... args) {
return webrtc::scoped_refptr<FinalRefCountedObject<T>>(
new webrtc::FinalRefCountedObject<T>(std::forward<Args>(args)...));
}
// Backwards compatibe alias.
// TODO: bugs.webrtc.org/42225969 - deprecate and remove.
using ::webrtc::make_ref_counted;
} // namespace rtc
#endif // API_MAKE_REF_COUNTED_H_

View File

@ -22,13 +22,13 @@
// };
//
// void some_function() {
// scoped_refptr<MyFoo> foo = new MyFoo();
// scoped_refptr<MyFoo> foo = make_ref_counted<MyFoo>();
// foo->Method(param);
// // `foo` is released when this function returns
// }
//
// void some_other_function() {
// scoped_refptr<MyFoo> foo = new MyFoo();
// scoped_refptr<MyFoo> foo = make_ref_counted<MyFoo>();
// ...
// foo = nullptr; // explicitly releases `foo`
// ...
@ -41,7 +41,7 @@
// references between the two objects, like so:
//
// {
// scoped_refptr<MyFoo> a = new MyFoo();
// scoped_refptr<MyFoo> a = make_ref_counted<MyFoo>();
// scoped_refptr<MyFoo> b;
//
// b.swap(a);
@ -52,7 +52,7 @@
// object, simply use the assignment operator:
//
// {
// scoped_refptr<MyFoo> a = new MyFoo();
// scoped_refptr<MyFoo> a = make_ref_counted<MyFoo>();
// scoped_refptr<MyFoo> b;
//
// b = a;
@ -66,17 +66,20 @@
#include <cstddef>
#include <utility>
#include "absl/base/nullability.h"
namespace webrtc {
template <class T>
class scoped_refptr {
class ABSL_NULLABILITY_COMPATIBLE scoped_refptr {
public:
typedef T element_type;
using absl_nullability_compatible = void;
using element_type = T;
scoped_refptr() : ptr_(nullptr) {}
scoped_refptr(std::nullptr_t) : ptr_(nullptr) {} // NOLINT(runtime/explicit)
explicit scoped_refptr(T* p) : ptr_(p) {
explicit scoped_refptr(absl::Nullable<T*> p) : ptr_(p) {
if (ptr_)
ptr_->AddRef();
}
@ -119,7 +122,7 @@ class scoped_refptr {
return retVal;
}
scoped_refptr<T>& operator=(T* p) {
scoped_refptr<T>& operator=(absl::Nullable<T*> p) {
// AddRef first so that self assignment should work
if (p)
p->AddRef();
@ -149,7 +152,7 @@ class scoped_refptr {
return *this;
}
void swap(T** pp) noexcept {
void swap(absl::Nonnull<T**> pp) noexcept {
T* p = ptr_;
ptr_ = *pp;
*pp = p;
@ -219,9 +222,8 @@ bool operator<(const scoped_refptr<T>& a, const scoped_refptr<U>& b) {
namespace rtc {
// Backwards compatible alias.
// TODO(bugs.webrtc.org/15622): Deprecate and remove.
template <typename T>
using scoped_refptr = webrtc::scoped_refptr<T>;
// TODO: bugs.webrtc.org/42225969 - Deprecate and remove.
using ::webrtc::scoped_refptr;
} // namespace rtc
#endif // API_SCOPED_REFPTR_H_