/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkTScopedComPtr_DEFINED
#define SkTScopedComPtr_DEFINED

#include "src/core/SkLeanWindows.h"
#include "src/utils/win/SkObjBase.h"

#ifdef SK_BUILD_FOR_WIN

template<typename T> T* SkRefComPtr(T* ptr) {
    ptr->AddRef();
    return ptr;
}

template<typename T> T* SkSafeRefComPtr(T* ptr) {
    if (ptr) {
        ptr->AddRef();
    }
    return ptr;
}

template<typename T>
class SkTScopedComPtr {
private:
    T *fPtr;

public:
    constexpr SkTScopedComPtr() : fPtr(nullptr) {}
    constexpr SkTScopedComPtr(std::nullptr_t) : fPtr(nullptr) {}
    explicit SkTScopedComPtr(T *ptr) : fPtr(ptr) {}
    SkTScopedComPtr(SkTScopedComPtr&& that) : fPtr(that.release()) {}
    SkTScopedComPtr(const SkTScopedComPtr&) = delete;

    ~SkTScopedComPtr() { this->reset();}

    SkTScopedComPtr& operator=(SkTScopedComPtr&& that) {
        this->reset(that.release());
        return *this;
    }
    SkTScopedComPtr& operator=(const SkTScopedComPtr&) = delete;
    SkTScopedComPtr& operator=(std::nullptr_t) { this->reset(); return *this; }

    T &operator*() const { SkASSERT(fPtr != nullptr); return *fPtr; }

    explicit operator bool() const { return fPtr != nullptr; }

    T *operator->() const { return fPtr; }

    /**
     * Returns the address of the underlying pointer.
     * This is dangerous -- it breaks encapsulation and the reference escapes.
     * Must only be used on instances currently pointing to NULL,
     * and only to initialize the instance.
     */
    T **operator&() { SkASSERT(fPtr == nullptr); return &fPtr; }

    T *get() const { return fPtr; }

    void reset(T* ptr = nullptr) {
        if (fPtr) {
            fPtr->Release();
        }
        fPtr = ptr;
    }

    void swap(SkTScopedComPtr<T>& that) {
        T* temp = this->fPtr;
        this->fPtr = that.fPtr;
        that.fPtr = temp;
    }

    T* release() {
        T* temp = this->fPtr;
        this->fPtr = nullptr;
        return temp;
    }
};

#endif  // SK_BUILD_FOR_WIN
#endif  // SkTScopedComPtr_DEFINED
