Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 10:00:35

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 //  SmartRefVector.h
0013 //  --------------------------------------------------------------------
0014 //
0015 //  Package   : Kernel
0016 //
0017 //  Author    : Markus Frank
0018 //
0019 //  ====================================================================
0020 #ifndef KERNEL_SMARTREFVECTOR_H
0021 #define KERNEL_SMARTREFVECTOR_H 1
0022 
0023 // STL include files
0024 #include <vector>
0025 
0026 // Include files
0027 #include "GaudiKernel/SmartRef.h"
0028 
0029 // forward declare _object and PyObject to avoid including Python.h here
0030 struct _object;
0031 namespace SmartRefVectorImpl {
0032   using PyObject = _object;
0033   // Avoid leaking the below into global namespace
0034   struct SmartRefVectorPythonizer {
0035     // newer PyROOT will map SmartRefVector<TYPE>& operator()( ContainedObject* pObj )
0036     // to "__getitem__" deleting it via this callback will make `__getitem__` call
0037     //  the operator [] from the base class
0038     //  see e.g. https://github.com/root-project/root/issues/7179
0039     static void __cppyy_pythonize__( PyObject* klass, const std::string& name );
0040   };
0041 } // namespace SmartRefVectorImpl
0042 
0043 /** Kernel objects: SmartRefVector
0044 
0045     Description:
0046     The SmartRefVector class allows transparent handling of multiple object links
0047     within the data store. Links are unloaded a priori and will only be
0048     loaded "on demand", i.e. when dereferenced.
0049 
0050     SmartRefVectors should behave in the same way as normal vectors of pointers;
0051 
0052     Using SmartRefVectors the environment of the vector is automatically
0053     propagated to each contained reference.
0054 
0055     In order to speed things up, an attempt was made to avoid any virtual
0056     functions.
0057 
0058     Base Class:
0059     STL vector
0060 
0061     Dependencies:
0062     <UL>
0063     <LI> Base class:                vector
0064     <LI> SmartRef constructs:       Gaudi/Kernel/SmartRef.h
0065     </UL>
0066 
0067     <P> History    :
0068     <PRE>
0069     +---------+----------------------------------------------+--------+
0070     |    Date |                 Comment                      | Who    |
0071     +---------+----------------------------------------------+--------+
0072     | 12/07/99| Initial version.                             | MF     |
0073     +---------+----------------------------------------------+--------+
0074     </PRE>
0075     Author:  M.Frank
0076     Version: 1.0
0077 */
0078 template <class TYPE>
0079 class SmartRefVector : public std::vector<SmartRef<TYPE>>, SmartRefVectorImpl::SmartRefVectorPythonizer {
0080 protected:
0081   /// That's the type of crap I am hosting
0082   typedef SmartRef<TYPE> _Entry;
0083   /// Object types: typedef myself as Base
0084   typedef std::vector<_Entry>                          _Base;
0085   typedef typename std::vector<_Entry>::const_iterator _BaseConstIter;
0086   typedef typename std::vector<_Entry>::value_type     _BaseValueType;
0087 
0088   /// Object data: Pointer to the identifiable object the link originates
0089   mutable const DataObject* m_data;
0090   /// Object data: Pointer to the Contained object (if applicable)
0091   mutable const ContainedObject* m_contd;
0092 
0093   /// Set the environment for the vector and all contained objects references
0094   void _setEnvironment( const DataObject* pObj, const ContainedObject* pContd ) const {
0095     m_data  = pObj;
0096     m_contd = pContd;
0097     for ( _BaseConstIter i = _Base::begin(); i != _Base::end(); i++ ) { ( *i )._setEnvironment( pObj, pContd ); }
0098   }
0099 
0100 public:
0101   using SmartRefVectorPythonizer::__cppyy_pythonize__;
0102 
0103   /// Standard Constructor
0104   SmartRefVector() {
0105     m_contd = 0;
0106     m_data  = 0;
0107   }
0108   /// templated Constructor
0109   template <class ITERATOR>
0110   SmartRefVector( ITERATOR first, ITERATOR last )
0111       : std::vector<SmartRef<TYPE>>( first, last ), m_data( 0 ), m_contd( 0 ) {}
0112   /// Copy Constructor
0113   SmartRefVector( const SmartRefVector& copy ) : std::vector<SmartRef<TYPE>>( copy ) { *this = copy; }
0114   /// Standard destructor
0115   // virtual ~SmartRefVector()                  {
0116   //}
0117 
0118   /// operator(): assigns parent object for serialisation
0119   SmartRefVector<TYPE>& operator()( ContainedObject* pObj ) {
0120     _setEnvironment( ( 0 == pObj ) ? 0 : pObj->parent(), pObj );
0121     return *this;
0122   }
0123   /// operator() const: assigns parent object for serialisation
0124   const SmartRefVector<TYPE>& operator()( const ContainedObject* pObj ) const {
0125     _setEnvironment( ( 0 == pObj ) ? 0 : pObj->parent(), pObj );
0126     return *this;
0127   }
0128   /// operator(): assigns parent object for serialisation
0129   SmartRefVector<TYPE>& operator()( DataObject* pObj ) {
0130     _setEnvironment( pObj, 0 );
0131     return *this;
0132   }
0133   /// operator() const: assigns parent object for serialisation
0134   const SmartRefVector<TYPE>& operator()( const DataObject* pObj ) const {
0135     _setEnvironment( pObj, 0 );
0136     return *this;
0137   }
0138   /// Assignment
0139   SmartRefVector<TYPE>& operator=( const SmartRefVector<TYPE>& copy ) {
0140     _Base::operator=( copy );
0141     // Harms.... MF
0142     // on copy we MUST make a 1 to 1 copy
0143     // _setEnvironment( copy.m_data, copy.m_contd );
0144     // use instead:
0145     m_data  = copy.m_data;
0146     m_contd = copy.m_contd;
0147     return *this;
0148   }
0149   /// Access to embedded type
0150   const std::type_info* type() const { return &typeid( TYPE ); }
0151   /// Helper to read references
0152   StreamBuffer& readRefs( StreamBuffer& s );
0153   /// Helper to write references
0154   StreamBuffer& writeRefs( StreamBuffer& s ) const;
0155   /// Output Streamer operator
0156   // MCl: it is "_s" instead of the most common "s" to avoid a fake icc remark #1599
0157   friend StreamBuffer& operator<<( StreamBuffer& _s, const SmartRefVector<TYPE>& ptr ) { return ptr.writeRefs( _s ); }
0158   /// Input Streamer operator
0159   // MCl: it is "_s" instead of the most common "s" to avoid a fake icc remark #1599
0160   friend StreamBuffer& operator>>( StreamBuffer& _s, SmartRefVector<TYPE>& ptr ) { return ptr.readRefs( _s ); }
0161 };
0162 
0163 template <class TYPE>
0164 inline StreamBuffer& SmartRefVector<TYPE>::writeRefs( StreamBuffer& s ) const {
0165   long len = _Base::size();
0166   s << len;
0167   for ( _BaseConstIter i = _Base::begin(); i != _Base::end(); i++ ) {
0168     ( *i )._setEnvironment( m_data, m_contd );
0169     ( *i ).writeRef( s );
0170   }
0171   return s;
0172 }
0173 
0174 template <class TYPE>
0175 inline StreamBuffer& SmartRefVector<TYPE>::readRefs( StreamBuffer& s ) {
0176   long len;
0177   _Base::erase( _Base::begin(), _Base::end() );
0178   s >> len;
0179   for ( long i = 0; i < len; i++ ) {
0180     _BaseValueType entry;
0181     entry._setEnvironment( m_data, m_contd );
0182     entry.readRef( s );
0183     _Base::push_back( entry );
0184   }
0185   return s;
0186 }
0187 
0188 #endif // KERNEL_SMARTREFVECTOR_H