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 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 { 36 private: 37 T *fPtr; 38 39 public: 40 constexpr SkTScopedComPtr() : fPtr(nullptr) {} 41 constexpr SkTScopedComPtr(std::nullptr_t) : fPtr(nullptr) {} 42 explicit SkTScopedComPtr(T *ptr) : fPtr(ptr) {} 43 SkTScopedComPtr(SkTScopedComPtr&& that) : fPtr(that.release()) {} 44 SkTScopedComPtr(const SkTScopedComPtr&) = delete; 45 46 ~SkTScopedComPtr() { this->reset();} 47 48 SkTScopedComPtr& operator=(SkTScopedComPtr&& that) { 49 this->reset(that.release()); 50 return *this; 51 } 52 SkTScopedComPtr& operator=(const SkTScopedComPtr&) = delete; 53 SkTScopedComPtr& operator=(std::nullptr_t) { this->reset(); return *this; } 54 55 T &operator*() const { SkASSERT(fPtr != nullptr); return *fPtr; } 56 57 explicit operator bool() const { return fPtr != nullptr; } 58 59 SkBlockComRef<T> *operator->() const { return static_cast<SkBlockComRef<T>*>(fPtr); } 60 61 /** 62 * Returns the address of the underlying pointer. 63 * This is dangerous -- it breaks encapsulation and the reference escapes. 64 * Must only be used on instances currently pointing to NULL, 65 * and only to initialize the instance. 66 */ 67 T **operator&() { SkASSERT(fPtr == nullptr); return &fPtr; } 68 69 T *get() const { return fPtr; } 70 71 void reset(T* ptr = nullptr) { 72 if (fPtr) { 73 fPtr->Release(); 74 } 75 fPtr = ptr; 76 } 77 78 void swap(SkTScopedComPtr<T>& that) { 79 T* temp = this->fPtr; 80 this->fPtr = that.fPtr; 81 that.fPtr = temp; 82 } 83 84 T* release() { 85 T* temp = this->fPtr; 86 this->fPtr = nullptr; 87 return temp; 88 } 89 }; 90 91 #endif // SK_BUILD_FOR_WIN 92 #endif // SkTScopedComPtr_DEFINED 93