Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

SmartIF.h

Go to the documentation of this file.
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

Generated at Wed Nov 21 12:22:05 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000