19df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
79df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com */
89df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com
9e02944075840d672bd1797f3d945ff82d302282fcommit-bot@chromium.org#ifndef SkTScopedComPtr_DEFINED
10e02944075840d672bd1797f3d945ff82d302282fcommit-bot@chromium.org#define SkTScopedComPtr_DEFINED
119df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com
12b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#include "SkTypes.h"
139df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com#include "SkTemplates.h"
149df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com
159df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.comtemplate<typename T>
16b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comclass SkBlockComRef : public T {
17b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comprivate:
18b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com    virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0;
19b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com    virtual ULONG STDMETHODCALLTYPE Release(void) = 0;
20b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com};
21b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com
227103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.comtemplate<typename T> T* SkRefComPtr(T* ptr) {
237103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com    ptr->AddRef();
247103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com    return ptr;
257103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com}
267103344b64f3f0df88e76857c16edc8eedb58366bungeman@google.com
274bbc524ca44874cd5db6d72fab103ba085c86486bungeman@google.comtemplate<typename T> T* SkSafeRefComPtr(T* ptr) {
284bbc524ca44874cd5db6d72fab103ba085c86486bungeman@google.com    if (ptr) {
294bbc524ca44874cd5db6d72fab103ba085c86486bungeman@google.com        ptr->AddRef();
304bbc524ca44874cd5db6d72fab103ba085c86486bungeman@google.com    }
314bbc524ca44874cd5db6d72fab103ba085c86486bungeman@google.com    return ptr;
324bbc524ca44874cd5db6d72fab103ba085c86486bungeman@google.com}
334bbc524ca44874cd5db6d72fab103ba085c86486bungeman@google.com
34b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.comtemplate<typename T>
359df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.comclass SkTScopedComPtr : SkNoncopyable {
369df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.comprivate:
379df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com    T *fPtr;
389df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com
399df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.compublic:
409df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com    explicit SkTScopedComPtr(T *ptr = NULL) : fPtr(ptr) { }
419df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com    ~SkTScopedComPtr() {
42a9e586a21f7c13d12e3662d95ae34ad64cc00f95bungeman@google.com        this->reset();
439df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com    }
44e8f0592ae8b37e94d99f49816eb22e9fafde6d86bungeman@google.com    T &operator*() const { SkASSERT(fPtr != NULL); return *fPtr; }
45b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com    SkBlockComRef<T> *operator->() const {
46b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com        return static_cast<SkBlockComRef<T>*>(fPtr);
47b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com    }
489df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com    /**
499df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com     * Returns the address of the underlying pointer.
509df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com     * This is dangerous -- it breaks encapsulation and the reference escapes.
519df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com     * Must only be used on instances currently pointing to NULL,
529df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com     * and only to initialize the instance.
539df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com     */
549df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com    T **operator&() { SkASSERT(fPtr == NULL); return &fPtr; }
559df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com    T *get() const { return fPtr; }
56a9e586a21f7c13d12e3662d95ae34ad64cc00f95bungeman@google.com    void reset() {
5749f085dddff10473b6ebf832a974288300224e60bsalomon        if (this->fPtr) {
58a9e586a21f7c13d12e3662d95ae34ad64cc00f95bungeman@google.com            this->fPtr->Release();
59a9e586a21f7c13d12e3662d95ae34ad64cc00f95bungeman@google.com            this->fPtr = NULL;
60a9e586a21f7c13d12e3662d95ae34ad64cc00f95bungeman@google.com        }
61a9e586a21f7c13d12e3662d95ae34ad64cc00f95bungeman@google.com    }
62fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
63b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com    void swap(SkTScopedComPtr<T>& that) {
64b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com        T* temp = this->fPtr;
65b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com        this->fPtr = that.fPtr;
66b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com        that.fPtr = temp;
67b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com    }
68fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
69b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com    T* release() {
70b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com        T* temp = this->fPtr;
71b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com        this->fPtr = NULL;
72b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com        return temp;
73b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com    }
749df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com};
759df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com
769df621da5024dda2ffd77cfa6e6c0a0f68e4aa86bungeman@google.com#endif
77