p6comptr.h

Go to the documentation of this file.
00001 
00010 #ifndef P6COMPTR_H__
00011 #define P6COMPTR_H__ 1
00012 
00013 namespace P6R {
00014 
00024    template<typename I> class p6ComPtrBase
00025    {
00026    protected:
00027 
00033       p6ComPtrBase(I *pRawPtr = NULL)
00034       : m_pRaw(pRawPtr)
00035       { 
00036          if(m_pRaw) { m_pRaw->addref(); }
00037       }
00038 
00039       P6VOID release()
00040       {
00041          //P6R::p6ICom* pTmp = m_pRaw;
00042          I* pTmp = m_pRaw;
00043          
00044          m_pRaw = NULL;
00045          if(pTmp) {
00046             pTmp->release();
00047          }
00048       }
00049 
00050    //private:
00051       // This causes compilation errors with stlpd_std::list<> on windows VC++ 2005
00052       // We'd like to make this private to prevent people from doing the wrong
00053       // thing with address of.  Using this operator can cause leaks when p6ComPtr
00054       // has already been assigned an interface pointer.  The pointer will
00055       // not be released before it is potentially overwritten. addressofWithRelease() 
00056       // should be used instead.
00057       //const p6ComPtrBase<I>* operator&() const { return this; } 
00058 
00059    public:
00060       typedef I element_type;
00061 
00062       ~p6ComPtrBase() { release(); }
00063       
00064       operator I*()                 const { return static_cast<I*>(m_pRaw); }
00065       I& operator*()                const { P6ASSERT(NULL != m_pRaw); return *static_cast<I*>(m_pRaw); }
00066       I* operator->()               const { P6ASSERT(NULL != m_pRaw); return static_cast<I*>(m_pRaw); }
00067       P6BOOL operator==(I* pI)      const { return (pI == m_pRaw)    ? P6TRUE:P6FALSE; }
00068       P6BOOL operator!=(I* pI)      const { return (pI != m_pRaw)    ? P6TRUE:P6FALSE; }
00069       P6BOOL operator<(I* pI)       const { return (m_pRaw < pI)     ? P6TRUE:P6FALSE; }
00070       P6BOOL operator!()            const { return (NULL == m_pRaw)  ? P6TRUE:P6FALSE; }
00071 
00072       inline I** addressof()
00073       {
00074          return reinterpret_cast<I**>(&m_pRaw);
00075       }
00076 
00077       inline I** addressofWithRelease()
00078       {
00079          release(); 
00080          return reinterpret_cast<I**>(&m_pRaw);
00081       }
00082 
00091       inline P6VOID swap(I** ppIface)
00092       {
00093          I *tmp = *ppIface;
00094          *ppIface = reinterpret_cast<I*>(m_pRaw);
00095          m_pRaw   = tmp;
00096       }
00097 
00101       inline P6VOID swap(p6ComPtrBase<I> &rhs)
00102       {
00103          I *tmp = rhs.m_pRaw;
00104          rhs.m_pRaw  = m_pRaw;
00105          m_pRaw      = tmp;
00106       }
00107 
00108       inline I* get() const
00109       {
00110          return reinterpret_cast<I*>(m_pRaw);
00111       }
00112 
00118       void attach(I* pIface)
00119       {
00120          release();
00121          m_pRaw = pIface;
00122       }
00123 
00130       inline I* detach()
00131       {
00132          I* p = m_pRaw;
00133          m_pRaw = NULL;
00134          return p;
00135       }
00136 
00145       inline P6VOID detach(I** ppIface)
00146       {
00147          *ppIface = NULL;
00148          swap(ppIface);
00149       }
00150       
00164       inline P6R::P6ERR createInstance(P6R::p6ICom *pOuter,const P6R::CID &cid,const P6R::IID &riid)
00165       {
00166          release();
00167          return p6CreateInstance(pOuter,cid,riid,reinterpret_cast<P6VOID**>(&m_pRaw));
00168       }
00169 
00179       inline P6R::P6ERR getRuntimeIface(const P6R::IID &riid)
00180       {
00181          release();
00182          return p6GetRuntimeIface(riid,reinterpret_cast<P6VOID**>(&m_pRaw));
00183       }
00184       
00198       template<typename Q> P6R::P6ERR queryInterface(const P6R::IID &riid,Q** ppIface)
00199       {
00200          P6ASSERT(NULL != m_pRaw);
00201          return m_pRaw->queryInterface(riid,reinterpret_cast<P6VOID**>(ppIface));
00202       }
00203       
00204    protected:
00205       I  *m_pRaw;
00206    };
00207 
00214    template<typename I> class p6ComPtr : public p6ComPtrBase<I>
00215    {
00216    public:
00217       typedef I element_type;
00222       explicit p6ComPtr(I* ip = NULL) : p6ComPtrBase<I>(ip)
00223       { }
00224 
00231       p6ComPtr(const P6R::CID &rclsid,const P6R::IID &riid) : p6ComPtrBase<I>(NULL)
00232       { 
00233          P6ERR err = p6ComPtrBase<I>::createInstance(NULL,rclsid,riid);
00234          P6ASSERT(eOk == err);
00235       }
00236 
00237       p6ComPtr(const P6R::IID &riid)
00238       {
00239          P6ERR err = p6ComPtrBase<I>::getRuntimeIface(riid);
00240          P6ASSERT(eOk == err);
00241       }
00242 
00252       p6ComPtr(p6ICom *pCom,const P6R::IID &riid) : p6ComPtrBase<I>(0)
00253       {
00254          p6ComPtr<I> tmp;
00255          P6R::P6ERR err = pCom->queryInterface(riid,(P6VOID**)tmp.addressof());
00256          P6ASSERT(eOk == err);
00257          if(P6SUCCEEDED(err)) p6ComPtrBase<I>::swap(tmp);
00258       }
00259       
00263       p6ComPtr(const p6ComPtr<I>& rSI) : p6ComPtrBase<I>(rSI.m_pRaw)
00264       { }
00265 
00269       p6ComPtr<I>& operator=(I* ip)
00270       {
00271          if(*this != ip) {
00272             p6ComPtr<I> tmp(ip);
00273             swap(tmp);
00274          }
00275          return *this;
00276       }
00277 
00281       p6ComPtr<I>& operator=(const p6ComPtr<I>& cp)
00282       {
00283          if(*this!=cp) {
00284             p6ComPtr<I> tmp(cp);
00285             swap(tmp);
00286          }
00287          return *this;
00288       }
00289    };
00290 
00297    template<> class p6ComPtr<p6ICom> : public p6ComPtrBase<p6ICom>
00298    {
00299    public:
00300       typedef p6ICom element_type;
00301 
00305       p6ComPtr()
00306          :  p6ComPtrBase<p6ICom>(NULL)
00307       {
00308       }
00309       
00313       explicit p6ComPtr(p6ICom *pI)
00314          : p6ComPtrBase<p6ICom>(pI)
00315       {
00316       }
00317       
00321       p6ComPtr(const p6ComPtr<p6ICom> &smartPtr)
00322          : p6ComPtrBase<p6ICom>(smartPtr.m_pRaw)
00323       {
00324       }
00325 
00326       operator p6ICom*() const
00327       {
00328          return get();
00329       }
00330 
00334       p6ComPtr<p6ICom>& operator=(p6ICom* ip)
00335       {
00336          if(*this != ip) {
00337             p6ComPtr<p6ICom> tmp(ip);
00338             swap(tmp);
00339          }
00340          return *this;
00341       }
00342 
00346       p6ComPtr<p6ICom>& operator=(const p6ComPtr<p6ICom>& cp)
00347       {
00348          if(*this!=cp) {
00349             p6ComPtr<p6ICom> tmp(cp);
00350             swap(tmp);
00351          }
00352          return *this;
00353       }
00354    };
00355 
00356 
00392 #define VALIDATECOMPTR(type,smartComPtr) IID_##type, reinterpret_cast<P6R::P6VOID**>(static_cast<type**>((smartComPtr).addressofWithRelease()))
00393 
00394 
00395 
00396 } // namespace
00397 
00398 #endif
00399 
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines
Copyright © 2004 - 2010 P6R Inc. - All Rights Reserved.