![]() |
|
|||
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
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |