File indexing completed on 2025-01-31 10:09:05
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, int ) { return ref.target() == nullptr; }
0172 friend bool operator==( const SmartRef<TYPE>& ref, std::nullptr_t ) { return ref.target() == nullptr; }
0173
0174
0175 friend bool operator==( int, const SmartRef<TYPE>& ref ) { return ref.target() == nullptr; }
0176 friend bool operator==( std::nullptr_t, const SmartRef<TYPE>& ref ) { return ref.target() == nullptr; }
0177
0178 bool operator!=( const SmartRef<TYPE>& c ) const { return !( this->operator==( c ) ); }
0179
0180 friend bool operator!=( const SmartRef<TYPE>& ref, int ) { return ref.target() != nullptr; }
0181
0182 friend bool operator!=( const SmartRef<TYPE>& ref, std::nullptr_t ) { return ref.target() != nullptr; }
0183
0184
0185 friend bool operator!=( int, const SmartRef<TYPE>& ref ) { return ref.target() != nullptr; }
0186
0187 friend bool operator!=( std::nullptr_t, const SmartRef<TYPE>& ref ) { return ref.target() != nullptr; }
0188
0189
0190 explicit operator bool() const { return target() != nullptr; }
0191
0192
0193 const SmartRef<TYPE>& _setEnvironment( const DataObject* pObj, const ContainedObject* pContd ) const {
0194 m_base.m_data = pObj;
0195 m_base.m_contd = pContd;
0196 m_base.setObjectType( data() );
0197 return *this;
0198 }
0199
0200 SmartRef<TYPE>& _setEnvironment( const DataObject* pObj, const ContainedObject* pContd ) {
0201 m_base.m_data = pObj;
0202 m_base.m_contd = pContd;
0203 m_base.setObjectType( data() );
0204 return *this;
0205 }
0206
0207 SmartRef<TYPE>& operator()( ContainedObject* pObj ) {
0208 const DataObject* src = ( pObj ? pObj->parent() : nullptr );
0209 return _setEnvironment( src, pObj );
0210 }
0211
0212 const SmartRef<TYPE>& operator()( const ContainedObject* pObj ) const {
0213 const DataObject* src = ( pObj ? pObj->parent() : nullptr );
0214 return _setEnvironment( src, pObj );
0215 }
0216
0217 SmartRef<TYPE>& operator()( DataObject* pObj ) { return _setEnvironment( pObj, nullptr ); }
0218
0219 const SmartRef<TYPE>& operator()( const DataObject* pObj ) const { return _setEnvironment( pObj, nullptr ); }
0220
0221 SmartRef<TYPE>& operator=( const SmartRef<TYPE>& c ) {
0222 m_target = c.m_target;
0223 m_base.m_hintID = c.m_base.m_hintID;
0224 m_base.m_linkID = c.m_base.m_linkID;
0225 return _setEnvironment( c.m_base.m_data, c.m_base.m_contd );
0226 }
0227
0228 SmartRef<TYPE>& operator=( const TYPE* pObject ) {
0229 m_target = pObject;
0230 m_base.m_hintID = INVALID;
0231 m_base.m_linkID = INVALID;
0232 return *this;
0233 }
0234
0235 TYPE& operator*() { return *SmartRef<TYPE>::target(); }
0236
0237 const TYPE& operator*() const { return *SmartRef<TYPE>::target(); }
0238
0239 TYPE* operator->() { return SmartRef<TYPE>::target(); }
0240
0241 const TYPE* operator->() const { return SmartRef<TYPE>::target(); }
0242
0243 operator const TYPE*() const { return SmartRef<TYPE>::target(); }
0244
0245 operator TYPE*() { return SmartRef<TYPE>::target(); }
0246
0247 StreamBuffer& writeRef( StreamBuffer& s ) const {
0248 m_base.writeObject( m_target, s );
0249 return s;
0250 }
0251
0252 StreamBuffer& readRef( StreamBuffer& s ) {
0253 m_target = dynamic_cast<const TYPE*>( m_base.readObject( m_target, s ) );
0254 return s;
0255 }
0256
0257
0258 friend StreamBuffer& operator<<( StreamBuffer& _s, const SmartRef<TYPE>& ptr ) { return ptr.writeRef( _s ); }
0259
0260
0261 friend StreamBuffer& operator>>( StreamBuffer& _s, SmartRef<TYPE>& ptr ) { return ptr.readRef( _s ); }
0262 };
0263
0264 #endif