| Index: include/core/SkRefCnt.h
|
| diff --git a/include/core/SkRefCnt.h b/include/core/SkRefCnt.h
|
| index 9d1e5f1f02c252c13c2091208903457403c0a825..43251d0788c2e6a992965da626729da035d9e165 100644
|
| --- a/include/core/SkRefCnt.h
|
| +++ b/include/core/SkRefCnt.h
|
| @@ -227,4 +227,103 @@ private:
|
| mutable int32_t fRefCnt;
|
| };
|
|
|
| +///////////////////////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +/**
|
| + * Shared pointer class to wrap classes that support a ref()/unref() interface.
|
| + *
|
| + * This can be used for classes inheriting from SkRefCnt, but it also works for other
|
| + * classes that match the interface, but have different internal choices: e.g. the hosted class
|
| + * may have its ref/unref be thread-safe, but that is not assumed/imposed by sk_sp.
|
| + */
|
| +template <typename T> class sk_sp {
|
| +public:
|
| + sk_sp() : fPtr(nullptr) {}
|
| + sk_sp(std::nullptr_t) : fPtr(nullptr) {}
|
| +
|
| + /**
|
| + * Shares the underlying object by calling ref(), so that both the argument and the newly
|
| + * created sk_sp both have a reference to it.
|
| + */
|
| + sk_sp(const sk_sp<T>& that) : fPtr(SkSafeRef(that.get())) {}
|
| +
|
| + /**
|
| + * Move the underlying object from the argument to the newly created sk_sp. Afterwards only
|
| + * the new sk_sp will have a reference to the object, and the argument will point to null.
|
| + * No call to ref() or unref() will be made.
|
| + */
|
| + sk_sp(sk_sp<T>&& that) : fPtr(that.release()) {}
|
| +
|
| + /**
|
| + * Adopt the bare pointer into the newly created sk_sp.
|
| + * No call to ref() or unref() will be made.
|
| + */
|
| + explicit sk_sp(T* obj) : fPtr(obj) {}
|
| +
|
| + /**
|
| + * Calls unref() on the underlying object pointer.
|
| + */
|
| + ~sk_sp() {
|
| + SkSafeUnref(fPtr);
|
| + }
|
| +
|
| + sk_sp<T>& operator=(std::nullptr_t) { this->reset(); }
|
| +
|
| + /**
|
| + * Shares the underlying object referenced by the argument by calling ref() on it. If this
|
| + * sk_sp previously had a reference to an object (i.e. not null) it will call unref() on that
|
| + * object.
|
| + */
|
| + sk_sp<T>& operator=(const sk_sp<T>& that) {
|
| + this->reset(SkSafeRef(that.get()));
|
| + return *this;
|
| + }
|
| +
|
| + /**
|
| + * Move the underlying object from the argument to the sk_sp. If the sk_sp previously held
|
| + * a reference to another object, unref() will be called on that object. No call to ref()
|
| + * will be made.
|
| + */
|
| + sk_sp<T>& operator=(sk_sp<T>&& that) {
|
| + this->reset(that.release());
|
| + return *this;
|
| + }
|
| +
|
| + bool operator==(std::nullptr_t) const { return this->get() == nullptr; }
|
| + bool operator!=(std::nullptr_t) const { return this->get() != nullptr; }
|
| +
|
| + bool operator==(const sk_sp<T>& that) const { return this->get() == that.get(); }
|
| + bool operator!=(const sk_sp<T>& that) const { return this->get() != that.get(); }
|
| +
|
| + explicit operator bool() const { return this->get() != nullptr; }
|
| +
|
| + T* get() const { return fPtr; }
|
| + T* operator->() const { return fPtr; }
|
| +
|
| + /**
|
| + * Adopt the new bare pointer, and call unref() on any previously held object (if not null).
|
| + * No call to ref() will be made.
|
| + */
|
| + void reset(T* ptr = nullptr) {
|
| + if (fPtr != ptr) {
|
| + SkSafeUnref(fPtr);
|
| + fPtr = ptr;
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Return the bare pointer, and set the internal object pointer to nullptr.
|
| + * The caller must assume ownership of the object, and manage its reference count directly.
|
| + * No call to unref() will be made.
|
| + */
|
| + T* SK_WARN_UNUSED_RESULT release() {
|
| + T* ptr = fPtr;
|
| + fPtr = nullptr;
|
| + return ptr;
|
| + }
|
| +
|
| +private:
|
| + T* fPtr;
|
| +};
|
| +
|
| #endif
|
|
|