00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef KERNEL_SMARTREF_H
00011 #define KERNEL_SMARTREF_H 1
00012
00013
00014 #include "GaudiKernel/SmartRefBase.h"
00015 #include "GaudiKernel/ContainedObject.h"
00016
00017 #include <typeinfo>
00018
00019
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
00137
00139 bool shouldFollowLink(const DataObject* ) const {
00140 return (0 == m_target && m_base.m_hintID != INVALID );
00141 }
00143 bool shouldFollowLink(const ContainedObject* ) 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
00268
00269
00270
00271
00272
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