Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:09:05

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
0003 *                                                                                   *
0004 * This software is distributed under the terms of the Apache version 2 licence,     *
0005 * copied verbatim in the file "LICENSE".                                            *
0006 *                                                                                   *
0007 * In applying this licence, CERN does not waive the privileges and immunities       *
0008 * granted to it by virtue of its status as an Intergovernmental Organization        *
0009 * or submit itself to any jurisdiction.                                             *
0010 \***********************************************************************************/
0011 //  ====================================================================
0012 //  SmartRef.h
0013 //  --------------------------------------------------------------------
0014 //
0015 //  Package   : Kernel
0016 //
0017 //  Author    : Markus Frank
0018 //
0019 //  ====================================================================
0020 #ifndef KERNEL_SMARTREF_H
0021 #define KERNEL_SMARTREF_H 1
0022 
0023 // Include files
0024 #include "GaudiKernel/ContainedObject.h"
0025 #include "GaudiKernel/SmartRefBase.h"
0026 
0027 #include <typeinfo>
0028 
0029 // Forward declarations
0030 template <class TYPE>
0031 class SmartRefArray;
0032 template <class TYPE>
0033 class SmartRefList;
0034 template <class TYPE>
0035 class SmartRefMap;
0036 
0037 /** Kernel objects: SmartRef
0038 
0039     Description:
0040     The SmartRef class allows transparent handling of object links
0041     within the data store. Links are unloaded a priori and will only be
0042     loaded "on demand", i.e. when dereferenced.
0043 
0044     SmartRefs should behave in the same way as normal pointers;
0045     The SmartRef object in fact is a smart pointer construct intercepting
0046     the dereference operators.
0047 
0048     When loading, the executed code resides in the non templated base class.
0049     This ensures, that the templated code is minimized and code blow up is
0050     inhibited.
0051 
0052     Using SmartRefs StreamBuffers are able to also save the references
0053     on data conversion requests.
0054 
0055     Base Class:
0056     SmartRefBase
0057 
0058     Dependencies:
0059     <UL>
0060     <LI> Base class:         GaudiKernel/SmartRefBase.h
0061     </UL>
0062 
0063     <P> History    :
0064     <PRE>
0065     +---------+----------------------------------------------+--------+
0066     |    Date |                 Comment                      | Who    |
0067     +---------+----------------------------------------------+--------+
0068     | 21/04/99| Initial version.                             | MF     |
0069     | 16/01/04| Move base class into aggregation.            | MF     |
0070     +---------+----------------------------------------------+--------+
0071     </PRE>
0072     Author:  M.Frank
0073     Version: 1.0
0074 */
0075 template <class TYPE>
0076 class SmartRef final {
0077   /// The container must be a friend
0078   friend class SmartRefArray<TYPE>;
0079   friend class SmartRefList<TYPE>;
0080   friend class SmartRefMap<TYPE>;
0081 
0082   SmartRefBase m_base;
0083   /// Pointer to target data object
0084   mutable const TYPE* m_target = nullptr;
0085 
0086 public:
0087   enum { VALID = StreamBuffer::VALID, INVALID = StreamBuffer::INVALID };
0088   /// Entry type definition
0089   typedef TYPE entry_type;
0090 
0091   /// Standard Constructor
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   /// Copy Constructor
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   /// Constructor
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   /// Constructor for references to contained objects passing environment
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   /// Constructor for references to contained objects passing environment
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   /// Constructor for references to DataObjects passing environment
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   /// Check if link should be followed: link must be valid and object not yet loaded
0135   bool shouldFollowLink( const DataObject* ) const { return !m_target && m_base.m_hintID != INVALID; }
0136   /// Check if link should be followed: link must be valid and object not yet loaded
0137   bool shouldFollowLink( const ContainedObject* ) const {
0138     return !m_target && m_base.m_hintID != INVALID && m_base.m_linkID != INVALID;
0139   }
0140   /// Access hint id:
0141   long hintID() const { return m_base.m_hintID; }
0142   /// Access link id:
0143   long linkID() const { return m_base.m_linkID; }
0144   /// Setup smart reference when reading. Must be allowed from external sources.
0145   void set( DataObject* pObj, long hint_id, long link_id ) { m_base.set( pObj, hint_id, link_id ); }
0146   /// Access to embedded type
0147   const std::type_info* type() const { return &typeid( TYPE ); }
0148   /// Access to raw data pointer
0149   TYPE*       data() { return const_cast<TYPE*>( m_target ); }
0150   const TYPE* data() const { return m_target; }
0151   /// Access to the object
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   /// Access to the object
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   /// Return the path of the linked object inside the data store.
0162   const std::string& path() const { return m_base.path(); }
0163   /// Equality operator
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   /*[[deprecated]]*/ 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   /// Friend helper to check for object existence (will load object)
0175   /*[[deprecated]]*/ 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   /// NON-Equality operator
0178   bool operator!=( const SmartRef<TYPE>& c ) const { return !( this->operator==( c ) ); }
0179 
0180   /*[[deprecated]]*/ 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   /// Friend helper to check for object existence (will load object)
0185   /*[[deprecated]]*/ 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   /// explicit conversion to bool to check for object existence (will load object)
0190   explicit operator bool() const { return target() != nullptr; }
0191 
0192   /// Set the environment (CONST)
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   /// Set the environment (CONST)
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   /// operator(): assigns parent object for serialisation
0207   SmartRef<TYPE>& operator()( ContainedObject* pObj ) {
0208     const DataObject* src = ( pObj ? pObj->parent() : nullptr );
0209     return _setEnvironment( src, pObj );
0210   }
0211   /// operator() const: assigns parent object for serialisation
0212   const SmartRef<TYPE>& operator()( const ContainedObject* pObj ) const {
0213     const DataObject* src = ( pObj ? pObj->parent() : nullptr );
0214     return _setEnvironment( src, pObj );
0215   }
0216   /// operator(): assigns parent object for serialisation
0217   SmartRef<TYPE>& operator()( DataObject* pObj ) { return _setEnvironment( pObj, nullptr ); }
0218   /// operator() const: assigns parent object for serialisation
0219   const SmartRef<TYPE>& operator()( const DataObject* pObj ) const { return _setEnvironment( pObj, nullptr ); }
0220   /// Assignment
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   /// Assignment
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   /// Dereference operator
0235   TYPE& operator*() { return *SmartRef<TYPE>::target(); }
0236   /// Dereference operator
0237   const TYPE& operator*() const { return *SmartRef<TYPE>::target(); }
0238   /// Dereference operator
0239   TYPE* operator->() { return SmartRef<TYPE>::target(); }
0240   /// Dereference operator to const object
0241   const TYPE* operator->() const { return SmartRef<TYPE>::target(); }
0242   /// Implicit type conversion to const object
0243   operator const TYPE*() const { return SmartRef<TYPE>::target(); }
0244   /// Implicit type conversion
0245   operator TYPE*() { return SmartRef<TYPE>::target(); }
0246   /// Write the reference to the stream buffer (needed due to stupid G++ compiler)
0247   StreamBuffer& writeRef( StreamBuffer& s ) const {
0248     m_base.writeObject( m_target, s );
0249     return s;
0250   }
0251   /// Read the reference from the stream buffer (needed due to stupid G++ compiler)
0252   StreamBuffer& readRef( StreamBuffer& s ) {
0253     m_target = dynamic_cast<const TYPE*>( m_base.readObject( m_target, s ) );
0254     return s;
0255   }
0256   /// Output Streamer operator
0257   // MCl: it is "_s" instead of the most common "s" to avoid a fake icc remark #1599
0258   friend StreamBuffer& operator<<( StreamBuffer& _s, const SmartRef<TYPE>& ptr ) { return ptr.writeRef( _s ); }
0259   /// Input Streamer operator
0260   // MCl: it is "_s" instead of the most common "s" to avoid a fake icc remark #1599
0261   friend StreamBuffer& operator>>( StreamBuffer& _s, SmartRef<TYPE>& ptr ) { return ptr.readRef( _s ); }
0262 };
0263 
0264 #endif // KERNEL_SMARTREF_H