![]() |
|
|
Generated: 8 Jan 2009 |
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 friend StreamBuffer& operator<< (StreamBuffer& s, const SmartRef<TYPE>& ptr) { 00258 return ptr.writeRef(s); 00259 } 00261 friend StreamBuffer& operator>> (StreamBuffer& s, SmartRef<TYPE>& ptr) { 00262 return ptr.readRef(s); 00263 } 00264 }; 00265 00266 // 00267 // Inline function necessary to be outside the class definition. 00268 // Mostly this stuff cannot go into the class definition because 00269 // G++ has problems recognizing proper templates if they are not 00270 // completely defined. 00271 // 00272 // M.Frank 00273 // 00274 00276 template <class TYPE> inline 00277 TYPE* SmartRef<TYPE>::target() { 00278 if ( 0 == m_target ) { 00279 m_target = dynamic_cast<const TYPE*>(m_base.accessData(m_target)); 00280 } 00281 return const_cast<TYPE*>(m_target); 00282 } 00283 00285 template <class TYPE> inline 00286 const TYPE* SmartRef<TYPE>::target() const { 00287 if ( 0 == m_target ) { 00288 m_target = dynamic_cast<const TYPE*>(m_base.accessData(m_target)); 00289 } 00290 return m_target; 00291 } 00292 00294 template <class TYPE> inline 00295 StreamBuffer& SmartRef<TYPE>::writeRef (StreamBuffer& s) const { 00296 m_base.writeObject(m_target, s); 00297 return s; 00298 } 00299 00301 template <class TYPE> inline 00302 StreamBuffer& SmartRef<TYPE>::readRef (StreamBuffer& s) { 00303 m_target = dynamic_cast<TYPE*>( m_base.readObject(m_target, s) ); 00304 return s; 00305 } 00306 00308 template <class TYPE> inline 00309 bool operator == (const SmartRef<TYPE>& ref, int) { 00310 const TYPE* obj = ref; 00311 return obj == 0; 00312 } 00313 00315 template <class TYPE> inline 00316 bool operator == (int, const SmartRef<TYPE>& ref) { 00317 const TYPE* obj = ref; 00318 return obj == 0; 00319 } 00320 00322 template <class TYPE> inline 00323 bool operator != (const SmartRef<TYPE>& ref, int) { 00324 const TYPE* obj = ref; 00325 return obj != 0; 00326 } 00327 00329 template <class TYPE> inline 00330 bool operator != (int, const SmartRef<TYPE>& ref) { 00331 const TYPE* obj = ref; 00332 return obj != 0; 00333 } 00334 00335 #endif // KERNEL_SMARTREF_H 00336 00337