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