michael@0: michael@0: /* michael@0: * Copyright 2011 Google Inc. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: #ifndef SkTScopedComPtr_DEFINED michael@0: #define SkTScopedComPtr_DEFINED michael@0: michael@0: #include "SkTypes.h" michael@0: #include "SkTemplates.h" michael@0: michael@0: template michael@0: class SkBlockComRef : public T { michael@0: private: michael@0: virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0; michael@0: virtual ULONG STDMETHODCALLTYPE Release(void) = 0; michael@0: }; michael@0: michael@0: template T* SkRefComPtr(T* ptr) { michael@0: ptr->AddRef(); michael@0: return ptr; michael@0: } michael@0: michael@0: template T* SkSafeRefComPtr(T* ptr) { michael@0: if (ptr) { michael@0: ptr->AddRef(); michael@0: } michael@0: return ptr; michael@0: } michael@0: michael@0: template michael@0: class SkTScopedComPtr : SkNoncopyable { michael@0: private: michael@0: T *fPtr; michael@0: michael@0: public: michael@0: explicit SkTScopedComPtr(T *ptr = NULL) : fPtr(ptr) { } michael@0: ~SkTScopedComPtr() { michael@0: this->reset(); michael@0: } michael@0: T &operator*() const { SkASSERT(fPtr != NULL); return *fPtr; } michael@0: SkBlockComRef *operator->() const { michael@0: return static_cast*>(fPtr); michael@0: } michael@0: /** michael@0: * Returns the address of the underlying pointer. michael@0: * This is dangerous -- it breaks encapsulation and the reference escapes. michael@0: * Must only be used on instances currently pointing to NULL, michael@0: * and only to initialize the instance. michael@0: */ michael@0: T **operator&() { SkASSERT(fPtr == NULL); return &fPtr; } michael@0: T *get() const { return fPtr; } michael@0: void reset() { michael@0: if (NULL != this->fPtr) { michael@0: this->fPtr->Release(); michael@0: this->fPtr = NULL; michael@0: } michael@0: } michael@0: michael@0: void swap(SkTScopedComPtr& that) { michael@0: T* temp = this->fPtr; michael@0: this->fPtr = that.fPtr; michael@0: that.fPtr = temp; michael@0: } michael@0: michael@0: T* release() { michael@0: T* temp = this->fPtr; michael@0: this->fPtr = NULL; michael@0: return temp; michael@0: } michael@0: }; michael@0: michael@0: #endif