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