1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#ifndef SkSkTScopedPtr_DEFINED
10#define SkSkTScopedPtr_DEFINED
11
12#include "SkTypes.h"
13#include "SkTemplates.h"
14
15template<typename T>
16class SkBlockComRef : public T {
17private:
18    virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0;
19    virtual ULONG STDMETHODCALLTYPE Release(void) = 0;
20};
21
22template<typename T>
23class SkTScopedComPtr : SkNoncopyable {
24private:
25    T *fPtr;
26
27public:
28    explicit SkTScopedComPtr(T *ptr = NULL) : fPtr(ptr) { }
29    ~SkTScopedComPtr() {
30        this->reset();
31    }
32    T &operator*() const { return *fPtr; }
33    SkBlockComRef<T> *operator->() const {
34        return static_cast<SkBlockComRef<T>*>(fPtr);
35    }
36    /**
37     * Returns the address of the underlying pointer.
38     * This is dangerous -- it breaks encapsulation and the reference escapes.
39     * Must only be used on instances currently pointing to NULL,
40     * and only to initialize the instance.
41     */
42    T **operator&() { SkASSERT(fPtr == NULL); return &fPtr; }
43    T *get() const { return fPtr; }
44    void reset() {
45        if (NULL != this->fPtr) {
46            this->fPtr->Release();
47            this->fPtr = NULL;
48        }
49    }
50
51    void swap(SkTScopedComPtr<T>& that) {
52        T* temp = this->fPtr;
53        this->fPtr = that.fPtr;
54        that.fPtr = temp;
55    }
56
57    T* release() {
58        T* temp = this->fPtr;
59        this->fPtr = NULL;
60        return temp;
61    }
62};
63
64#endif
65