00001 //==================================================================== 00002 // SmartIF.h 00003 //-------------------------------------------------------------------- 00004 // 00005 // Package : Gaudi/Kernel (The LHCb Application Manager) 00006 // 00007 // Description: Smart pointer class to handle interfaces 00008 // 00009 // Author : M.Frank 00010 // Created : 30/10/98 00011 // 00012 //==================================================================== 00013 #ifndef GAUDI_SMARTIF_H 00014 #define GAUDI_SMARTIF_H 1 00015 00016 // Framework include files 00017 #include "GaudiKernel/IInterface.h" 00018 00019 // Forward declarations 00020 template <class TYPE> class SmartIF; 00021 template <> class SmartIF<IInterface>; 00022 template <class TYPE> class SmartIFBase; 00023 00047 template <class TYPE> class SmartIFBase { 00048 protected: 00049 const IID m_iid; 00050 TYPE* m_interface; 00052 void releaseInterface() { 00053 if ( m_interface ) m_interface->release(); 00054 m_interface = 0; 00055 } 00057 SmartIFBase(const IID& iid) : m_iid(iid), m_interface(0) { 00058 } 00060 virtual ~SmartIFBase() { 00061 releaseInterface(); 00062 } 00063 public: 00065 bool isValid() const { 00066 return ( 0 != m_interface ); 00067 } 00069 operator TYPE* () { 00070 return m_interface; 00071 } 00073 operator const TYPE* () const { 00074 return m_interface; 00075 } 00077 bool operator !() const { 00078 return 0 == m_interface; 00079 } 00081 operator bool() const { 00082 return 0 != m_interface; 00083 } 00085 bool operator !=(const TYPE* test) const { 00086 return test != m_interface; 00087 } 00089 bool operator ==(const TYPE* test) const { 00090 return test == m_interface; 00091 } 00093 TYPE* operator->() { 00094 return m_interface; 00095 } 00097 const TYPE* operator->() const { 00098 return m_interface; 00099 } 00101 void** operator & () { 00102 return (void**) &m_interface; 00103 } 00104 }; 00105 00125 template <class TYPE> class SmartIF : public SmartIFBase<TYPE> { 00126 public: 00128 SmartIF(const IID& iid, IInterface* iface) : SmartIFBase<TYPE>(iid) { 00129 SmartIF<TYPE>::operator=(iface); 00130 } 00132 SmartIF(const IID& iid, TYPE* iface) : SmartIFBase<TYPE>(iid) { 00133 SmartIF<TYPE>::operator=(iface); 00134 } 00136 SmartIF(const IID& iid) : SmartIFBase<TYPE>(iid) { 00137 } 00139 SmartIF(TYPE* iface = 0) : SmartIFBase<TYPE>(IID_IInterface) { 00140 SmartIF<TYPE>::operator=(iface); 00141 } 00143 SmartIF(SmartIF<TYPE>& copy) : SmartIFBase<TYPE>(copy.m_iid) { 00144 SmartIF<TYPE>::operator=(copy.m_interface); 00145 } 00147 virtual ~SmartIF() { 00148 } 00150 SmartIF& operator = (IInterface* iface) { 00151 if ( iface != m_interface ) { 00152 TYPE* newIF = 0; 00153 if ( iface != 0 ) { 00154 iface->queryInterface(m_iid, (void**)&newIF); 00155 } 00156 releaseInterface(); 00157 m_interface = newIF; 00158 } 00159 return *this; 00160 } 00162 SmartIFBase<TYPE>& operator = (TYPE* iface) { 00163 if ( iface != m_interface ) { 00164 if ( iface != 0 ) { 00165 iface->addRef(); 00166 } 00167 releaseInterface(); 00168 m_interface = iface; 00169 } 00170 return *this; 00171 } 00173 template <class T> SmartIFBase<TYPE>& operator = (SmartIFBase<T>& iface) { 00174 T* ptr = iface.operator->(); 00175 if ( (void*)ptr != (void*)m_interface ) { 00176 TYPE* newIF = 0; 00177 if ( ptr != 0 ) { 00178 ptr->queryInterface(m_iid, (void**)&newIF); 00179 } 00180 releaseInterface(); 00181 m_interface = newIF; 00182 } 00183 return *this; 00184 } 00186 SmartIFBase<TYPE>& operator = (SmartIFBase<TYPE>& iface) { 00187 TYPE* newIF = iface.operator->(); 00188 if ( (void*)newIF != (void*)m_interface ) { 00189 newIF->addRef(); 00190 releaseInterface(); 00191 m_interface = newIF; 00192 } 00193 return *this; 00194 } 00196 TYPE*& pRef() { 00197 return m_interface; 00198 } 00200 const TYPE* const & pRef() const { 00201 return m_interface; 00202 } 00203 }; 00204 00227 template <> class SmartIF<IInterface> : public SmartIFBase<IInterface> { 00228 public: 00229 typedef IInterface TYPE; 00231 SmartIF(SmartIF<IInterface>& copy) 00232 : SmartIFBase<IInterface>(copy.m_iid) 00233 { 00234 SmartIF<TYPE>::operator=(copy.m_interface); 00235 } 00237 SmartIF(IInterface* iface = 0) 00238 : SmartIFBase<IInterface>(IID_IInterface) 00239 { 00240 SmartIF<TYPE>::operator=(iface); 00241 } 00243 virtual ~SmartIF() { 00244 } 00246 template <class T> SmartIFBase<TYPE>& operator = (SmartIFBase<T>& iface) { 00247 T* ptr = iface.operator->(); 00248 if ( (void*)ptr != (void*)m_interface ) { 00249 TYPE* newIF = 0; 00250 if ( ptr != 0 ) { 00251 ptr->queryInterface(m_iid, (void**)&newIF); 00252 } 00253 releaseInterface(); 00254 m_interface = newIF; 00255 } 00256 return *this; 00257 } 00259 SmartIFBase<TYPE>& operator = (SmartIFBase<TYPE>& iface) { 00260 TYPE* newIF = iface.operator->(); 00261 if ( (void*)newIF != (void*)m_interface ) { 00262 newIF->addRef(); 00263 releaseInterface(); 00264 m_interface = newIF; 00265 } 00266 return *this; 00267 } 00269 SmartIFBase<TYPE>& operator = (TYPE* iface) { 00270 if ( iface != m_interface ) { 00271 if ( iface != 0 ) { 00272 iface->addRef(); 00273 } 00274 releaseInterface(); 00275 m_interface = iface; 00276 } 00277 return *this; 00278 } 00280 IInterface* & pRef() { 00281 return m_interface; 00282 } 00284 const IInterface* const & pRef() const { 00285 return m_interface; 00286 } 00287 }; 00288 00289 #endif // GAUDI_SMARTIF_H
1.2.3 written by Dimitri van Heesch,
© 1997-2000