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 #ifndef GAUDIKERNEL_SHAREDOBJECTSCONTAINER_H
0012 #define GAUDIKERNEL_SHAREDOBJECTSCONTAINER_H 1
0013 // ============================================================================
0014 // Include files
0015 // ============================================================================
0016 // STD & STL
0017 // ============================================================================
0018 #include <algorithm>
0019 #include <vector>
0020 // ============================================================================
0021 // GaudiKernel
0022 // ============================================================================
0023 #include "GaudiKernel/ClassID.h"
0024 #include "GaudiKernel/Kernel.h"
0025 #include "GaudiKernel/ObjectContainerBase.h"
0026 // ============================================================================
0027 /** @class SharedObjectsContainer GaudiKernel/SharedObjectsContainer.h
0028  *
0029  *  Very simple class to represent the container of objects which are
0030  *  not owned by this container. This concept seem to be very useful for
0031  *  LHCb HLT, DaVinci, tracking, alignments.
0032  *
0033  *  @warning the container is not persistable (on-purpose)
0034  *
0035  *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0036  *  @date   2008-07-23
0037  */
0038 template <class TYPE>
0039 class SharedObjectsContainer : public ObjectContainerBase {
0040 public:
0041   // ==========================================================================
0042   /// the actual container type
0043   typedef std::vector<const TYPE*> ConstVector;
0044   /// various types (to make STL happy)
0045   typedef typename ConstVector::value_type             value_type;
0046   typedef typename ConstVector::size_type              size_type;
0047   typedef typename ConstVector::reference              reference;
0048   typedef typename ConstVector::const_reference        const_reference;
0049   typedef typename ConstVector::iterator               iterator;
0050   typedef typename ConstVector::const_iterator         const_iterator;
0051   typedef typename ConstVector::reverse_iterator       reverse_iterator;
0052   typedef typename ConstVector::const_reverse_iterator const_reverse_iterator;
0053   // ==========================================================================
0054 public:
0055   // ==========================================================================
0056   // the default constructor (creates the empty vector)
0057   SharedObjectsContainer() = default;
0058   // move constructor and move assignement
0059   SharedObjectsContainer( SharedObjectsContainer&& )            = default;
0060   SharedObjectsContainer& operator=( SharedObjectsContainer&& ) = default;
0061   // the constructor from the data
0062   SharedObjectsContainer( const ConstVector& data ) : m_data( data ) {}
0063   SharedObjectsContainer( ConstVector&& data ) : m_data( std::move( data ) ) {}
0064 
0065   /** the templated constructor from the pair of iterators
0066    *  @param first 'begin'-iterator of the input sequence
0067    *  @param last  'last'-iterator of the input sequence
0068    */
0069   template <class DATA>
0070   SharedObjectsContainer( DATA first, DATA last ) : m_data( first, last ) {}
0071   /** the templated constructor from the pair of iterators and the predicate.
0072    *
0073    *  Only the elements which satisfy the criteria goes into the container
0074    *  e.g. create the container only with "basic" particles:
0075    *
0076    *  @code
0077    *
0078    *   typedef SharedObjectsContainer<LHCb::Particle>  PARTICLES ;
0079    *
0080    *   // some sequence of someting, convertiblle to "const LHCb::Particle*":
0081    *   SEQUENCE source = ... ;
0082    *
0083    *   PARTICLES* particles = new PARTICLES
0084    *          ( source.begin() ,
0085    *            source.end  () ,
0086    *            std::mem_fun(&LHCb::Particle::isBasic) ) ;
0087    *
0088    *  @endcode
0089    *
0090    *  @param first 'begin'-iterator if the input sequence
0091    *  @param last  'last'-iterator of the input sequence
0092    *  @param cut   pre predicate
0093    */
0094   template <class DATA, class PREDICATE>
0095   SharedObjectsContainer( DATA first, DATA last, const PREDICATE& cut ) {
0096     insert( first, last, cut );
0097   }
0098   // ==========================================================================
0099 public:
0100   // ==========================================================================
0101   /// Retrieve the unique class ID (virtual)
0102   const CLID& clID() const override { return SharedObjectsContainer<TYPE>::classID(); }
0103   /// Retrieve the unuqie class ID (static)
0104   static const CLID& classID() {
0105     static const CLID s_clid = ( ( static_cast<CLID>( -1 ) << 16 )    // 16 used and 16 empty bits
0106                                  & !CLID_ObjectVector                 // not an ObjectVector
0107                                  & !CLID_ObjectList                   // not an ObjectList
0108                                  & !static_cast<CLID>( 0x00030000 )   // not a  KeyedContainer/map
0109                                  & !static_cast<CLID>( 0x00040000 ) ) // not a  KeyedContainer/hashmap
0110                                + TYPE::classID();                     // the specific CLID from the contents
0111     //
0112     return s_clid;
0113   }
0114   // ==========================================================================
0115 public:
0116   // ==========================================================================
0117   /// get the access to the underlying container (const)
0118   inline const ConstVector& data() const { return m_data; }
0119   /// cast to the underlying container
0120   operator const ConstVector&() const { return data(); }
0121   // ==========================================================================
0122 public:
0123   // ==========================================================================
0124   /// get the actual size of the container
0125   size_type size() const { return m_data.size(); }
0126   /// empty container?
0127   bool empty() const { return m_data.empty(); }
0128   /** insert one object into the container
0129    *  @param object object to be added
0130    */
0131   void push_back( const TYPE* object ) { m_data.push_back( object ); }
0132   /** insert one object into the container
0133    *  @param object object to be added
0134    */
0135   void insert( const TYPE* object ) { m_data.push_back( object ); }
0136   /** add the sequence of objects into the container
0137    *  @param first 'begin'-iterator for the sequnce
0138    *  @param last  'end'-iterator for the sequence
0139    */
0140   template <class DATA>
0141   void insert( DATA first, DATA last ) {
0142     m_data.insert( end(), first, last );
0143   }
0144   /** add the sequence of 'good'objects into the container
0145    *
0146    *  Only the objects which satisfy the predicate go to the container,
0147    *  e.g. put into container only particles which transverse momentum
0148    *  in excess of 1 * GeV:
0149    *  @code
0150    *
0151    *   namespace bl = boost::lambda ;
0152    *   typedef SharedObjectsContainer<LHCb::Particle>  PARTICLES ;
0153    *
0154    *   // some sequence of someting, convertible to "const LHCb::Particle*":
0155    *   SEQUENCE source = ... ;
0156    *
0157    *   PARTICLES* particles = ... ;
0158    *
0159    *   particles -> insert
0160    *         ( source.begin() ,
0161    *           source.end  () ,
0162    *           bl::bind(&LHCb::Particle::pt,bl::_1) > 1 * Gaudi::Units::GeV ) ;
0163    *
0164    *  @endcode
0165    *
0166    *  @param first 'begin'-iterator for the sequnce
0167    *  @param last  'end'-iterator for the sequence
0168    *  @param cut    the predicate to be applied
0169    */
0170   template <class DATA, class PREDICATE>
0171   void insert( DATA first, DATA last, const PREDICATE& cut ) {
0172     m_data.reserve( m_data.size() + std::distance( first, last ) );
0173     std::copy_if( first, last, std::back_inserter( m_data ), std::cref( cut ) );
0174   }
0175   /** get from the container all objects which satisfy the certain criteria
0176    *
0177    *  E.g. get all particles with transverse momentum in excess of 1 * GeV
0178    *
0179    *  @code
0180    *
0181    *   namespace bl = boost::lambda ;
0182    *   typedef SharedObjectsContainer<LHCb::Particle>  PARTICLES ;
0183    *   typedef std::vector<const LHCb::Particle*>      TARGET    ;
0184    *
0185    *   PARTICLES* particles = ... ;
0186    *
0187    *   TARGET target ;
0188    *
0189    *   particles -> get
0190    *         ( bl::bind(&LHCb::Particle::pt,bl::_1) > 1 * Gaudi::Units::GeV ,
0191    *           std::back_inserter ( target ) ) ;
0192    *
0193    *  @endcode
0194    *
0195    *  @param cut the predicate
0196    *  @param outptut the output iterator
0197    *  @return the current position of the output itrator (almost useless)
0198    */
0199   template <class OUTPUT, class PREDICATE>
0200   OUTPUT get( const PREDICATE& cut, OUTPUT output ) const {
0201     return std::copy_if( begin(), end(), output, std::cref( cut ) );
0202   }
0203   /// erase the object by iterator
0204   void erase( iterator i ) { m_data.erase( i ); }
0205   /** erase the objects which satisfy the criteria
0206    *
0207    *  E.g. remove all particles with small transverse momentum
0208    *
0209    *  @code
0210    *
0211    *   namespace bl = boost::lambda ;
0212    *   typedef SharedObjectsContainer<LHCb::Particle>  PARTICLES ;
0213    *
0214    *   PARTICLES* particles = ... ;
0215    *   particles -> erase
0216    *         ( bl::bind(&LHCb::Particle::pt,bl::_1) < 1 * Gaudi::Units::GeV ) ;
0217    *
0218    *  @endcode
0219    *  @see std::remove_if
0220    *  @param cut predicate
0221    */
0222   template <class PREDICATE>
0223   void erase( const PREDICATE& cut ) {
0224     m_data.erase( std::remove_if( begin(), end(), cut ), end() );
0225   }
0226   /** erase the first occurance of the certain element
0227    *
0228    *  To remove <b>all</b> occurances one can use:
0229    *  @code
0230    *
0231    *   typedef SharedObjectsContainer<LHCb::Particle>  PARTICLES ;
0232    *   PARTICLES* particles = ... ;
0233    *
0234    *   const LHCb::Particle* B = ... ;
0235    *
0236    *   // remove all occurances
0237    *   while ( particles -> erase ( B ) ) {} ;
0238    *
0239    *  @endcode
0240    *
0241    *  @param object the element to be removed
0242    *  @return true if the element is removed
0243    */
0244   bool erase( const TYPE* object ) {
0245     auto i = std::find( begin(), end(), object );
0246     if ( end() == i ) { return false; }
0247     m_data.erase( i );
0248     return true;
0249   }
0250   // ==========================================================================
0251 public:
0252   // ==========================================================================
0253   /// index access
0254   reference operator[]( size_type index ) { return m_data[index]; }
0255   /// index access (const-version)
0256   const_reference operator[]( size_type index ) const { return m_data[index]; }
0257   /// 'functional'-access
0258   reference operator()( size_type index ) { return m_data[index]; }
0259   /// 'functional'-access  (const version)
0260   const_reference operator()( size_type index ) const { return m_data[index]; }
0261   /// checked access
0262   reference at( size_type index ) { return m_data.at( index ); }
0263   /// checked access (const-version)
0264   const_reference at( size_type index ) const { return m_data.at( index ); }
0265   // ==========================================================================
0266 public:
0267   // ==========================================================================
0268   iterator               begin() { return m_data.begin(); }
0269   iterator               end() { return m_data.end(); }
0270   const_iterator         begin() const { return m_data.begin(); }
0271   const_iterator         end() const { return m_data.end(); }
0272   reverse_iterator       rbegin() { return m_data.rbegin(); }
0273   reverse_iterator       rend() { return m_data.rend(); }
0274   const_reverse_iterator rbegin() const { return m_data.rbegin(); }
0275   const_reverse_iterator rend() const { return m_data.rend(); }
0276   // ==========================================================================
0277 public:
0278   // ==========================================================================
0279   /// the first element (only for non-empty vectors)
0280   reference front() { return m_data.front(); }
0281   /// the first element (only for non-empty vectors) (const-version)
0282   const_reference front() const { return m_data.front(); }
0283   /// the last  element (only for non-empty vectors)
0284   reference back() { return m_data.back(); }
0285   /// the last  element (only for non-empty vectors) (const-version)
0286   const_reference back() const { return m_data.back(); }
0287   // ==========================================================================
0288 public:
0289   // ==========================================================================
0290   /// equal content with other container ?
0291   bool operator==( const SharedObjectsContainer& right ) const { return &right == this || right.m_data == m_data; }
0292   /// equal content with corresponding vector ?
0293   bool operator==( const ConstVector& right ) const { return m_data == right; }
0294   /// comparisons with other container
0295   bool operator<( const SharedObjectsContainer& right ) const { return m_data < right.m_data; }
0296   /// comparisons with corresponding vector
0297   bool operator<( const ConstVector& right ) const { return m_data < right; }
0298   // ==========================================================================
0299   // ObjectContainerBase methods:
0300   // ==========================================================================
0301 public:
0302   /** Distance of a given object from the beginning of its container
0303    *  @param object the object to be checked
0304    */
0305   long index( const ContainedObject* object ) const override {
0306     auto _i = std::find( begin(), end(), object );
0307     return end() != _i ? ( _i - begin() ) : -1; // RETURN
0308   }
0309   /** Pointer to an object of a given distance
0310    *  @param index th eindex to be checked
0311    *  @return the object
0312    */
0313   const ContainedObject* containedObject( long index ) const override {
0314     if ( 0 > index || !( index < (long)size() ) ) { return nullptr; } // RETURN
0315     return m_data[index];
0316   }
0317   ContainedObject* containedObject( long index ) override {
0318     if ( 0 > index || !( index < (long)size() ) ) { return nullptr; } // RETURN
0319     return &const_cast<TYPE&>( *m_data[index] );
0320   }
0321   /// Number of objects in the container
0322   size_type numberOfObjects() const override { return m_data.size(); }
0323   /** Virtual functions (forwards to the concrete container definitions)
0324    *  Add an object to the container. On success the object's index is
0325    *  returned.
0326    */
0327   long add( ContainedObject* object ) override {
0328     if ( !object ) { return -1; } // RETURN
0329     TYPE* _obj = dynamic_cast<TYPE*>( object );
0330     if ( !_obj ) { return -1; } // RETURN
0331     const size_type pos = size();
0332     push_back( _obj );
0333     return pos;
0334   }
0335   /** Release object from the container (the pointer will be removed
0336    *  from the container, but the object itself will remain alive).
0337    *  If the object was found it's index is returned.
0338    */
0339   long remove( ContainedObject* value ) override {
0340     auto _i = std::find( begin(), end(), value );
0341     if ( end() == _i ) { return -1; } // RETURN
0342     const size_type pos = _i - begin();
0343     m_data.erase( _i );
0344     return pos; // RETURN
0345   }
0346   // ==========================================================================
0347 private:
0348   // ==========================================================================
0349   // the actual data
0350   ConstVector m_data; // the actual data
0351   // ==========================================================================
0352 };
0353 // ============================================================================
0354 // The END
0355 // ============================================================================
0356 #endif // GAUDIKERNEL_SHAREDOBJECTSCONTAINER_H