File indexing completed on 2025-07-02 08:34:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #ifndef KERNEL_SMARTREF_H
0021 #define KERNEL_SMARTREF_H 1
0022
0023
0024 #include <GaudiKernel/ContainedObject.h>
0025 #include <GaudiKernel/SmartRefBase.h>
0026
0027 #include <typeinfo>
0028
0029
0030 template <class TYPE>
0031 class SmartRefArray;
0032 template <class TYPE>
0033 class SmartRefList;
0034 template <class TYPE>
0035 class SmartRefMap;
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075 template <class TYPE>
0076 class SmartRef final {
0077
0078 friend class SmartRefArray<TYPE>;
0079 friend class SmartRefList<TYPE>;
0080 friend class SmartRefMap<TYPE>;
0081
0082 SmartRefBase m_base;
0083
0084 mutable const TYPE* m_target = nullptr;
0085
0086 public:
0087 enum { VALID = StreamBuffer::VALID, INVALID = StreamBuffer::INVALID };
0088
0089 typedef TYPE entry_type;
0090
0091
0092 SmartRef( const TYPE* pObject = nullptr ) {
0093 m_base.m_hintID = INVALID;
0094 m_base.m_linkID = INVALID;
0095 m_target = pObject;
0096 _setEnvironment( nullptr, nullptr );
0097 }
0098
0099 SmartRef( const SmartRef& copy ) {
0100 m_base.m_hintID = copy.m_base.m_hintID;
0101 m_base.m_linkID = copy.m_base.m_linkID;
0102 m_target = copy.m_target;
0103 _setEnvironment( copy.m_base.m_data, copy.m_base.m_contd );
0104 }
0105
0106 SmartRef( long hint, long link, const TYPE* obj = nullptr ) {
0107 m_base.m_hintID = hint;
0108 m_base.m_linkID = link;
0109 m_target = obj;
0110 _setEnvironment( nullptr, nullptr );
0111 }
0112
0113 SmartRef( const ContainedObject* pObj, long hint, long link, const TYPE* obj = nullptr ) {
0114 m_base.m_hintID = hint;
0115 m_base.m_linkID = link;
0116 m_target = obj;
0117 const DataObject* src = ( pObj ? pObj->parent() : nullptr );
0118 _setEnvironment( src, pObj );
0119 }
0120
0121 SmartRef( const DataObject* pObj, long hint, long link, const TYPE* obj = nullptr ) {
0122 m_base.m_hintID = hint;
0123 m_base.m_linkID = link;
0124 m_target = obj;
0125 _setEnvironment( pObj, nullptr );
0126 }
0127
0128 SmartRef( const DataObject* pObj, long hint, const TYPE* obj = nullptr ) {
0129 m_base.m_hintID = hint;
0130 m_base.m_linkID = INVALID;
0131 m_target = obj;
0132 _setEnvironment( pObj, nullptr );
0133 }
0134
0135 bool shouldFollowLink( const DataObject* ) const { return !m_target && m_base.m_hintID != INVALID; }
0136
0137 bool shouldFollowLink( const ContainedObject* ) const {
0138 return !m_target && m_base.m_hintID != INVALID && m_base.m_linkID != INVALID;
0139 }
0140
0141 long hintID() const { return m_base.m_hintID; }
0142
0143 long linkID() const { return m_base.m_linkID; }
0144
0145 void set( DataObject* pObj, long hint_id, long link_id ) { m_base.set( pObj, hint_id, link_id ); }
0146
0147 const std::type_info* type() const { return &typeid( TYPE ); }
0148
0149 TYPE* data() { return const_cast<TYPE*>( m_target ); }
0150 const TYPE* data() const { return m_target; }
0151
0152 const TYPE* target() const {
0153 if ( !m_target ) { m_target = dynamic_cast<const TYPE*>( m_base.accessData( m_target ) ); }
0154 return m_target;
0155 }
0156
0157 TYPE* target() {
0158 if ( !m_target ) { m_target = dynamic_cast<const TYPE*>( m_base.accessData( m_target ) ); }
0159 return const_cast<TYPE*>( m_target );
0160 }
0161
0162 const std::string& path() const { return m_base.path(); }
0163
0164 bool operator==( const SmartRef<TYPE>& c ) const {
0165 if ( m_target && c.m_target ) return m_target == c.m_target;
0166 if ( !m_target && !c.m_target ) return m_base.isEqual( m_target, c.m_base );
0167 if ( m_target && !c.m_target ) return m_base.isEqualEx( m_target, c.m_base );
0168 if ( !m_target && c.m_target ) return c.m_base.isEqualEx( c.m_target, m_base );
0169 return false;
0170 }
0171 friend bool operator==( const SmartRef<TYPE>& ref, std::nullptr_t ) { return ref.target() == nullptr; }
0172
0173
0174 friend bool operator==( std::nullptr_t, const SmartRef<TYPE>& ref ) { return ref.target() == nullptr; }
0175
0176 bool operator!=( const SmartRef<TYPE>& c ) const { return !( this->operator==( c ) ); }
0177
0178 friend bool operator!=( const SmartRef<TYPE>& ref, std::nullptr_t ) { return ref.target() != nullptr; }
0179
0180
0181 friend bool operator!=( std::nullptr_t, const SmartRef<TYPE>& ref ) { return ref.target() != nullptr; }
0182
0183
0184 explicit operator bool() const { return target() != nullptr; }
0185
0186
0187 const SmartRef<TYPE>& _setEnvironment( const DataObject* pObj, const ContainedObject* pContd ) const {
0188 m_base.m_data = pObj;
0189 m_base.m_contd = pContd;
0190 m_base.setObjectType( data() );
0191 return *this;
0192 }
0193
0194 SmartRef<TYPE>& _setEnvironment( const DataObject* pObj, const ContainedObject* pContd ) {
0195 m_base.m_data = pObj;
0196 m_base.m_contd = pContd;
0197 m_base.setObjectType( data() );
0198 return *this;
0199 }
0200
0201 SmartRef<TYPE>& operator()( ContainedObject* pObj ) {
0202 const DataObject* src = ( pObj ? pObj->parent() : nullptr );
0203 return _setEnvironment( src, pObj );
0204 }
0205
0206 const SmartRef<TYPE>& operator()( const ContainedObject* pObj ) const {
0207 const DataObject* src = ( pObj ? pObj->parent() : nullptr );
0208 return _setEnvironment( src, pObj );
0209 }
0210
0211 SmartRef<TYPE>& operator()( DataObject* pObj ) { return _setEnvironment( pObj, nullptr ); }
0212
0213 const SmartRef<TYPE>& operator()( const DataObject* pObj ) const { return _setEnvironment( pObj, nullptr ); }
0214
0215 SmartRef<TYPE>& operator=( const SmartRef<TYPE>& c ) {
0216 m_target = c.m_target;
0217 m_base.m_hintID = c.m_base.m_hintID;
0218 m_base.m_linkID = c.m_base.m_linkID;
0219 return _setEnvironment( c.m_base.m_data, c.m_base.m_contd );
0220 }
0221
0222 SmartRef<TYPE>& operator=( const TYPE* pObject ) {
0223 m_target = pObject;
0224 m_base.m_hintID = INVALID;
0225 m_base.m_linkID = INVALID;
0226 return *this;
0227 }
0228
0229 TYPE& operator*() { return *SmartRef<TYPE>::target(); }
0230
0231 const TYPE& operator*() const { return *SmartRef<TYPE>::target(); }
0232
0233 TYPE* operator->() { return SmartRef<TYPE>::target(); }
0234
0235 const TYPE* operator->() const { return SmartRef<TYPE>::target(); }
0236
0237 operator const TYPE*() const { return SmartRef<TYPE>::target(); }
0238
0239 operator TYPE*() { return SmartRef<TYPE>::target(); }
0240
0241 StreamBuffer& writeRef( StreamBuffer& s ) const {
0242 m_base.writeObject( m_target, s );
0243 return s;
0244 }
0245
0246 StreamBuffer& readRef( StreamBuffer& s ) {
0247 m_target = dynamic_cast<const TYPE*>( m_base.readObject( m_target, s ) );
0248 return s;
0249 }
0250
0251
0252 friend StreamBuffer& operator<<( StreamBuffer& _s, const SmartRef<TYPE>& ptr ) { return ptr.writeRef( _s ); }
0253
0254
0255 friend StreamBuffer& operator>>( StreamBuffer& _s, SmartRef<TYPE>& ptr ) { return ptr.readRef( _s ); }
0256 };
0257
0258 #endif