00001
00002
00003
00004
00005 #ifndef GAUDIKERNEL_VECTORMAP_H
00006 #define GAUDIKERNEL_VECTORMAP_H 1
00007
00008
00009
00010
00011
00012 #include <utility>
00013 #include <functional>
00014 #include <vector>
00015 #include <algorithm>
00016 #include <ostream>
00017
00018
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
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
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
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
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
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
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
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() ; }
00734
00735
00736
00737
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
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& ) { 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
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 ;
00855
00856 };
00857
00858 }
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 }
00878
00879
00880
00881
00882
00883 #endif // GAUDIKERNEL_MAPS_H
00884