#pragma once 
 | 
  
 | 
namespace win 
 | 
{ 
 | 
    template<typename T> 
 | 
    class ComPtr; 
 | 
  
 | 
    template<typename T> 
 | 
    class ComPtrRef 
 | 
    { 
 | 
    private: 
 | 
        ComPtr<T>& m_ComPtr; 
 | 
  
 | 
        ComPtrRef(ComPtr<T>& comPtr) : 
 | 
            m_ComPtr(comPtr) 
 | 
        { 
 | 
        } 
 | 
  
 | 
        friend class ComPtr<T>; 
 | 
  
 | 
    public: 
 | 
        inline operator T**() 
 | 
        { 
 | 
            return m_ComPtr.ReleaseAndGetAddressOf(); 
 | 
        } 
 | 
  
 | 
        inline operator void**() 
 | 
        { 
 | 
            return reinterpret_cast<void**>(m_ComPtr.ReleaseAndGetAddressOf()); 
 | 
        } 
 | 
  
 | 
        inline T* operator*() throw () 
 | 
        { 
 | 
            return m_ComPtr; 
 | 
        } 
 | 
  
 | 
    }; 
 | 
  
 | 
    template<typename T> 
 | 
    class ComPtr 
 | 
    { 
 | 
    private: 
 | 
        T *ptr; 
 | 
  
 | 
    public: 
 | 
        inline ComPtr(void) : ptr(NULL) {} 
 | 
        inline ~ComPtr(void) { this->Free(); } 
 | 
  
 | 
        ComPtr(T *ptr) 
 | 
        { 
 | 
            if (NULL != (this->ptr = ptr)) 
 | 
            { 
 | 
                this->ptr->AddRef(); 
 | 
            } 
 | 
        } 
 | 
  
 | 
        ComPtr(const ComPtr &ptr) 
 | 
        { 
 | 
            if (NULL != (this->ptr = ptr.ptr)) 
 | 
            { 
 | 
                this->ptr->AddRef(); 
 | 
            } 
 | 
        } 
 | 
  
 | 
        inline bool operator!() const 
 | 
        { 
 | 
            return (NULL == this->ptr); 
 | 
        } 
 | 
  
 | 
        inline operator T*() const { return this->ptr; } 
 | 
  
 | 
        inline T *operator->() const 
 | 
        { 
 | 
            //_assert(NULL != this->ptr); 
 | 
            return this->ptr; 
 | 
        } 
 | 
  
 | 
        inline T &operator*() 
 | 
        { 
 | 
            //_assert(NULL != this->ptr); 
 | 
            return *this->ptr; 
 | 
        } 
 | 
  
 | 
        inline ComPtrRef<T> operator&() 
 | 
        { 
 | 
            return ComPtrRef<T>(*this); 
 | 
        } 
 | 
  
 | 
        const ComPtr &operator=(T *ptr) 
 | 
        { 
 | 
            if (this->ptr != ptr) 
 | 
            { 
 | 
                this->Free(); 
 | 
  
 | 
                if (NULL != (this->ptr = ptr)) 
 | 
                { 
 | 
                    this->ptr->AddRef(); 
 | 
                } 
 | 
            } 
 | 
  
 | 
            return *this; 
 | 
        } 
 | 
  
 | 
        const ComPtr &operator=(const ComPtr &ptr) 
 | 
        { 
 | 
            if (this->ptr != ptr.ptr) 
 | 
            { 
 | 
                this->Free(); 
 | 
  
 | 
                if (NULL != (this->ptr = ptr.ptr)) 
 | 
                { 
 | 
                    this->ptr->AddRef(); 
 | 
                } 
 | 
            } 
 | 
  
 | 
            return *this; 
 | 
        } 
 | 
  
 | 
        void Free(void) 
 | 
        { 
 | 
            if (NULL != this->ptr) 
 | 
            { 
 | 
                this->ptr->Release(); 
 | 
                this->ptr = NULL; 
 | 
            } 
 | 
        } 
 | 
  
 | 
        inline T** ReleaseAndGetAddressOf() 
 | 
        { 
 | 
            Free(); 
 | 
            return &ptr; 
 | 
        } 
 | 
  
 | 
        template<typename U> 
 | 
        inline HRESULT As(ComPtrRef<U> p) const throw () 
 | 
        { 
 | 
            return ptr->QueryInterface(__uuidof(U), p); 
 | 
        } 
 | 
  
 | 
        inline bool operator==(std::nullptr_t) const 
 | 
        { 
 | 
            return this->ptr == nullptr; 
 | 
        } 
 | 
  
 | 
        template<typename U> 
 | 
        inline bool operator==(U* other) 
 | 
        { 
 | 
            if (ptr == nullptr || other == nullptr) 
 | 
                return ptr == other; 
 | 
  
 | 
            ComPtr<IUnknown> meUnknown; 
 | 
            ComPtr<IUnknown> otherUnknown; 
 | 
  
 | 
            if (FAILED(this->ptr->QueryInterface(__uuidof(IUnknown), &meUnknown))) 
 | 
                return false; 
 | 
  
 | 
            if (FAILED(other->QueryInterface(__uuidof(IUnknown), &otherUnknown))) 
 | 
                return false; 
 | 
  
 | 
            return static_cast<IUnknown*>(meUnknown) == static_cast<IUnknown*>(otherUnknown); 
 | 
        } 
 | 
  
 | 
        template<typename U> 
 | 
        inline bool operator==(ComPtr<U>& other) 
 | 
        { 
 | 
            return *this == static_cast<U*>(other); 
 | 
        } 
 | 
  
 | 
        inline bool operator!=(std::nullptr_t) const 
 | 
        { 
 | 
            return this->ptr != nullptr; 
 | 
        } 
 | 
  
 | 
        template<typename U> 
 | 
        inline bool operator!=(U* other) 
 | 
        { 
 | 
            return !(*this == other); 
 | 
        } 
 | 
  
 | 
        template<typename U> 
 | 
        inline bool operator!=(ComPtr<U>& other) 
 | 
        { 
 | 
            return *this != static_cast<U*>(other); 
 | 
        } 
 | 
    }; 
 | 
} 
 |