| |
| /* |
| * 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 |