- ////////////////////////////////////////
- //
- // interface for a simple wrapper class for COM (ref counted) pointers.
- //
- #if !defined(COM_PTR_INC__)
- #define COM_PTR_INC__
- #if _MSC_VER >= 1000
- #pragma once
- #endif // _MSC_VER >= 1000
- #include "hxassert.h"
- namespace comptr_util
- {
- template<typename I>
- inline
- void Release(I*& p)
- {
- if( p )
- {
- p->Release();
- p = 0;
- }
- }
- #if defined(HELIX_FEATURE_FULLGUID)
- typedef REFIID IID_RETTYPE;
- #else
- // IID is an enum and a reference to it cannot be returned, so we force return by value
- typedef IID IID_RETTYPE;
- #endif
- // trait for allowing us to get REFIID corresponding to IID
- template<typename I>
- struct IIDTraits
- {
- // missing #include "comptr_traits.h"? missing trait in "comptr_traits.h"?
- static inline IID_RETTYPE riid() { return missing_trait_definition; }
- };
- /*
- template <class T>
- struct ptr_traits
- {
- typedef void ptr_type; // 'void' for non-pointers
- };
- // partial-specialization for ptrs
- template <class T>
- struct ptr_traits<T*>
- {
- typedef T ptr_type;
- };
- // convert from IUnknown* to IPtr via QI
- template<typename IPtr, typename IOther>
- inline
- IPtr com_cast(IOther* pOther)
- {
- IPtr ptr = 0;
- if(pOther)
- {
- typename ptr_traits<IPtr>::ptr_type I;
- pOther->QueryInterface(comptr_util::IIDTraits<I>::riid(), reinterpret_cast<void**>(&ptr));
- }
- return ptr;
- }
- */
- } // ns comptr_util
- template<typename I>
- class comptr
- {
- public:
- // construction
- comptr(I* p = 0);
- //comptr(IUnknown* pOther);
- comptr(const comptr<I>& rhs);
- // destruction
- ~comptr();
- // assignment
- comptr<I>& operator= (I* p);
- comptr<I>& operator= (const comptr<I>& rhs);
- // take refcount (don't increment)
- void Take(I* p);
- // query interface
- bool From(IUnknown* pOther);
- // conversion
- // I* Ptr() const;
- operator I*() const;
- // operators
- // operator bool() const { return m_p != 0; }
- I* operator-> () const;
- // methods
- void Reset(I* p = 0);
- I*& AsRef();
- void** AsPtrPtr();
- private:
- I* m_p;
- };
- template< typename I>
- inline
- comptr<I>::comptr (I* p)
- : m_p(p)
- {
- if(m_p)
- {
- m_p->AddRef();
- }
- }
- template<typename I>
- inline
- comptr<I>::comptr(const comptr<I>& rhs)
- : m_p(rhs.m_p)
- {
- if( m_p )
- {
- m_p->AddRef();
- }
- }
- template <typename I>
- /*inline*/
- void comptr<I>::Reset(I* p)
- {
- if( m_p != p)
- {
- // relinquish m_p
- if( m_p )
- {
- m_p->Release();
- }
- // aquire p
- m_p = p;
- if( m_p )
- {
- m_p->AddRef();
- }
- }
- }
- template<typename I>
- inline
- comptr<I>::~comptr()
- {
- comptr_util::Release(m_p);
- }
- template< typename I>
- inline
- comptr<I>& comptr<I>::operator= (const comptr<I>& rhs)
- {
- Reset(rhs.m_p);
- return *this;
- }
- template< typename I>
- inline
- comptr<I>& comptr<I>::operator= (I* p)
- {
- Reset(p);
- return *this;
- }
- /*
- template <typename I>
- inline
- I* comptr<I>::Ptr() const
- {
- return m_p;
- }*/
- template <typename I>
- inline
- comptr<I>::operator I*() const
- {
- return m_p;
- }
- template <typename I>
- inline
- I* comptr<I>::operator->() const
- {
- HX_ASSERT_VALID_PTR(m_p);
- return m_p;
- }
- //
- // Take addref'd pointer; for cases where interface
- // is already addref'd for you:
- //
- // comptr<ISomething> something;
- // /* GetIface() returns addref'd ptr */
- // something.Take(pOther->GetIface());
- //
- template<typename I>
- inline
- void comptr<I>::Take(I* p)
- {
- comptr_util::Release(m_p);
- m_p = p; // already has ref count incremented
- }
- //
- // enables us to write:
- //
- // comptr<IMyInterface> iface;
- // /* pOther may expose IMyInterface */
- // if(iface.From(pOther))
- // { /* use it ... */ }
- //
- template< typename I>
- inline
- bool comptr<I>::From( IUnknown* pOther )
- {
- comptr_util::Release(m_p);
- if(pOther)
- {
- pOther->QueryInterface(comptr_util::IIDTraits<I>::riid(), reinterpret_cast<void**>(&m_p));
- }
- //m_p = comptr_util::com_cast<I*>(pOther);
- return m_p != 0;
- }
- //
- // For passing to functions expecting I*& for write access to I*
- //
- // HX_RESULT Factory::GetMyInterface(IMyInterface*& pInterfaceOut);
- //
- // comptr<IMyInterface> iface;
- // pFactory->GetMyInterface(iface.AsRef());
- //
- template <typename I>
- inline
- I*& comptr<I>::AsRef()
- {
- HX_ASSERT(!m_p); // about to overwrite and un-released ptr? (must be null)
- return m_p;
- }
- //
- // For passing to functions expecting void** for write access to I*
- //
- template <typename I>
- inline
- void** comptr<I>::AsPtrPtr()
- {
- HX_ASSERT(!m_p); // about to overwrite and un-released ptr? (must be null)
- return reinterpret_cast<void**>(&m_p);
- }
- #endif // !defined(COM_PTR_INC__)