SmartRef.h
Go to the documentation of this file.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
00258 friend StreamBuffer& operator<< (StreamBuffer& _s, const SmartRef<TYPE>& ptr) {
00259 return ptr.writeRef(_s);
00260 }
00262
00263 friend StreamBuffer& operator>> (StreamBuffer& _s, SmartRef<TYPE>& ptr) {
00264 return ptr.readRef(_s);
00265 }
00266 };
00267
00268
00269
00270
00271
00272
00273
00274
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