/* * Copyright 2011 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkSkTScopedPtr_DEFINED #define SkSkTScopedPtr_DEFINED #include "SkTypes.h" #include "SkTemplates.h" template<typename T> class SkBlockComRef : public T { private: virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0; virtual ULONG STDMETHODCALLTYPE Release(void) = 0; }; template<typename T> class SkTScopedComPtr : SkNoncopyable { private: T *fPtr; public: explicit SkTScopedComPtr(T *ptr = NULL) : fPtr(ptr) { } ~SkTScopedComPtr() { this->reset(); } T &operator*() const { return *fPtr; } SkBlockComRef<T> *operator->() const { return static_cast<SkBlockComRef<T>*>(fPtr); } /** * Returns the address of the underlying pointer. * This is dangerous -- it breaks encapsulation and the reference escapes. * Must only be used on instances currently pointing to NULL, * and only to initialize the instance. */ T **operator&() { SkASSERT(fPtr == NULL); return &fPtr; } T *get() const { return fPtr; } void reset() { if (NULL != this->fPtr) { this->fPtr->Release(); this->fPtr = NULL; } } void swap(SkTScopedComPtr<T>& that) { T* temp = this->fPtr; this->fPtr = that.fPtr; that.fPtr = temp; } T* release() { T* temp = this->fPtr; this->fPtr = NULL; return temp; } }; #endif