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