SkTScopedComPtr.h revision bd81a327b5728b51cac8642128bd2f165d078ef7
1/* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#ifndef SkTScopedComPtr_DEFINED 9#define SkTScopedComPtr_DEFINED 10 11#include "SkLeanWindows.h" 12 13#ifdef SK_BUILD_FOR_WIN 14 15template<typename T> 16class SkBlockComRef : public T { 17private: 18 virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0; 19 virtual ULONG STDMETHODCALLTYPE Release(void) = 0; 20}; 21 22template<typename T> T* SkRefComPtr(T* ptr) { 23 ptr->AddRef(); 24 return ptr; 25} 26 27template<typename T> T* SkSafeRefComPtr(T* ptr) { 28 if (ptr) { 29 ptr->AddRef(); 30 } 31 return ptr; 32} 33 34template<typename T> 35class SkTScopedComPtr : SkNoncopyable { 36private: 37 T *fPtr; 38 39public: 40 explicit SkTScopedComPtr(T *ptr = nullptr) : fPtr(ptr) { } 41 42 ~SkTScopedComPtr() { this->reset();} 43 44 T &operator*() const { SkASSERT(fPtr != nullptr); return *fPtr; } 45 46 explicit operator bool() const { return fPtr != nullptr; } 47 48 SkBlockComRef<T> *operator->() const { return static_cast<SkBlockComRef<T>*>(fPtr); } 49 50 /** 51 * Returns the address of the underlying pointer. 52 * This is dangerous -- it breaks encapsulation and the reference escapes. 53 * Must only be used on instances currently pointing to NULL, 54 * and only to initialize the instance. 55 */ 56 T **operator&() { SkASSERT(fPtr == nullptr); return &fPtr; } 57 58 T *get() const { return fPtr; } 59 60 void reset(T* ptr = nullptr) { 61 if (fPtr) { 62 fPtr->Release(); 63 } 64 fPtr = ptr; 65 } 66 67 void swap(SkTScopedComPtr<T>& that) { 68 T* temp = this->fPtr; 69 this->fPtr = that.fPtr; 70 that.fPtr = temp; 71 } 72 73 T* release() { 74 T* temp = this->fPtr; 75 this->fPtr = nullptr; 76 return temp; 77 } 78}; 79 80#endif // SK_BUILD_FOR_WIN 81#endif // SkTScopedComPtr_DEFINED 82