Gaudi Framework, version v21r11

Home   Generated: 30 Sep 2010

VectorMap.h

Go to the documentation of this file.
00001 // $Id: VectorMap.h,v 1.11 2007/05/24 14:39:11 hmd Exp $
00002 // ============================================================================
00003 // CVS tag $Name:  $, version $Revision: 1.11 $
00004 // ============================================================================
00005 #ifndef GAUDIKERNEL_VECTORMAP_H
00006 #define GAUDIKERNEL_VECTORMAP_H 1
00007 // ============================================================================
00008 // Include files
00009 // ============================================================================
00010 // STD & STL
00011 // ============================================================================
00012 #include <utility>
00013 #include <functional>
00014 #include <vector>
00015 #include <algorithm>
00016 #include <ostream>
00017 // ============================================================================
00018 // GaudiKernel
00019 // ============================================================================
00020 #include "GaudiKernel/MapBase.h"
00021 // ============================================================================
00022 namespace GaudiUtils
00023 {
00024   // ==========================================================================
00099   template
00100   <
00101     class KEY                                                 ,
00102     class VALUE                                               ,
00103     class KEYCOMPARE=std::less<const KEY>                     ,
00104     class ALLOCATOR=std::allocator<std::pair<KEY,VALUE> >
00105     >
00106   class VectorMap : public Gaudi::Utils::MapBase
00107   {
00108   public:
00109     // ========================================================================
00111     typedef KEY                                    key_type         ;
00113     typedef VALUE                                  mapped_type      ;
00115     typedef KEYCOMPARE                             key_compare      ;
00117     typedef std::pair<key_type,mapped_type>        value_type       ;
00118     // ========================================================================
00119   public:
00120     // ========================================================================
00122     typedef ALLOCATOR                              allocator_type   ;
00124     typedef typename ALLOCATOR::const_reference    reference        ;
00126     typedef typename ALLOCATOR::const_reference    const_reference  ;
00128     typedef typename ALLOCATOR::size_type          size_type        ;
00130     typedef typename ALLOCATOR::difference_type    difference_type  ;
00131     // ========================================================================
00132   public:
00133     // ========================================================================
00135     typedef std::vector<value_type,allocator_type> _vector          ;
00136     // ========================================================================
00137   protected:
00138     // ========================================================================
00140     typedef typename _vector::iterator             _iterator        ;
00141     // ========================================================================
00142   public:
00143     // ========================================================================
00145     typedef typename _vector::const_iterator       iterator         ;
00147     typedef typename _vector::const_iterator       const_iterator   ;
00149     typedef std::reverse_iterator<iterator>        reverse_iterator ;
00151     typedef std::reverse_iterator<const_iterator>  const_reverse_iterator ;
00153     typedef std::pair<iterator,iterator>           iterators        ;
00155     typedef std::pair<iterator,bool>               result_type      ;
00156     // ========================================================================
00157   public:
00158     // ========================================================================
00163     struct _compare_type : public key_compare
00164     {
00165     public:
00166       // ======================================================================
00168       _compare_type ( const key_compare& cmp ) : key_compare ( cmp ) {} ;
00170       _compare_type ()                         : key_compare (     ) {} ;
00172       bool operator () ( const key_type&  k1 , const key_type&   k2 ) const
00173       { return this->key_compare::operator() ( k1 , k2 ) ; }
00175       bool operator() ( const value_type& v1 , const value_type& v2 ) const
00176       { return operator() ( v1.first, v2.first ); }
00178       bool operator() ( const key_type&   k  , const value_type& v  ) const
00179       { return operator() ( k , v.first ) ; }
00181       bool operator() ( const value_type& v  , const key_type  & k  ) const
00182       { return operator() ( v.first , k ) ; }
00183       // ======================================================================
00184     };
00185     // ========================================================================
00187     typedef _compare_type                            compare_type   ;
00188     // ========================================================================
00189   public:
00190     // ========================================================================
00191     // sequential access  (only const-versions!)
00192     // ========================================================================
00194     iterator         begin  () const { return m_vct . begin  () ; }
00196     iterator         end    () const { return m_vct . end    () ; }
00198     reverse_iterator rbegin () const { return m_vct . rbegin () ; }
00200     reverse_iterator rend   () const { return m_vct . rend   () ; }
00201     // ========================================================================
00202     // list operations : erase & insert
00203     // ========================================================================
00207     void erase  ( iterator pos ) { m_vct.erase ( iter ( pos ) ) ; }
00208     // ========================================================================
00225     size_type erase  ( const key_type&    key    )
00226     {
00227       iterator pos = find ( key ) ;
00228       if ( end() == pos ) { return 0 ; }
00229       erase ( pos ) ;
00230       return 1 ;
00231     }
00232     // ========================================================================
00238     size_type erase  ( iterator           first   ,
00239                        iterator           last    )
00240     {
00241       m_vct.erase ( iter ( first ) , iter ( last )  ) ;
00242       return last - first ;
00243     }
00244     // ========================================================================
00265     template <class TYPE>
00266     size_type erase  ( TYPE first , TYPE last )
00267     {
00268       size_type res = 0 ;
00269       for ( ; first != last ; ++first ) { res += erase ( *first ) ; }
00270       return res ;
00271     }
00272     // ========================================================================
00314     result_type insert
00315     ( const key_type&    key    ,
00316       const mapped_type& mapped  )
00317     { return insert ( value_type ( key , mapped ) ) ; }
00318     // ========================================================================
00359     result_type insert
00360     ( const value_type&  value  )
00361     {
00362       bool found = true ;
00363       _iterator result = lower_bound ( value.first ) ;
00364       if ( end() == result || compare( value.first , result -> first ) )
00365       { result = m_vct.insert ( result , value ) ; found = false ; }
00366       return result_type ( iter ( result ) , !found ) ;
00367     }
00368     // ========================================================================
00377     result_type insert
00378     ( iterator           pos    ,
00379       const value_type&  value  )
00380     {
00381       if ( pos != end() && compare ( *pos , value ) &&
00382            ( pos == end() - 1 ||
00383               ( !compare ( value , *( pos + 1 ) )
00384                 && compare ( *( pos + 1 ) , value ) ) ) )
00385       { return result_type( m_vct.insert ( iter ( pos ) , value ) , true ) ; }
00386       return insert ( value ) ;
00387     }
00388     // ========================================================================
00398     result_type insert
00399     ( iterator           pos    ,
00400       const key_type&    key    ,
00401       const mapped_type& mapped )
00402     { return insert ( pos , value_type ( key , mapped ) ) ; }
00403     // ========================================================================
00409     template <class PAIRS>
00410     void insert
00411     ( PAIRS first ,
00412       PAIRS last  )
00413     { for ( ; first != last ; ++first ) { insert ( *first ) ; } }
00414     // ========================================================================
00422     template <class KEYS, class VALUES> void insert
00423     ( KEYS   kf ,
00424       KEYS   kl ,
00425       VALUES vf )
00426     { for ( ; kf != kl ; ++kf, ++vf ) { insert ( *kf , *vf ) ; } }
00427     // ========================================================================
00428     // map operations: lookup, count, ...
00429     // ========================================================================
00453     iterator find ( const key_type& key ) const
00454     {
00455       iterator res = lower_bound ( key ) ;
00456       if ( end() != res && compare ( key , res->first ) )
00457       { res = end(); }
00458       return res ;
00459     }
00460     // ========================================================================
00476     size_type count ( const key_type& key ) const
00477     { return end() == find ( key ) ? 0 : 1 ; }
00478     // ========================================================================
00479     iterator  lower_bound ( const key_type& key ) const
00480     { return std::lower_bound ( begin () , end () , key , compare () ) ; }
00481     iterator  upper_bound ( const key_type& key ) const
00482     { return std::upper_bound ( begin () , end () , key , compare () ) ; }
00483     iterators equal_range ( const key_type& key ) const
00484     { return std::equal_range ( begin () , end () , key , compare () ) ; }
00485     // ========================================================================
00486     // general container operations :
00487     // ========================================================================
00489     bool      empty    () const { return m_vct . empty    () ; }
00491     size_type size     () const { return m_vct . size     () ; }
00493     size_type max_size () const { return m_vct . max_size () ; }
00495     void clear    ()                { m_vct.clear   ()       ; }
00497     void reserve  ( size_type num ) { m_vct.reserve ( num )  ; }
00498     // ========================================================================
00500     void swap     ( VectorMap& other )
00501     {
00502       std::swap ( m_vct , other.m_vct ) ;
00503     }
00504     // ========================================================================
00505     // The basic comparison operators for container
00506     // ========================================================================
00508     bool operator== ( const VectorMap& other ) const
00509     { return m_vct == other.m_vct ; }
00511     bool operator<  ( const VectorMap& other ) const
00512     { return m_vct <  other.m_vct ; }
00513     // ========================================================================
00514     // The derived comparison operators for container
00515     // ========================================================================
00516     friend bool operator>  ( const VectorMap& left  ,
00517                              const VectorMap& right )
00518     { return    right < left     ; }
00519     friend bool operator!= ( const VectorMap& left  ,
00520                              const VectorMap& right )
00521     { return !( left == right  ) ; }
00522     friend bool operator>= ( const VectorMap& left  ,
00523                              const VectorMap& right )
00524     { return !( left  <  right ) ; }
00525     friend bool operator<= ( const VectorMap& left  ,
00526                              const VectorMap& right )
00527     { return !( right <  left  ) ; }
00528     // ========================================================================    
00558     bool update
00559     ( const key_type&    key    ,
00560       const mapped_type& mapped )
00561     {
00562       _iterator result = lower_bound ( key ) ;
00563       if ( end() == result || compare ( key , result -> first ) )
00564       { 
00565         result = m_vct.insert ( result , value_type(key,mapped) ) ; 
00566         return false ;
00567       }
00568       else { result->second = mapped ; }
00569       //
00570       return true ;
00571     }
00572     // ========================================================================
00601     bool update ( const value_type& val )
00602     { return update ( val.first , val.second ) ; }
00603     // ========================================================================
00635     const mapped_type& operator() ( const key_type& key ) const
00636     {
00637       static const mapped_type s_default = mapped_type() ;
00638       iterator res = find ( key ) ;
00639       if ( end() == res ) { return s_default ; }
00640       return res->second ;
00641     }
00642     // ========================================================================
00673     const mapped_type& operator[] ( const key_type& key ) const
00674     { return (*this)( key ) ; }
00675     // ========================================================================
00693     const mapped_type& at ( const key_type& key ) const
00694     {
00695       iterator res = find ( key ) ;
00696       if ( end() == res ) { this->throw_out_of_range_exception () ; }
00697       return res->second ;
00698     }
00699     // ========================================================================
00700   public:
00701     // ========================================================================
00702     // Constructors, destructors, etc.
00703     // ========================================================================
00708     VectorMap ( const allocator_type& alloc = allocator_type () )
00709       : m_vct ( alloc )
00710     {}
00711     // ========================================================================
00715     VectorMap ( const VectorMap& right )
00716       : Gaudi::Utils::MapBase(right), m_vct ( right.m_vct )
00717     {}
00718     // ========================================================================
00725     template <class INPUT>
00726     VectorMap ( INPUT first ,
00727                 INPUT last  ,
00728                 const allocator_type& alloc = allocator_type () )
00729       : m_vct ( first , last , alloc )
00730     { std::sort ( m_vct.begin(), m_vct.end(), compare() ) ; }
00731     // ========================================================================
00733     ~VectorMap() { clear() ; }                     // destructor (non-virtual!)
00734     // ========================================================================
00735     /* assignement operator
00736      * @param rigth object to be assigned
00737      * @return self
00738      */
00739     VectorMap& operator= ( const VectorMap& right )
00740     {
00741       if ( &right == this ) { return *this ; }
00742       m_vct = right.m_vct ;
00743       return *this ;
00744     }
00745     // ========================================================================
00746   public:
00747     // ========================================================================
00748     // The specific public accessors
00749     // ========================================================================
00751     const compare_type& compare     () const
00752     {
00753       static const  compare_type s_cmp = compare_type() ;
00754       return s_cmp ;
00755     }
00757     const key_compare&  compare_key () const { return compare()  ; }
00759     friend std::ostream& operator<<
00760       ( std::ostream& str , const VectorMap& /* obj */) { return str ; }
00761     // ========================================================================
00762   public:
00763     // ========================================================================
00765     inline VectorMap& merge ( const VectorMap& right ) 
00766     {
00767       for ( const_iterator it = right.begin() ; right.end() != it ; ++it ) 
00768       { update ( it->first , it->second ) ; }
00769       //
00770       return *this ;
00771     }
00773     template <class K1,class K2, class K3,class K4>
00774     inline VectorMap& merge ( const VectorMap<K1,K2,K3,K4>& right ) 
00775     {
00776       for ( typename VectorMap<K1,K2,K3,K4>::const_iterator it = 
00777               right.begin() ; right.end() != it ; ++it ) 
00778       { update ( it->first , it->second ) ; }
00779       //
00780       return *this ;
00781     }
00782     // ========================================================================
00783   public:
00784     // ========================================================================
00790     const key_type&    key_at   ( const size_t index ) const 
00791     {
00792       if ( index  >= size() ) 
00793       { this->throw_out_of_range_exception () ; }
00794       const_iterator it = this->begin() ;
00795       std::advance ( it , index ) ;
00796       return it -> first ;
00797     }
00803     const mapped_type& value_at ( const size_t index ) const 
00804     {
00805       if ( index  >= size() ) 
00806       { this->throw_out_of_range_exception () ; }
00807       const_iterator it = this->begin() ;
00808       std::advance ( it , index ) ;
00809       return it -> second ;
00810     }
00811     // ========================================================================
00812   protected:
00813     // ========================================================================
00814     // Pure technical helper functions
00815     // ========================================================================
00821     template <class TYPE1, class TYPE2>
00822     bool  compare ( const TYPE1& obj1 ,
00823                     const TYPE2& obj2 ) const
00824     {
00825       return compare() ( obj1 , obj2 )  ;
00826     }
00827     // ========================================================================
00829     _iterator lower_bound ( const key_type& key )
00830     {
00831       return std::lower_bound
00832       ( m_vct.begin() , m_vct.end() , key , compare() ) ;
00833     } 
00834     // ========================================================================
00836     _iterator iter (  iterator p )
00837     {
00838       _iterator result = m_vct.begin() ;
00839       std::advance ( result , std::distance ( begin() , p ) ) ;
00840       return result ;
00841     }
00842     // ========================================================================
00844     iterator  iter ( _iterator p )
00845     {
00846       iterator result ( begin() ) ;
00847       std::advance ( result , std::distance (  m_vct.begin() , p ) ) ;
00848       return result ;
00849     }
00850     // ========================================================================
00851   private:
00852     // ========================================================================
00854     _vector      m_vct ; // the underlying sorted vector of (key,mapped) pairs
00855     // ========================================================================
00856   };
00857   // ==========================================================================
00858 } //                                               end of namespace GaudiUtils 
00859 // ============================================================================
00860 namespace std
00861 {
00862   // ==========================================================================
00867   template
00868   < class KEY        ,
00869     class VALUE      ,
00870     class KEYCOMPARE ,
00871     class ALLOCATOR  >
00872   inline void swap
00873   ( GaudiUtils::VectorMap<KEY,VALUE,KEYCOMPARE,ALLOCATOR>& left  ,
00874     GaudiUtils::VectorMap<KEY,VALUE,KEYCOMPARE,ALLOCATOR>& right )
00875   { left.swap( right ) ; }
00876  // ===========================================================================
00877 } //                                                       end of namespace std 
00878 // ============================================================================
00879 
00880 // ============================================================================
00881 // The END
00882 // ============================================================================
00883 #endif // GAUDIKERNEL_MAPS_H
00884 // ============================================================================

Generated at Thu Sep 30 09:57:33 2010 for Gaudi Framework, version v21r11 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004