![]() |
|
|
Generated: 18 Jul 2008 |
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 // Forward declarations 00018 template <class TYPE> class SmartRefArray; 00019 template <class TYPE> class SmartRefList; 00020 template <class TYPE> class SmartRefMap; 00021 00060 template <class TYPE> class SmartRef { 00062 friend class SmartRefArray<TYPE>; 00063 friend class SmartRefList<TYPE>; 00064 friend class SmartRefMap<TYPE>; 00065 00066 public: 00067 enum { VALID = StreamBuffer::VALID, INVALID = StreamBuffer::INVALID }; 00069 typedef TYPE entry_type; 00070 protected: 00071 SmartRefBase m_base; 00073 mutable const TYPE* m_target; 00074 protected: 00075 public: 00077 SmartRef() { 00078 m_base.m_hintID = INVALID; 00079 m_base.m_linkID = INVALID; 00080 m_target = 0; 00081 _setEnvironment(0, 0); 00082 } 00084 SmartRef(TYPE* pObject) { 00085 m_base.m_hintID = INVALID; 00086 m_base.m_linkID = INVALID; 00087 m_target = pObject; 00088 _setEnvironment(0, 0); 00089 } 00091 SmartRef(const TYPE* pObject) { 00092 m_base.m_hintID = INVALID; 00093 m_base.m_linkID = INVALID; 00094 m_target = const_cast<TYPE*>(pObject); 00095 _setEnvironment(0, 0); 00096 } 00098 SmartRef(const SmartRef& copy) { 00099 m_base.m_hintID = copy.m_base.m_hintID; 00100 m_base.m_linkID = copy.m_base.m_linkID; 00101 m_target = copy.m_target; 00102 _setEnvironment(copy.m_base.m_data, copy.m_base.m_contd); 00103 } 00105 SmartRef(long hint, long link, TYPE* obj = 0) { 00106 m_base.m_hintID = hint; 00107 m_base.m_linkID = link; 00108 m_target = obj; 00109 _setEnvironment(0, 0); 00110 } 00112 SmartRef(const ContainedObject* pObj, long hint, long link, TYPE* obj = 0) { 00113 m_base.m_hintID = hint; 00114 m_base.m_linkID = link; 00115 m_target = obj; 00116 const DataObject* src = (0==pObj) ? 0 : pObj->parent(); 00117 _setEnvironment(src, pObj); 00118 } 00120 SmartRef(const DataObject* pObj, long hint, long link, TYPE* obj = 0) { 00121 m_base.m_hintID = hint; 00122 m_base.m_linkID = link; 00123 m_target = obj; 00124 _setEnvironment(pObj, 0); 00125 } 00127 SmartRef(const DataObject* pObj, long hint, TYPE* obj = 0) { 00128 m_base.m_hintID = hint; 00129 m_base.m_linkID = INVALID; 00130 m_target = obj; 00131 _setEnvironment(pObj, 0); 00132 } 00134 //virtual ~SmartRef() { 00135 //} 00137 bool shouldFollowLink(const DataObject* /* typ */) const { 00138 return (0 == m_target && m_base.m_hintID != INVALID ); 00139 } 00141 bool shouldFollowLink(const ContainedObject* /* typ */) const { 00142 return (0 == m_target && m_base.m_hintID != INVALID && m_base.m_linkID != INVALID ); 00143 } 00145 long hintID() const { 00146 return m_base.m_hintID; 00147 } 00149 long linkID() const { 00150 return m_base.m_linkID; 00151 } 00153 void set(DataObject* pObj, long hint_id, long link_id) { 00154 m_base.set(pObj, hint_id, link_id); 00155 } 00157 const std::type_info* type() const { 00158 return &typeid(TYPE); 00159 } 00161 TYPE* data() { 00162 return const_cast<TYPE*>(m_target); 00163 } 00164 const TYPE* data() const { 00165 return m_target; 00166 } 00168 const TYPE* target() const; 00170 TYPE* target(); 00172 inline const std::string &path() const { return m_base.path(); } 00174 bool operator==(const SmartRef<TYPE>& c) const { 00175 if ( 0 != m_target && 0 != c.m_target ) { 00176 return m_target == c.m_target; 00177 } 00178 else if ( 0 == m_target && 0 == c.m_target ) { 00179 return m_base.isEqual(m_target,c.m_base); 00180 } 00181 else if ( 0 != m_target && 0 == c.m_target ) { 00182 return m_base.isEqualEx(m_target, c.m_base); 00183 } 00184 else if ( 0 == m_target && 0 != c.m_target ) { 00185 return c.m_base.isEqualEx(c.m_target, m_base); 00186 } 00187 return false; 00188 } 00190 bool operator!=(const SmartRef<TYPE>& c) const { 00191 return !(this->operator==(c)); 00192 } 00194 const SmartRef<TYPE>& _setEnvironment(const DataObject* pObj, const ContainedObject* pContd) const { 00195 m_base.m_data = pObj; 00196 m_base.m_contd = pContd; 00197 m_base.setObjectType(data()); 00198 return *this; 00199 } 00201 SmartRef<TYPE>& _setEnvironment(const DataObject* pObj, const ContainedObject* pContd) { 00202 m_base.m_data = pObj; 00203 m_base.m_contd = pContd; 00204 m_base.setObjectType(data()); 00205 return *this; 00206 } 00208 SmartRef<TYPE>& operator() (ContainedObject* pObj) { 00209 const DataObject* src = (0==pObj) ? 0 : pObj->parent(); 00210 return _setEnvironment(src, pObj); 00211 } 00213 const SmartRef<TYPE>& operator() (const ContainedObject* pObj) const { 00214 const DataObject* src = (0==pObj) ? 0 : pObj->parent(); 00215 return _setEnvironment(src, pObj); 00216 } 00218 SmartRef<TYPE>& operator() (DataObject* pObj) { 00219 return _setEnvironment(pObj,0); 00220 } 00222 const SmartRef<TYPE>& operator() (const DataObject* pObj) const { 00223 return _setEnvironment(pObj,0); 00224 } 00226 SmartRef<TYPE>& operator=(const SmartRef<TYPE>& c) { 00227 m_target = c.m_target; 00228 m_base.m_hintID = c.m_base.m_hintID; 00229 m_base.m_linkID = c.m_base.m_linkID; 00230 return _setEnvironment(c.m_base.m_data, c.m_base.m_contd); } 00232 SmartRef<TYPE>& operator=(TYPE* pObject) { 00233 m_target = pObject; 00234 m_base.m_hintID = INVALID; 00235 m_base.m_linkID = INVALID; 00236 return *this; 00237 } 00239 TYPE& operator*() { return *SmartRef<TYPE>::target(); } 00241 const TYPE& operator*() const { return *SmartRef<TYPE>::target(); } 00243 TYPE* operator->() { return SmartRef<TYPE>::target(); } 00245 const TYPE* operator->() const { return SmartRef<TYPE>::target(); } 00247 operator const TYPE* () const { return SmartRef<TYPE>::target(); } 00249 operator TYPE* () { return SmartRef<TYPE>::target(); } 00251 StreamBuffer& writeRef(StreamBuffer& s) const; 00253 StreamBuffer& readRef(StreamBuffer& s); 00255 friend StreamBuffer& operator<< (StreamBuffer& s, const SmartRef<TYPE>& ptr) { 00256 return ptr.writeRef(s); 00257 } 00259 friend StreamBuffer& operator>> (StreamBuffer& s, SmartRef<TYPE>& ptr) { 00260 return ptr.readRef(s); 00261 } 00262 }; 00263 00264 // 00265 // Inline function necessary to be outside the class definition. 00266 // Mostly this stuff cannot go into the class definition because 00267 // G++ has problems recognizing proper templates if they are not 00268 // completely defined. 00269 // 00270 // M.Frank 00271 // 00272 00274 template <class TYPE> inline 00275 TYPE* SmartRef<TYPE>::target() { 00276 if ( 0 == m_target ) { 00277 m_target = dynamic_cast<const TYPE*>(m_base.accessData(m_target)); 00278 } 00279 return const_cast<TYPE*>(m_target); 00280 } 00281 00283 template <class TYPE> inline 00284 const TYPE* SmartRef<TYPE>::target() const { 00285 if ( 0 == m_target ) { 00286 m_target = dynamic_cast<const TYPE*>(m_base.accessData(m_target)); 00287 } 00288 return m_target; 00289 } 00290 00292 template <class TYPE> inline 00293 StreamBuffer& SmartRef<TYPE>::writeRef (StreamBuffer& s) const { 00294 m_base.writeObject(m_target, s); 00295 return s; 00296 } 00297 00299 template <class TYPE> inline 00300 StreamBuffer& SmartRef<TYPE>::readRef (StreamBuffer& s) { 00301 m_target = dynamic_cast<TYPE*>( m_base.readObject(m_target, s) ); 00302 return s; 00303 } 00304 00306 template <class TYPE> inline 00307 bool operator == (const SmartRef<TYPE>& ref, int) { 00308 const TYPE* obj = ref; 00309 return obj == 0; 00310 } 00311 00313 template <class TYPE> inline 00314 bool operator == (int, const SmartRef<TYPE>& ref) { 00315 const TYPE* obj = ref; 00316 return obj == 0; 00317 } 00318 00320 template <class TYPE> inline 00321 bool operator != (const SmartRef<TYPE>& ref, int) { 00322 const TYPE* obj = ref; 00323 return obj != 0; 00324 } 00325 00327 template <class TYPE> inline 00328 bool operator != (int, const SmartRef<TYPE>& ref) { 00329 const TYPE* obj = ref; 00330 return obj != 0; 00331 } 00332 00333 #endif // KERNEL_SMARTREF_H 00334 00335