summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2021-04-08 19:00:31 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-04-08 19:00:31 +0000
commitdebdf364bdcf1470bc702100bc9fe492d8e02081 (patch)
tree0c351677a50cbc34409f8ab62bbd82a8ab597441
parentd792f77c1218be39b1bef52bb04a21645dd27fa4 (diff)
parent25d87e44191ff4307d7b719b5b8edd80fd2d6896 (diff)
downloadcore-debdf364bdcf1470bc702100bc9fe492d8e02081.tar.gz
Merge changes I66c97386,Id205c88d am: 05a7dfa104 am: 25d87e4419
Original change: https://android-review.googlesource.com/c/platform/system/core/+/1668805 Change-Id: I3b48cc428b332122b8e445eef9b9e1e23152e9e2
-rw-r--r--libutils/RefBase_test.cpp4
-rw-r--r--libutils/include/utils/RefBase.h1
-rw-r--r--libutils/include/utils/StrongPointer.h12
3 files changed, 15 insertions, 2 deletions
diff --git a/libutils/RefBase_test.cpp b/libutils/RefBase_test.cpp
index dcc469e48..93f9654b1 100644
--- a/libutils/RefBase_test.cpp
+++ b/libutils/RefBase_test.cpp
@@ -242,12 +242,12 @@ TEST(RefBase, ReplacedComparison) {
}
TEST(RefBase, AssertWeakRefExistsSuccess) {
- // uses some other refcounting method, or non at all
bool isDeleted;
sp<Foo> foo = sp<Foo>::make(&isDeleted);
wp<Foo> weakFoo = foo;
EXPECT_EQ(weakFoo, wp<Foo>::fromExisting(foo.get()));
+ EXPECT_EQ(weakFoo.unsafe_get(), wp<Foo>::fromExisting(foo.get()).unsafe_get());
EXPECT_FALSE(isDeleted);
foo = nullptr;
@@ -255,7 +255,7 @@ TEST(RefBase, AssertWeakRefExistsSuccess) {
}
TEST(RefBase, AssertWeakRefExistsDeath) {
- // uses some other refcounting method, or non at all
+ // uses some other refcounting method, or none at all
bool isDeleted;
Foo* foo = new Foo(&isDeleted);
diff --git a/libutils/include/utils/RefBase.h b/libutils/include/utils/RefBase.h
index 5a5bd56e5..714894924 100644
--- a/libutils/include/utils/RefBase.h
+++ b/libutils/include/utils/RefBase.h
@@ -547,6 +547,7 @@ wp<T> wp<T>::fromExisting(T* other) {
refs->incWeakRequireWeak(other);
wp<T> ret;
+ ret.m_ptr = other;
ret.m_refs = refs;
return ret;
}
diff --git a/libutils/include/utils/StrongPointer.h b/libutils/include/utils/StrongPointer.h
index 1f070524a..dd53b9ec0 100644
--- a/libutils/include/utils/StrongPointer.h
+++ b/libutils/include/utils/StrongPointer.h
@@ -72,6 +72,12 @@ public:
template<typename U> sp(const sp<U>& other); // NOLINT(implicit)
template<typename U> sp(sp<U>&& other); // NOLINT(implicit)
+ // Cast a strong pointer directly from one type to another. Constructors
+ // allow changing types, but only if they are pointer-compatible. This does
+ // a static_cast internally.
+ template <typename U>
+ static inline sp<T> cast(const sp<U>& other);
+
~sp();
// Assignment
@@ -279,6 +285,12 @@ sp<T>::sp(sp<U>&& other)
other.m_ptr = nullptr;
}
+template <typename T>
+template <typename U>
+sp<T> sp<T>::cast(const sp<U>& other) {
+ return sp<T>::fromExisting(static_cast<T*>(other.get()));
+}
+
template<typename T>
sp<T>::~sp() {
if (m_ptr)