aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkRefCnt.h10
-rw-r--r--tests/RefCntTest.cpp27
2 files changed, 36 insertions, 1 deletions
diff --git a/include/core/SkRefCnt.h b/include/core/SkRefCnt.h
index cea72cda66..9e8f3be61c 100644
--- a/include/core/SkRefCnt.h
+++ b/include/core/SkRefCnt.h
@@ -238,6 +238,8 @@ private:
* may have its ref/unref be thread-safe, but that is not assumed/imposed by sk_sp.
*/
template <typename T> class sk_sp {
+ /** Supports safe bool idiom. Obsolete with explicit operator bool. */
+ using unspecified_bool_type = T* sk_sp::*;
public:
sk_sp() : fPtr(nullptr) {}
sk_sp(std::nullptr_t) : fPtr(nullptr) {}
@@ -316,10 +318,16 @@ public:
template <typename U>
bool operator!=(const sk_sp<U>& that) const { return this->get() != that.get(); }
+ T& operator*() const {
+ SkASSERT(this->get() != nullptr);
+ return *this->get();
+ }
+
// MSVC 2013 does not work correctly with explicit operator bool.
// https://chromium-cpp.appspot.com/#core-blacklist
+ // When explicit operator bool can be used, remove operator! and operator unspecified_bool_type.
//explicit operator bool() const { return this->get() != nullptr; }
-
+ operator unspecified_bool_type() const { return this->get() ? &sk_sp::fPtr : nullptr; }
bool operator!() const { return this->get() == nullptr; }
T* get() const { return fPtr; }
diff --git a/tests/RefCntTest.cpp b/tests/RefCntTest.cpp
index bda45317bc..60a34ecf88 100644
--- a/tests/RefCntTest.cpp
+++ b/tests/RefCntTest.cpp
@@ -164,9 +164,31 @@ DEF_TEST(sk_sp, reporter) {
check(reporter, 0, 0, 1, 0);
REPORTER_ASSERT(reporter, paint.fEffect.get()->fRefCnt == 1);
+ if (paint.get()) {
+ REPORTER_ASSERT(reporter, true);
+ } else {
+ REPORTER_ASSERT(reporter, false);
+ }
+ if (!paint.get()) {
+ REPORTER_ASSERT(reporter, false);
+ } else {
+ REPORTER_ASSERT(reporter, true);
+ }
+
paint.set(nullptr);
check(reporter, 0, 1, 1, 1);
+ if (paint.get()) {
+ REPORTER_ASSERT(reporter, false);
+ } else {
+ REPORTER_ASSERT(reporter, true);
+ }
+ if (!paint.get()) {
+ REPORTER_ASSERT(reporter, true);
+ } else {
+ REPORTER_ASSERT(reporter, false);
+ }
+
auto e = Create();
REPORTER_ASSERT(reporter, sizeof(e) == sizeof(void*));
@@ -180,9 +202,14 @@ DEF_TEST(sk_sp, reporter) {
check(reporter, 2, 1, 2, 1);
REPORTER_ASSERT(reporter, paint.fEffect.get()->fRefCnt == 3);
+ // Test sk_sp::operator->
delete paint.get()->method();
check(reporter, 2, 1, 2, 1);
+ // Test sk_sp::operator*
+ delete (*paint.get()).method();
+ check(reporter, 2, 1, 2, 1);
+
paint.set(nullptr);
e = nullptr;
paint2.set(nullptr);