| # Gaudi Framework, version v21r11 |

Home |  | Generated: 30 Sep 2010

# SmartRef.h

Go to the documentation of this file.

    00001 //      ====================================================================
    00002 //      SmartRef.h
    00003 //      --------------------------------------------------------------------
    00004 //
    00005 //      Package   : Kernel
    00006 //
    00007 //      Author    : Markus Frank
    00008 //
    00009 //      ====================================================================
    00010 #ifndef KERNEL_SMARTREF_H
    00011 #define KERNEL_SMARTREF_H 1
    00012
    00013 // Include files
    00014 #include "GaudiKernel/SmartRefBase.h"
    00015 #include "GaudiKernel/ContainedObject.h"
    00016
    00017 #include <typeinfo>
    00018
    00019 // Forward declarations
    00020 template <class TYPE> class SmartRefArray;
    00021 template <class TYPE> class SmartRefList;
    00022 template <class TYPE> class SmartRefMap;
    00023
    00062 template <class TYPE> class SmartRef  {
    00064   friend class SmartRefArray<TYPE>;
    00065   friend class SmartRefList<TYPE>;
    00066   friend class SmartRefMap<TYPE>;
    00067
    00068 public:
    00069   enum { VALID = StreamBuffer::VALID, INVALID = StreamBuffer::INVALID };
    00071   typedef TYPE   entry_type;
    00072 protected:
    00073   SmartRefBase        m_base;
    00075   mutable const TYPE* m_target;
    00076 protected:
    00077 public:
    00079   SmartRef()  {
    00080     m_base.m_hintID = INVALID;
    00081     m_base.m_linkID = INVALID;
    00082     m_target = 0;
    00083     _setEnvironment(0, 0);
    00084   }
    00086   SmartRef(TYPE* pObject)  {
    00087     m_base.m_hintID = INVALID;
    00088     m_base.m_linkID = INVALID;
    00089     m_target = pObject;
    00090     _setEnvironment(0, 0);
    00091   }
    00093   SmartRef(const TYPE* pObject)  {
    00094     m_base.m_hintID = INVALID;
    00095     m_base.m_linkID = INVALID;
    00096     m_target = const_cast<TYPE*>(pObject);
    00097     _setEnvironment(0, 0);
    00098   }
    00100   SmartRef(const SmartRef& copy)   {
    00101     m_base.m_hintID = copy.m_base.m_hintID;
    00102     m_base.m_linkID = copy.m_base.m_linkID;
    00103     m_target = copy.m_target;
    00104     _setEnvironment(copy.m_base.m_data, copy.m_base.m_contd);
    00105   }
    00107   SmartRef(long hint, long link, TYPE* obj = 0)   {
    00108     m_base.m_hintID = hint;
    00109     m_base.m_linkID = link;
    00110     m_target = obj;
    00111     _setEnvironment(0, 0);
    00112   }
    00114   SmartRef(const ContainedObject* pObj, long hint, long link, TYPE* obj = 0)   {
    00115     m_base.m_hintID = hint;
    00116     m_base.m_linkID = link;
    00117     m_target = obj;
    00118     const DataObject* src = (0==pObj) ? 0 : pObj->parent();
    00119     _setEnvironment(src, pObj);
    00120   }
    00122   SmartRef(const DataObject* pObj, long hint, long link, TYPE* obj = 0)   {
    00123     m_base.m_hintID = hint;
    00124     m_base.m_linkID = link;
    00125     m_target = obj;
    00126     _setEnvironment(pObj, 0);
    00127   }
    00129   SmartRef(const DataObject* pObj, long hint, TYPE* obj = 0)   {
    00130     m_base.m_hintID = hint;
    00131     m_base.m_linkID = INVALID;
    00132     m_target = obj;
    00133     _setEnvironment(pObj, 0);
    00134   }
    00136   //virtual ~SmartRef()                  {
    00137   //}
    00139   bool shouldFollowLink(const DataObject* /* typ */) const   {
    00140     return (0 == m_target && m_base.m_hintID != INVALID );
    00141   }
    00143   bool shouldFollowLink(const ContainedObject* /* typ */) const   {
    00144     return (0 == m_target && m_base.m_hintID != INVALID && m_base.m_linkID != INVALID );
    00145   }
    00147   long hintID()   const   {
    00148     return m_base.m_hintID;
    00149   }
    00151   long linkID()   const   {
    00152     return m_base.m_linkID;
    00153   }
    00155   void set(DataObject* pObj, long hint_id, long link_id) {
    00156      m_base.set(pObj, hint_id, link_id);
    00157   }
    00159   const std::type_info* type()  const   {
    00160     return &typeid(TYPE);
    00161   }
    00163   TYPE* data()    {
    00164     return const_cast<TYPE*>(m_target);
    00165   }
    00166   const TYPE* data()  const   {
    00167     return m_target;
    00168   }
    00170   const TYPE* target()  const;
    00172   TYPE* target();
    00174   inline const std::string &path() const { return m_base.path(); }
    00176   bool operator==(const SmartRef<TYPE>& c)   const   {
    00177     if ( 0 != m_target && 0 != c.m_target )   {
    00178       return m_target == c.m_target;
    00179     }
    00180     else if ( 0 == m_target && 0 == c.m_target )    {
    00181       return m_base.isEqual(m_target,c.m_base);
    00182     }
    00183     else if ( 0 != m_target && 0 == c.m_target )  {
    00184       return m_base.isEqualEx(m_target, c.m_base);
    00185     }
    00186     else if ( 0 == m_target && 0 != c.m_target )  {
    00187       return c.m_base.isEqualEx(c.m_target, m_base);
    00188     }
    00189     return false;
    00190   }
    00192   bool operator!=(const SmartRef<TYPE>& c)   const   {
    00193     return !(this->operator==(c));
    00194   }
    00196   const SmartRef<TYPE>& _setEnvironment(const DataObject* pObj, const ContainedObject* pContd)  const   {
    00197     m_base.m_data  = pObj;
    00198     m_base.m_contd = pContd;
    00199     m_base.setObjectType(data());
    00200     return *this;
    00201   }
    00203   SmartRef<TYPE>& _setEnvironment(const DataObject* pObj, const ContainedObject* pContd)    {
    00204     m_base.m_data  = pObj;
    00205     m_base.m_contd = pContd;
    00206     m_base.setObjectType(data());
    00207     return *this;
    00208   }
    00210   SmartRef<TYPE>& operator() (ContainedObject* pObj)    {
    00211     const DataObject* src = (0==pObj) ? 0 : pObj->parent();
    00212     return _setEnvironment(src, pObj);
    00213   }
    00215   const SmartRef<TYPE>& operator() (const ContainedObject* pObj)  const  {
    00216     const DataObject* src = (0==pObj) ? 0 : pObj->parent();
    00217     return _setEnvironment(src, pObj);
    00218   }
    00220   SmartRef<TYPE>& operator() (DataObject* pObj)    {
    00221     return _setEnvironment(pObj,0);
    00222   }
    00224   const SmartRef<TYPE>& operator() (const DataObject* pObj)  const  {
    00225     return _setEnvironment(pObj,0);
    00226   }
    00228   SmartRef<TYPE>& operator=(const SmartRef<TYPE>& c)  {
    00229     m_target = c.m_target;
    00230     m_base.m_hintID = c.m_base.m_hintID;
    00231     m_base.m_linkID = c.m_base.m_linkID;
    00232     return _setEnvironment(c.m_base.m_data, c.m_base.m_contd);  }
    00234   SmartRef<TYPE>& operator=(TYPE* pObject)   {
    00235     m_target = pObject;
    00236     m_base.m_hintID = INVALID;
    00237     m_base.m_linkID = INVALID;
    00238     return *this;
    00239   }
    00241   TYPE& operator*()                 {  return *SmartRef<TYPE>::target(); }
    00243   const TYPE& operator*()   const   {  return *SmartRef<TYPE>::target(); }
    00245   TYPE* operator->()                {  return SmartRef<TYPE>::target();  }
    00247   const TYPE* operator->()  const   {  return SmartRef<TYPE>::target();  }
    00249   operator const TYPE* ()  const    {  return SmartRef<TYPE>::target();  }
    00251   operator TYPE* ()                 {  return SmartRef<TYPE>::target();  }
    00253   StreamBuffer& writeRef(StreamBuffer& s)  const;
    00255   StreamBuffer& readRef(StreamBuffer& s);
    00257   // MCl: it is "_s" instead of the most common "s" to avoid a fake icc remark #1599
    00258   friend StreamBuffer& operator<< (StreamBuffer& _s, const SmartRef<TYPE>& ptr)  {
    00259     return ptr.writeRef(_s);
    00260   }
    00262   // MCl: it is "_s" instead of the most common "s" to avoid a fake icc remark #1599
    00263   friend StreamBuffer& operator>> (StreamBuffer& _s, SmartRef<TYPE>& ptr)    {
    00264     return ptr.readRef(_s);
    00265   }
    00266 };
    00267
    00268 //
    00269 // Inline function necessary to be outside the class definition.
    00270 // Mostly this stuff cannot go into the class definition because
    00271 // G++ has problems recognizing proper templates if they are not
    00272 // completely defined.
    00273 //
    00274 // M.Frank
    00275 //
    00276
    00278 template <class TYPE> inline
    00279 TYPE* SmartRef<TYPE>::target()  {
    00280   if ( 0 == m_target )    {
    00281     m_target = dynamic_cast<const TYPE*>(m_base.accessData(m_target));
    00282   }
    00283   return const_cast<TYPE*>(m_target);
    00284 }
    00285
    00287 template <class TYPE> inline
    00288 const TYPE* SmartRef<TYPE>::target()  const  {
    00289   if ( 0 == m_target )    {
    00290     m_target = dynamic_cast<const TYPE*>(m_base.accessData(m_target));
    00291   }
    00292   return m_target;
    00293 }
    00294
    00296 template <class TYPE> inline
    00297 StreamBuffer& SmartRef<TYPE>::writeRef (StreamBuffer& s)    const   {
    00298   m_base.writeObject(m_target, s);
    00299   return s;
    00300 }
    00301
    00303 template <class TYPE> inline
    00304 StreamBuffer& SmartRef<TYPE>::readRef (StreamBuffer& s)   {
    00305   m_target = dynamic_cast<TYPE*>( m_base.readObject(m_target, s) );
    00306   return s;
    00307 }
    00308
    00310 template <class TYPE> inline
    00311 bool operator == (const SmartRef<TYPE>& ref, int)   {
    00312   const TYPE* obj = ref;
    00313   return obj == 0;
    00314 }
    00315
    00317 template <class TYPE> inline
    00318 bool operator == (int, const SmartRef<TYPE>& ref)   {
    00319   const TYPE* obj = ref;
    00320   return obj == 0;
    00321 }
    00322
    00324 template <class TYPE> inline
    00325 bool operator != (const SmartRef<TYPE>& ref, int)   {
    00326   const TYPE* obj = ref;
    00327   return obj != 0;
    00328 }
    00329
    00331 template <class TYPE> inline
    00332 bool operator != (int, const SmartRef<TYPE>& ref)   {
    00333   const TYPE* obj = ref;
    00334   return obj != 0;
    00335 }
    00336
    00337 #endif // KERNEL_SMARTREF_H
    00338
    00339