diff options
-rw-r--r-- | include/core/SkRefCnt.h | 10 | ||||
-rw-r--r-- | tests/RefCntTest.cpp | 27 |
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); |