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
00042 I* pTmp = m_pRaw;
00043
00044 m_pRaw = NULL;
00045 if(pTmp) {
00046 pTmp->release();
00047 }
00048 }
00049
00050
00051
00052
00053
00054
00055
00056
00057
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 }
00397
00398 #endif
00399