Back to home page

EIC code displayed by LXR

 
 

    


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

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_OBJECTVECTOR_H
0012 #define GAUDIKERNEL_OBJECTVECTOR_H
0013 
0014 // Include files
0015 #include "GaudiKernel/ClassID.h"
0016 #include "GaudiKernel/Kernel.h"
0017 #include "GaudiKernel/ObjectContainerBase.h"
0018 #include "GaudiKernel/StreamBuffer.h"
0019 
0020 #include <iomanip>
0021 #include <vector>
0022 
0023 // Definition of the CLID for this class defined in ClassID.h
0024 // static const CLID CLID_ObjectList = (1<<17);  // ObjectVector   (bit 17 set)
0025 
0026 /** @class ObjectVector ObjectVector.h GaudiKernel/ObjectVector.h
0027     ObjectVector is one of the basic Gaudi container classes capable of being
0028     registered in Data Stores.
0029     It is based on Standard Library (STL) std::vector
0030     (see <A HREF="http://www.sgi.com/Technology/STL/">STL Programmer's Guide</A>)
0031     ObjectVector has all functions of the std::vector interface,
0032     and in addition a number of Gaudi specific functions.
0033 
0034     Each object is allowed to belong into a single container only.
0035     After inserting the object into the container, it takes over
0036     all responsibilities for the object.  E.g. erasing the object
0037     from its container causes removing the object's pointer from
0038     the container and deleting the object itself.
0039 
0040 
0041     @author  Pavel Binko
0042     @author  Pere Mato
0043     @date    19/10/1999, 30/11/2000
0044 */
0045 template <class TYPE>
0046 class ObjectVector : public ObjectContainerBase {
0047 
0048 public:
0049   typedef TYPE                                    contained_type;
0050   typedef typename std::vector<TYPE*>::value_type value_type;
0051 
0052   typedef typename std::vector<TYPE*>::reference       reference;
0053   typedef typename std::vector<TYPE*>::const_reference const_reference;
0054 
0055   typedef typename std::vector<TYPE*>::iterator       iterator;
0056   typedef typename std::vector<TYPE*>::const_iterator const_iterator;
0057 
0058   typedef typename std::vector<TYPE*>::reverse_iterator       reverse_iterator;
0059   typedef typename std::vector<TYPE*>::const_reverse_iterator const_reverse_iterator;
0060 #ifdef _WIN32
0061   typedef typename std::vector<TYPE*>::_Tptr  pointer;
0062   typedef typename std::vector<TYPE*>::_Ctptr const_pointer;
0063 #else
0064   typedef typename std::vector<TYPE*>::pointer       pointer;
0065   typedef typename std::vector<TYPE*>::const_pointer const_pointer;
0066 #endif
0067 
0068 public:
0069   /// Constructors
0070   ObjectVector()                                       = default;
0071   ObjectVector( const ObjectVector<TYPE>& )            = delete;
0072   ObjectVector& operator=( const ObjectVector<TYPE>& ) = delete;
0073   ObjectVector( ObjectVector&& rhs ) : ObjectContainerBase( std::move( rhs ) ), m_vector{ std::move( rhs.m_vector ) } {
0074     std::for_each( begin(), end(), [this]( TYPE* obj ) { obj->setParent( this ); } );
0075   }
0076 
0077   /// Destructor
0078   ~ObjectVector() override {
0079     for ( auto& i : m_vector ) {
0080       // Set the back pointer to 0 to avoid repetitional searching
0081       // for the object in the container, and deleting the object
0082       i->setParent( nullptr );
0083       delete i;
0084     }
0085   }
0086 
0087   /// Retrieve class ID
0088   const CLID& clID() const override { return ObjectVector<TYPE>::classID(); }
0089   /// Retrieve class ID
0090   static const CLID& classID() {
0091     static const CLID clid = TYPE::classID() + CLID_ObjectVector;
0092     return clid;
0093   }
0094 
0095   /// Return an iterator pointing to the beginning of the container
0096   typename ObjectVector<TYPE>::iterator begin() { return m_vector.begin(); }
0097 
0098   /// Return a const_iterator pointing to the beginning of the container
0099   typename ObjectVector<TYPE>::const_iterator begin() const { return m_vector.begin(); }
0100 
0101   /// Return an iterator pointing to the end of the container
0102   typename ObjectVector<TYPE>::iterator end() { return m_vector.end(); }
0103 
0104   /// Return a const_iterator pointing to the end of the container
0105   typename ObjectVector<TYPE>::const_iterator end() const { return m_vector.end(); }
0106 
0107   /// Return a reverse_iterator pointing to the beginning of the reversed container
0108   typename ObjectVector<TYPE>::reverse_iterator rbegin() { return m_vector.rbegin(); }
0109 
0110   /// Return a const_reverse_iterator pointing to the beginning
0111   ///   of the reversed container
0112   typename ObjectVector<TYPE>::const_reverse_iterator rbegin() const { return m_vector.rbegin(); }
0113 
0114   /// Return a reverse_iterator pointing to the end of the reversed container
0115   typename ObjectVector<TYPE>::reverse_iterator rend() { return m_vector.rend(); }
0116 
0117   /// Return a const_reverse_iterator pointing to the end of the reversed container
0118   typename ObjectVector<TYPE>::const_reverse_iterator rend() const { return m_vector.rend(); }
0119 
0120   /** Return the size of the container.
0121       Size means the number of objects stored in the container,
0122       independently on the amount of information stored in each object
0123   */
0124   typename ObjectVector<TYPE>::size_type size() const { return m_vector.size(); }
0125 
0126   /// The same as size(), return number of objects in the container
0127   typename ObjectVector<TYPE>::size_type numberOfObjects() const override { return m_vector.size(); }
0128 
0129   /// Return the largest possible size of the container
0130   typename ObjectVector<TYPE>::size_type max_size() const { return m_vector.max_size(); }
0131 
0132   /// Return number of elements for which memory has been allocated
0133   /// It is always greater than or equal to size()
0134   typename ObjectVector<TYPE>::size_type capacity() const { return m_vector.capacity(); }
0135 
0136   /** Reserve place for "value" objects in the container.
0137       If "value" is less than or equal to capacity(), this call has no effect,
0138       otherwise, it is a request for allocation of additional memory.
0139       If the request is successful, then capacity() is >= n,
0140       otherwise, capacity() is unchanged.
0141       In either case, size() is unchanged
0142   */
0143   void reserve( typename ObjectVector<TYPE>::size_type value ) { m_vector.reserve( value ); }
0144 
0145   /// Return true if the size of the container is 0
0146   bool empty() const { return m_vector.empty(); }
0147 
0148   /// Return reference to the first element
0149   typename ObjectVector<TYPE>::reference front() { return m_vector.front(); }
0150 
0151   /// Return const_reference to the first element
0152   typename ObjectVector<TYPE>::const_reference front() const { return m_vector.front(); }
0153 
0154   /// Return reference to the last element
0155   typename ObjectVector<TYPE>::reference back() { return m_vector.back(); }
0156 
0157   /// Return const_reference to the last element
0158   typename ObjectVector<TYPE>::const_reference back() const { return m_vector.back(); }
0159 
0160   /// push_back = append = insert a new element at the end of the container
0161   void push_back( typename ObjectVector<TYPE>::const_reference value ) {
0162     if ( value->parent() ) { const_cast<ObjectContainerBase*>( value->parent() )->remove( value ); }
0163     value->setParent( this );
0164     m_vector.push_back( value );
0165   }
0166 
0167   /// Add an object to the container
0168   long add( ContainedObject* pObject ) override {
0169     try {
0170       auto ptr = dynamic_cast<typename ObjectVector<TYPE>::value_type>( pObject );
0171       if ( ptr ) {
0172         push_back( ptr );
0173         return m_vector.size() - 1;
0174       }
0175     } catch ( ... ) {}
0176     return -1;
0177   }
0178 
0179   /// pop_back = remove the last element from the container
0180   /// The removed object will be deleted (see the method release)
0181   void pop_back() {
0182     auto position = m_vector.back();
0183     // Set the back pointer to 0 to avoid repetitional searching
0184     // for the object in the container, and deleting the object
0185     position->setParent( nullptr );
0186     delete position;
0187     // Removing from the container itself
0188     m_vector.pop_back();
0189   }
0190 
0191   /// Release object from the container (the poiter will be removed
0192   /// from the container, but the object itself will remain alive) (see the method pop_back)
0193   long remove( ContainedObject* value ) override {
0194     // Find the object of the value value
0195     auto i = std::find_if( begin(), end(), [&]( const ContainedObject* j ) { return j == value; } );
0196     if ( i == end() ) {
0197       // Object cannot be released from the conatiner,
0198       // as it is not contained in it
0199       return 0;
0200     }
0201     long idx = std::distance( begin(), i );
0202     // Set the back pointer to 0 to avoid repetitional searching
0203     // for the object in the container and deleting the object
0204     ( *i )->setParent( nullptr );
0205     erase( i );
0206     return idx;
0207   }
0208 
0209   /// Insert "value" before "position"
0210   typename ObjectVector<TYPE>::iterator insert( typename ObjectVector<TYPE>::iterator        position,
0211                                                 typename ObjectVector<TYPE>::const_reference value ) {
0212     value->setParent( this );
0213     return m_vector.insert( position, value );
0214   }
0215 
0216   /// Erase the object at "position" from the container. The removed object will be deleted.
0217   void erase( typename ObjectVector<TYPE>::iterator position ) {
0218     if ( ( *position )->parent() ) {
0219       // Set the back pointer to 0 to avoid repetitional searching
0220       // for the object in the container, and deleting the object
0221       ( *position )->setParent( nullptr );
0222       delete *position;
0223     }
0224     // Removing from the container itself
0225     m_vector.erase( position );
0226   }
0227 
0228   /// Erase the range [first, last) from the container. The removed object will be deleted
0229   void erase( typename ObjectVector<TYPE>::iterator first, typename ObjectVector<TYPE>::iterator last ) {
0230     for ( auto i = first; i != last; i++ ) {
0231       // Set the back pointer to 0 to avoid repetitional searching
0232       // for the object in the container, and deleting the object
0233       ( *i )->setParent( nullptr );
0234       delete *i;
0235     }
0236     // Removing from the container itself
0237     m_vector.erase( first, last );
0238   }
0239 
0240   /// Clear the entire content of the container and delete all contained objects
0241   void clear() { erase( begin(), end() ); }
0242 
0243   /// Return the reference to the n'th object in the container
0244   typename ObjectVector<TYPE>::reference operator[]( typename ObjectVector<TYPE>::size_type n ) { return m_vector[n]; }
0245 
0246   /// Return the const_reference to the n'th object in the container
0247   typename ObjectVector<TYPE>::const_reference operator[]( typename ObjectVector<TYPE>::size_type n ) const {
0248     return m_vector[n];
0249   }
0250 
0251   /// Return distance of a given object from the beginning of its container
0252   /// It correcponds to the "index" ( from 0 to size()-1 )
0253   /// If "obj" not fount, return -1
0254   long index( const ContainedObject* obj ) const override {
0255     auto i = std::find_if( begin(), end(), [&]( const ContainedObject* o ) { return o == obj; } );
0256     return i != end() ? std::distance( begin(), i ) : -1;
0257   }
0258 
0259   /// Return const pointer to an object of a given distance (index)
0260   ContainedObject const* containedObject( long dist ) const override { return m_vector[dist]; }
0261   ContainedObject*       containedObject( long dist ) override { return m_vector[dist]; }
0262 
0263   /// Fill the output stream (ASCII)
0264   std::ostream& fillStream( std::ostream& s ) const override {
0265     s << "class ObjectVector :    size = " << std::setw( 12 ) << size() << "\n";
0266     // Output the base class
0267     // ObjectContainerBase::fillStream(s);
0268     if ( !empty() ) {
0269       s << "\nContents of the STL vector :";
0270       long count = 0;
0271       for ( const auto& i : m_vector ) { s << "\nIndex " << std::setw( 12 ) << count++ << " of object of type " << *i; }
0272     }
0273     return s;
0274   }
0275 
0276 private:
0277   /// The STL vector itself
0278   std::vector<TYPE*> m_vector;
0279 };
0280 
0281 #endif // GAUDIKERNEL_OBJECTVECTOR_H