180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc.
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
90a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#ifndef SkTScopedComPtr_DEFINED
100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#define SkTScopedComPtr_DEFINED
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTypes.h"
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTemplates.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate<typename T>
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkBlockComRef : public T {
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0;
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual ULONG STDMETHODCALLTYPE Release(void) = 0;
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergertemplate<typename T> T* SkRefComPtr(T* ptr) {
237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    ptr->AddRef();
247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return ptr;
257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergertemplate<typename T> T* SkSafeRefComPtr(T* ptr) {
287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (ptr) {
297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        ptr->AddRef();
307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return ptr;
327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate<typename T>
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkTScopedComPtr : SkNoncopyable {
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    T *fPtr;
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    explicit SkTScopedComPtr(T *ptr = NULL) : fPtr(ptr) { }
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    ~SkTScopedComPtr() {
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->reset();
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    T &operator*() const { SkASSERT(fPtr != NULL); return *fPtr; }
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkBlockComRef<T> *operator->() const {
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return static_cast<SkBlockComRef<T>*>(fPtr);
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * Returns the address of the underlying pointer.
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * This is dangerous -- it breaks encapsulation and the reference escapes.
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * Must only be used on instances currently pointing to NULL,
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * and only to initialize the instance.
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    T **operator&() { SkASSERT(fPtr == NULL); return &fPtr; }
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    T *get() const { return fPtr; }
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void reset() {
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (NULL != this->fPtr) {
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            this->fPtr->Release();
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            this->fPtr = NULL;
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void swap(SkTScopedComPtr<T>& that) {
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        T* temp = this->fPtr;
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->fPtr = that.fPtr;
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        that.fPtr = temp;
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    T* release() {
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        T* temp = this->fPtr;
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->fPtr = NULL;
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return temp;
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
77