comptr.h
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:5k
源码类别:

Symbian

开发平台:

C/C++

  1. ////////////////////////////////////////
  2. //
  3. // interface for a simple wrapper class for COM (ref counted) pointers.
  4. //
  5. #if !defined(COM_PTR_INC__)
  6. #define COM_PTR_INC__
  7. #if _MSC_VER >= 1000
  8. #pragma once
  9. #endif // _MSC_VER >= 1000
  10. #include "hxassert.h"
  11. namespace comptr_util
  12. {
  13. template<typename I>
  14. inline
  15. void Release(I*& p)
  16. {
  17.     if( p )
  18.     {
  19.         p->Release();
  20.         p = 0;
  21.     }
  22. }
  23. #if defined(HELIX_FEATURE_FULLGUID)
  24. typedef REFIID IID_RETTYPE;
  25. #else
  26. // IID is an enum and a reference to it cannot be returned, so we force return by value
  27. typedef IID IID_RETTYPE;
  28. #endif
  29. // trait for allowing us to get REFIID corresponding to IID
  30. template<typename I>
  31. struct IIDTraits
  32. {
  33.     // missing #include "comptr_traits.h"? missing trait in "comptr_traits.h"?
  34.     static inline IID_RETTYPE riid() { return missing_trait_definition; }
  35. };
  36. /*
  37. template <class T>
  38. struct ptr_traits
  39. {
  40.   typedef void ptr_type; // 'void' for non-pointers
  41. };
  42. // partial-specialization for ptrs
  43. template <class T>
  44. struct ptr_traits<T*>
  45. {
  46.   typedef T ptr_type;
  47. };
  48. // convert from IUnknown* to IPtr via QI
  49. template<typename IPtr, typename IOther>
  50. inline
  51. IPtr com_cast(IOther* pOther)
  52. {
  53.     IPtr ptr = 0;
  54.     if(pOther)
  55.     {
  56.         typename ptr_traits<IPtr>::ptr_type I;
  57.         pOther->QueryInterface(comptr_util::IIDTraits<I>::riid(), reinterpret_cast<void**>(&ptr));
  58.     }
  59.     return ptr;
  60. }
  61. */
  62. } // ns comptr_util
  63. template<typename I>
  64. class comptr 
  65. {
  66. public:
  67.     // construction
  68.     comptr(I* p = 0);
  69.     //comptr(IUnknown* pOther);
  70.     comptr(const comptr<I>& rhs);
  71.     
  72.     // destruction
  73.     ~comptr();
  74.     // assignment
  75.     comptr<I>& operator= (I* p);
  76.     comptr<I>& operator= (const comptr<I>& rhs);
  77.     
  78.     // take refcount (don't increment)
  79.     void Take(I* p);
  80.     // query interface
  81.     bool From(IUnknown* pOther); 
  82.     // conversion
  83.     // I* Ptr() const;
  84.     operator I*() const;
  85.     // operators
  86.     // operator bool() const { return m_p != 0; }
  87.     I* operator-> () const;
  88.     
  89.     // methods
  90.     void Reset(I* p = 0);
  91.     I*& AsRef();
  92.     void** AsPtrPtr();
  93. private:
  94.     I* m_p;
  95. };
  96. template< typename I>
  97. inline
  98. comptr<I>::comptr (I* p)
  99. : m_p(p)
  100. {
  101.     if(m_p)
  102.     {
  103.         m_p->AddRef();
  104.     }
  105. }
  106. template<typename I>
  107. inline
  108. comptr<I>::comptr(const comptr<I>& rhs)
  109. : m_p(rhs.m_p) 
  110. {
  111.     if( m_p )
  112.     {
  113. m_p->AddRef();
  114.     }
  115. }
  116. template <typename I>
  117. /*inline*/
  118. void comptr<I>::Reset(I* p)
  119. {
  120.     if( m_p != p)
  121.     {
  122. // relinquish m_p
  123. if( m_p )
  124. {
  125.     m_p->Release();
  126. }
  127. // aquire p
  128. m_p = p;
  129. if( m_p )
  130. {
  131.     m_p->AddRef();
  132. }
  133.     }
  134. }
  135. template<typename I>
  136. inline
  137. comptr<I>::~comptr()
  138. {
  139.     comptr_util::Release(m_p);
  140. }
  141. template< typename I>
  142. inline
  143. comptr<I>& comptr<I>::operator= (const comptr<I>& rhs)
  144. {
  145.     Reset(rhs.m_p);
  146.     return *this;
  147. }
  148. template< typename I>
  149. inline
  150. comptr<I>& comptr<I>::operator= (I* p)
  151. {
  152.     Reset(p);
  153.     return *this;
  154. }
  155. /*
  156. template <typename I>
  157. inline
  158. I* comptr<I>::Ptr() const
  159. {
  160.     return m_p;
  161. }*/
  162. template <typename I>
  163. inline
  164. comptr<I>::operator I*() const
  165. {
  166.     return m_p;
  167. }
  168. template <typename I>
  169. inline
  170. I* comptr<I>::operator->() const
  171. {
  172.     HX_ASSERT_VALID_PTR(m_p);
  173.     return m_p;
  174. }
  175. //
  176. // Take addref'd pointer; for cases where interface 
  177. // is already addref'd for you:
  178. //
  179. // comptr<ISomething> something;
  180. // /* GetIface() returns addref'd ptr */
  181. // something.Take(pOther->GetIface()); 
  182. //
  183. template<typename I>
  184. inline
  185. void comptr<I>::Take(I* p)
  186. {
  187.     comptr_util::Release(m_p);
  188.     m_p = p; // already has ref count incremented
  189. }
  190. //
  191. // enables us to write:
  192. //
  193. // comptr<IMyInterface> iface;
  194. // /* pOther may expose IMyInterface */
  195. // if(iface.From(pOther))
  196. // { /* use it ... */ }
  197. //
  198. template< typename I>
  199. inline
  200. bool comptr<I>::From( IUnknown* pOther )
  201. {
  202.     comptr_util::Release(m_p);
  203.     if(pOther)
  204.     {
  205.         pOther->QueryInterface(comptr_util::IIDTraits<I>::riid(), reinterpret_cast<void**>(&m_p));
  206.     }
  207.     //m_p = comptr_util::com_cast<I*>(pOther);
  208.     return m_p != 0;
  209. }
  210. //
  211. // For passing to functions expecting I*& for write access to I*
  212. //
  213. // HX_RESULT Factory::GetMyInterface(IMyInterface*& pInterfaceOut); 
  214. //
  215. // comptr<IMyInterface> iface;
  216. // pFactory->GetMyInterface(iface.AsRef());
  217. //
  218. template <typename I>
  219. inline
  220. I*& comptr<I>::AsRef() 
  221.     HX_ASSERT(!m_p); // about to overwrite and un-released ptr? (must be null)
  222.     return m_p; 
  223. //
  224. // For passing to functions expecting void** for write access to I*
  225. //
  226. template <typename I>
  227. inline
  228. void** comptr<I>::AsPtrPtr()
  229. {
  230.     HX_ASSERT(!m_p); // about to overwrite and un-released ptr? (must be null)
  231.     return reinterpret_cast<void**>(&m_p);
  232. }
  233. #endif // !defined(COM_PTR_INC__)