00001 // $Id: SmartIF.h,v 1.10 2008/10/27 19:22:20 marcocle Exp $ 00002 #ifndef GAUDI_SMARTIF_H 00003 #define GAUDI_SMARTIF_H 1 00004 00005 // Framework include files 00006 #include "GaudiKernel/IInterface.h" 00007 00008 // Forward declarations 00009 template <class TYPE> class SmartIF; 00010 template <> class SmartIF<IInterface>; 00011 template <class TYPE> class SmartIFBase; 00012 00031 template <class TYPE> class SmartIFBase { 00032 protected: 00033 const InterfaceID m_iid; 00034 TYPE* m_interface; 00036 void releaseInterface() { 00037 if ( m_interface ) m_interface->release(); 00038 m_interface = 0; 00039 } 00041 SmartIFBase(const InterfaceID& iid) : m_iid(iid), m_interface(0) { 00042 } 00044 virtual ~SmartIFBase() { 00045 releaseInterface(); 00046 } 00047 public: 00049 bool isValid() const { 00050 return ( 0 != m_interface ); 00051 } 00053 operator TYPE* () { 00054 return m_interface; 00055 } 00057 operator const TYPE* () const { 00058 return m_interface; 00059 } 00061 bool operator !=(const TYPE* test) const { 00062 return test != m_interface; 00063 } 00065 bool operator ==(const TYPE* test) const { 00066 return test == m_interface; 00067 } 00069 TYPE* operator->() { 00070 return m_interface; 00071 } 00073 const TYPE* operator->() const { 00074 return m_interface; 00075 } 00077 void** operator & () { 00078 return (void**) &m_interface; 00079 } 00081 const TYPE* get() { 00082 return m_interface; 00083 } 00085 TYPE*& pRef() { 00086 return this->m_interface; 00087 } 00089 const TYPE* const & pRef() const { 00090 return this->m_interface; 00091 } 00093 bool operator!() const { return !(this->isValid()) ; } 00094 private: 00095 // disable copy 00096 SmartIFBase( const SmartIFBase& copy ); 00097 // disable assignement 00098 SmartIFBase& operator=( const SmartIFBase& right ) ; 00099 }; 00100 00120 template <class TYPE> class SmartIF : public SmartIFBase<TYPE> { 00121 public: 00123 SmartIF(const InterfaceID& iid, IInterface* iface) : SmartIFBase<TYPE>(iid) { 00124 SmartIF<TYPE>::operator=(iface); 00125 } 00127 SmartIF(const InterfaceID& iid, TYPE* iface) : SmartIFBase<TYPE>(iid) { 00128 SmartIF<TYPE>::operator=(iface); 00129 } 00131 SmartIF(const InterfaceID& iid) : SmartIFBase<TYPE>(iid) { 00132 } 00134 SmartIF ( TYPE* iface ) : SmartIFBase<TYPE>(TYPE::interfaceID()) { 00135 SmartIF<TYPE>::operator=(iface); 00136 } 00138 SmartIF(IInterface* iface = 0) : SmartIFBase<TYPE>(TYPE::interfaceID()) { 00139 SmartIF<TYPE>::operator=(iface); 00140 } 00142 SmartIF( const SmartIF<TYPE>& copy) : SmartIFBase<TYPE>(copy.m_iid) { 00143 SmartIF<TYPE>::operator=(copy.m_interface); 00144 } 00146 virtual ~SmartIF() { 00147 } 00149 SmartIF<TYPE>& operator = (int /* iface = 0*/) { 00150 this->releaseInterface(); 00151 this->m_interface = 0; 00152 return *this; 00153 } 00155 template <class T> 00156 SmartIF<TYPE>& operator = ( const SmartIF<T>& iface ) 00157 { 00158 T* ptr = iface.m_interface ; 00159 if ( (void*)ptr != (void*)this->m_interface ) 00160 { 00161 TYPE* newIF = 0; 00162 if ( ptr != 0 ) { 00163 ptr->queryInterface(this->m_iid, pp_cast<void>(&newIF)).ignore(); 00164 } 00165 this->releaseInterface(); 00166 this->m_interface = newIF; 00167 } 00168 return *this; 00169 } 00171 SmartIF<TYPE>& operator = ( const SmartIF<TYPE>& iface) 00172 { 00173 TYPE* newIF = iface.m_interface ; 00174 return (*this)=newIF ; 00175 } 00177 SmartIF& operator = (IInterface* iface) 00178 { 00179 if ( iface != this->m_interface ) 00180 { 00181 TYPE* newIF = 0; 00182 if ( iface != 0 ) { 00183 iface->queryInterface(this->m_iid, pp_cast<void>(&newIF)).ignore(); 00184 } 00185 this->releaseInterface(); 00186 this->m_interface = newIF; 00187 } 00188 return *this; 00189 } 00191 SmartIF<TYPE>& operator = (TYPE* iface) 00192 { 00193 if ( iface != this->m_interface ) { 00194 if ( iface != 0 ) { 00195 iface->addRef(); 00196 } 00197 this->releaseInterface(); 00198 this->m_interface = iface; 00199 } 00200 return *this; 00201 } 00203 bool operator!() const { return !(this->isValid()) ; } 00204 }; 00205 00228 template <> class SmartIF<IInterface> : public SmartIFBase<IInterface> { 00229 public: 00230 typedef IInterface TYPE; 00232 SmartIF( const SmartIF<IInterface>& copy) 00233 : SmartIFBase<IInterface>(copy.m_iid) 00234 { 00235 SmartIF<TYPE>::operator=(copy.m_interface); 00236 } 00238 SmartIF(IInterface* iface = 0) 00239 : SmartIFBase<IInterface>(IID_IInterface) 00240 { 00241 SmartIF<TYPE>::operator=(iface); 00242 } 00244 template <class T> 00245 SmartIF( const SmartIF<T>& right ) 00246 : SmartIFBase<IInterface>(IID_IInterface) 00247 { 00248 SmartIF<TYPE>::operator=(right.m_interface); 00249 } 00251 virtual ~SmartIF() { 00252 } 00254 template <class T> 00255 SmartIF<TYPE>& operator = ( const SmartIF<T>& iface) 00256 { 00257 T* ptr = iface.m_interface ; 00258 if ( (void*)ptr != (void*)this->m_interface ) { 00259 TYPE* newIF = 0; 00260 if ( ptr != 0 ) { 00261 ptr->queryInterface(this->m_iid, (void**)&newIF).ignore(); 00262 } 00263 this->releaseInterface(); 00264 this->m_interface = newIF; 00265 } 00266 return *this; 00267 } 00269 SmartIF<TYPE>& operator = ( const SmartIF<TYPE>& iface) { 00270 TYPE* newIF = iface.m_interface ; 00271 return (*this)=newIF ; 00272 } 00274 SmartIF<TYPE>& operator = (TYPE* iface) { 00275 if ( iface != m_interface ) { 00276 if ( iface != 0 ) { 00277 iface->addRef(); 00278 } 00279 releaseInterface(); 00280 m_interface = iface; 00281 } 00282 return *this; 00283 } 00285 bool operator!() const { return !(this->isValid()) ; } 00286 }; 00287 00288 #endif // GAUDI_SMARTIF_H