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
00016
00017 template <class TYPE> class SmartRefArray;
00018 template <class TYPE> class SmartRefList;
00019 template <class TYPE> class SmartRefMap;
00020
00058 template <class TYPE> class SmartRef : protected SmartRefBase {
00060 friend class SmartRefArray<TYPE>;
00061 friend class SmartRefList<TYPE>;
00062 friend class SmartRefMap<TYPE>;
00063
00064 public:
00065 enum { VALID = StreamBuffer::VALID, INVALID = StreamBuffer::INVALID };
00067 typedef TYPE entry_type;
00068 protected:
00070 mutable const TYPE* m_target;
00071 protected:
00072 public:
00074 SmartRef() {
00075 m_hintID = INVALID;
00076 m_linkID = INVALID;
00077 m_target = 0;
00078 _setEnvironment(0, 0);
00079 }
00081 SmartRef(TYPE* pObject) {
00082 m_hintID = INVALID;
00083 m_linkID = INVALID;
00084 m_target = pObject;
00085 _setEnvironment(0, 0);
00086 }
00088 SmartRef(const TYPE* pObject) {
00089 m_hintID = INVALID;
00090 m_linkID = INVALID;
00091 m_target = const_cast<TYPE*>(pObject);
00092 _setEnvironment(0, 0);
00093 }
00095 SmartRef(const SmartRef& copy) {
00096 m_hintID = copy.m_hintID;
00097 m_linkID = copy.m_linkID;
00098 m_target = copy.m_target;
00099 _setEnvironment(copy.m_data, copy.m_contd);
00100 }
00102 SmartRef(long hint, long link, TYPE* obj = 0) {
00103 m_hintID = hint;
00104 m_linkID = link;
00105 m_target = obj;
00106 _setEnvironment(0, 0);
00107 }
00109 SmartRef(const ContainedObject* pObj, long hint, long link, TYPE* obj = 0) {
00110 m_hintID = hint;
00111 m_linkID = link;
00112 m_target = obj;
00113 const DataObject* src = (0==pObj) ? 0 : pObj->parent();
00114 _setEnvironment(src, pObj);
00115 }
00117 SmartRef(const DataObject* pObj, long hint, long link, TYPE* obj = 0) {
00118 m_hintID = hint;
00119 m_linkID = link;
00120 m_target = obj;
00121 _setEnvironment(pObj, 0);
00122 }
00124 SmartRef(const DataObject* pObj, long hint, TYPE* obj = 0) {
00125 m_hintID = hint;
00126 m_linkID = INVALID;
00127 m_target = obj;
00128 _setEnvironment(pObj, 0);
00129 }
00131
00132
00134
00135 return (0 == m_target && m_hintID != INVALID );
00136 }
00138 bool shouldFollowLink(const ContainedObject* typ) const {
00139 return (0 == m_target && m_hintID != INVALID && m_linkID != INVALID );
00140 }
00142 long hintID() const {
00143 return m_hintID;
00144 }
00146 long linkID() const {
00147 return m_linkID;
00148 }
00149 TYPE* data() {
00150 return m_target;
00151 }
00152 const TYPE* data() const {
00153 return m_target;
00154 }
00156 const TYPE* target() const;
00158 TYPE* target();
00160 bool operator==(const SmartRef<TYPE>& c) const {
00161 return SmartRefBase::isEqual(m_target,c) || (m_target== c.m_target && 0 != m_target);
00162 }
00164 const SmartRef<TYPE>& _setEnvironment(const DataObject* pObj, const ContainedObject* pContd) const {
00165 m_data = pObj;
00166 m_contd = pContd;
00167 return *this;
00168 }
00170 SmartRef<TYPE>& _setEnvironment(const DataObject* pObj, const ContainedObject* pContd) {
00171 m_data = pObj;
00172 m_contd = pContd;
00173 return *this;
00174 }
00176 SmartRef<TYPE>& operator() (ContainedObject* pObj) {
00177 const DataObject* src = (0==pObj) ? 0 : pObj->parent();
00178 return _setEnvironment(src, pObj);
00179 }
00181 const SmartRef<TYPE>& operator() (const ContainedObject* pObj) const {
00182 const DataObject* src = (0==pObj) ? 0 : pObj->parent();
00183 return _setEnvironment(src, pObj);
00184 }
00186 SmartRef<TYPE>& operator() (DataObject* pObj) {
00187 return _setEnvironment(pObj,0);
00188 }
00190 const SmartRef<TYPE>& operator() (const DataObject* pObj) const {
00191 return _setEnvironment(pObj,0);
00192 }
00194 SmartRef<TYPE>& operator=(const SmartRef<TYPE>& c) {
00195 m_target = c.m_target;
00196 m_hintID = c.m_hintID;
00197 m_linkID = c.m_linkID;
00198 return _setEnvironment(c.m_data, c.m_contd);
00199 }
00201 SmartRef<TYPE>& operator=(TYPE* pObject) { m_target = pObject; return *this; }
00203 TYPE& operator*() { return *SmartRef<TYPE>::target(); }
00205 const TYPE& operator*() const { return *SmartRef<TYPE>::target(); }
00207 TYPE* operator->() { return SmartRef<TYPE>::target(); }
00209 const TYPE* operator->() const { return SmartRef<TYPE>::target(); }
00211 operator const TYPE* () const { return SmartRef<TYPE>::target(); }
00213 operator TYPE* () { return SmartRef<TYPE>::target(); }
00215 StreamBuffer& writeRef(StreamBuffer& s) const;
00217 StreamBuffer& readRef(StreamBuffer& s);
00219 friend StreamBuffer& operator<< (StreamBuffer& s, const SmartRef<TYPE>& ptr) {
00220 return ptr.writeRef(s);
00221 }
00223 friend StreamBuffer& operator>> (StreamBuffer& s, SmartRef<TYPE>& ptr) {
00224 return ptr.readRef(s);
00225 }
00226 };
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00238 template <class TYPE> inline
00239 TYPE* SmartRef<TYPE>::target() {
00240 if ( 0 == m_target ) {
00241 m_target = dynamic_cast<const TYPE*>(SmartRefBase::accessData(m_target));
00242 }
00243 return const_cast<TYPE*>(m_target);
00244 }
00245
00247 template <class TYPE> inline
00248 const TYPE* SmartRef<TYPE>::target() const {
00249 if ( 0 == m_target ) {
00250 m_target = dynamic_cast<const TYPE*>(SmartRefBase::accessData(m_target));
00251 }
00252 return m_target;
00253 }
00254
00256 template <class TYPE> inline
00257 StreamBuffer& SmartRef<TYPE>::writeRef (StreamBuffer& s) const {
00258 SmartRefBase::writeObject(m_target, s);
00259 return s;
00260 }
00261
00263 template <class TYPE> inline
00264 StreamBuffer& SmartRef<TYPE>::readRef (StreamBuffer& s) {
00265 m_target = dynamic_cast<TYPE*>( SmartRefBase::readObject(m_target, s) );
00266 return s;
00267 }
00268
00270 template <class TYPE> inline
00271 bool operator != (const SmartRef<TYPE>& ref, int) {
00272 const TYPE* obj = ref;
00273 return obj != 0;
00274 }
00275
00277 template <class TYPE> inline
00278 bool operator != (int, const SmartRef<TYPE>& ref) {
00279 const TYPE* obj = ref;
00280 return obj != 0;
00281 }
00282
00283 #endif // KERNEL_SMARTREF_H
00284
00285