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 namespace GaudiUtils
00020 {
00021
00023 void _throw_out_of_range_exception_() ;
00024
00048 template
00049 <
00050 class KEY ,
00051 class VALUE ,
00052 class KEYCOMPARE=std::less<const KEY> ,
00053 class ALLOCATOR=std::allocator<std::pair<KEY,VALUE> >
00054 >
00055 class VectorMap
00056 {
00057 public:
00059 typedef KEY key_type ;
00061 typedef VALUE mapped_type ;
00063 typedef KEYCOMPARE key_compare ;
00065 typedef std::pair<key_type,mapped_type> value_type ;
00066 public:
00068 typedef ALLOCATOR allocator_type ;
00070 typedef typename ALLOCATOR::const_reference reference ;
00072 typedef typename ALLOCATOR::const_reference const_reference ;
00074 typedef typename ALLOCATOR::size_type size_type ;
00076 typedef typename ALLOCATOR::difference_type difference_type ;
00077 public:
00079 typedef std::vector<value_type,allocator_type> _vector ;
00080 protected:
00082 typedef typename _vector::iterator _iterator ;
00083 public:
00085 typedef typename _vector::const_iterator iterator ;
00087 typedef typename _vector::const_iterator const_iterator ;
00089 typedef std::reverse_iterator<iterator> reverse_iterator ;
00091 typedef std::reverse_iterator<const_iterator> const_reverse_iterator ;
00093 typedef std::pair<iterator,iterator> iterators ;
00095 typedef std::pair<iterator,bool> result_type ;
00096 public:
00101 struct _compare_type : public key_compare
00102 {
00103 public:
00105 _compare_type ( const key_compare& cmp ) : key_compare ( cmp ) {} ;
00107 _compare_type () : key_compare ( ) {} ;
00109 bool operator () ( const key_type& k1 , const key_type& k2 ) const
00110 { return this->key_compare::operator() ( k1 , k2 ) ; }
00112 bool operator() ( const value_type& v1 , const value_type& v2 ) const
00113 { return operator() ( v1.first, v2.first ); }
00115 bool operator() ( const key_type& k , const value_type& v ) const
00116 { return operator() ( k , v.first ) ; }
00118 bool operator() ( const value_type& v , const key_type & k ) const
00119 { return operator() ( v.first , k ) ; }
00120 };
00122 typedef _compare_type compare_type ;
00123 public:
00124
00125
00126
00127
00128
00130 iterator begin () const { return m_vct . begin () ; }
00132 iterator end () const { return m_vct . end () ; }
00134 reverse_iterator rbegin () const { return m_vct . rbegin () ; }
00136 reverse_iterator rend () const { return m_vct . rend () ; }
00137
00138
00139
00140
00141
00145 void erase ( iterator pos ) { m_vct.erase ( iter ( pos ) ) ; }
00146
00163 size_type erase ( const key_type& key )
00164 {
00165 iterator pos = find ( key ) ;
00166 if ( end() == pos ) { return 0 ; }
00167 erase ( pos ) ;
00168 return 1 ;
00169 } ;
00170
00176 size_type erase ( iterator first ,
00177 iterator last )
00178 {
00179 m_vct.erase ( iter ( first ) , iter ( last ) ) ;
00180 return last - first ;
00181 }
00182
00203 template <class TYPE>
00204 size_type erase ( TYPE first , TYPE last )
00205 {
00206 size_type res = 0 ;
00207 for ( ; first != last ; ++first ) { res += erase ( *first ) ; }
00208 return res ;
00209 }
00210
00252 result_type insert
00253 ( const key_type& key ,
00254 const mapped_type& mapped )
00255 { return insert ( value_type ( key , mapped ) ) ; }
00256
00297 result_type insert
00298 ( const value_type& value )
00299 {
00300 bool found = true ;
00301 _iterator result = lower_bound ( value.first ) ;
00302 if ( end() == result || compare( value.first , result -> first ) )
00303 { result = m_vct.insert ( result , value ) ; found = false ; }
00304 return result_type ( iter ( result ) , !found ) ;
00305 }
00306
00315 result_type insert
00316 ( iterator pos ,
00317 const value_type& value )
00318 {
00319 if ( pos != end() && compare ( *pos , value ) &&
00320 ( pos == end() - 1 ||
00321 ( !compare ( value , *( pos + 1 ) )
00322 && compare ( *( pos + 1 ) , value ) ) ) )
00323 { return result_type( m_vct.insert ( iter ( pos ) , value ) , true ) ; }
00324 return insert ( value ) ;
00325 }
00326
00336 result_type insert
00337 ( iterator pos ,
00338 const key_type& key ,
00339 const mapped_type& mapped )
00340 { return insert ( pos , value_type ( key , mapped ) ) ; }
00341
00347 template <class PAIRS>
00348 void insert
00349 ( PAIRS first ,
00350 PAIRS last )
00351 { for ( ; first != last ; ++first ) { insert ( *first ) ; } }
00359 template <class KEYS, class VALUES> void insert
00360 ( KEYS kf ,
00361 KEYS kl ,
00362 VALUES vf )
00363 { for ( ; kf != kl ; ++kf, ++vf ) { insert ( *kf , *vf ) ; } }
00364
00365
00366
00367
00368
00392 iterator find ( const key_type& key ) const
00393 {
00394 iterator res = lower_bound ( key ) ;
00395 if ( end() != res && compare ( key , res->first ) )
00396 { res = end(); }
00397 return res ;
00398 }
00399
00415 size_type count ( const key_type& key ) const
00416 { return end() == find ( key ) ? 0 : 1 ; }
00417
00418 iterator lower_bound ( const key_type& key ) const
00419 { return std::lower_bound ( begin () , end () , key , compare () ) ; }
00420 iterator upper_bound ( const key_type& key ) const
00421 { return std::upper_bound ( begin () , end () , key , compare () ) ; }
00422 iterators equal_range ( const key_type& key ) const
00423 { return std::equal_range ( begin () , end () , key , compare () ) ; }
00424
00425
00426
00427
00428
00430 bool empty () const { return m_vct . empty () ; }
00432 size_type size () const { return m_vct . size () ; }
00434 size_type max_size () const { return m_vct . max_size () ; }
00435
00437 void clear () { m_vct.clear () ; }
00439 void reserve ( size_type num ) { m_vct.reserve ( num ) ; }
00440
00442 void swap ( VectorMap& other )
00443 {
00444 std::swap ( m_vct , other.m_vct ) ;
00445 }
00446
00447
00448
00449
00450
00452 bool operator== ( const VectorMap& other ) const
00453 { return m_vct == other.m_vct ; }
00454
00456 bool operator< ( const VectorMap& other ) const
00457 { return m_vct < other.m_vct ; }
00458
00459
00460
00461
00462
00463 friend bool operator> ( const VectorMap& left ,
00464 const VectorMap& right )
00465 { return right < left ; }
00466
00467 friend bool operator!= ( const VectorMap& left ,
00468 const VectorMap& right )
00469 { return !( left == right ) ; }
00470
00471 friend bool operator>= ( const VectorMap& left ,
00472 const VectorMap& right )
00473 { return !( left < right ) ; }
00474
00475 friend bool operator<= ( const VectorMap& left ,
00476 const VectorMap& right )
00477 { return !( right < left ) ; }
00478
00479
00509 iterator update
00510 ( const key_type& key ,
00511 const mapped_type& mapped )
00512 {
00513 _iterator result = lower_bound ( key ) ;
00514 if ( end() == result || compare ( key , result -> first ) )
00515 { result = m_vct.insert ( result , value_type(key,mapped) ) ; }
00516 else
00517 { result->second = mapped ; }
00518 return iter ( result ) ;
00519 }
00520
00549 iterator update ( const value_type& val )
00550 { return update ( val.first , val.second ) ; }
00551
00583 const mapped_type& operator() ( const key_type& key ) const
00584 {
00585 static const mapped_type s_default = mapped_type() ;
00586 iterator res = find ( key ) ;
00587 if ( end() == res ) { return s_default ; }
00588 return res->second ;
00589 }
00620 const mapped_type& operator[] ( const key_type& key ) const
00621 { return (*this)( key ) ; }
00622
00640 const mapped_type& at ( const key_type& key ) const
00641 {
00642 iterator res = find ( key ) ;
00643 if ( end() == res )
00644 { GaudiUtils::_throw_out_of_range_exception_() ; }
00645 return res->second ;
00646 }
00647
00648 public:
00649
00650
00651
00652
00653
00658 VectorMap ( const allocator_type& alloc = allocator_type () )
00659 : m_vct ( alloc )
00660 {}
00661
00665 VectorMap ( const VectorMap& right )
00666 : m_vct ( right.m_vct )
00667 {}
00668
00675 template <class INPUT>
00676 VectorMap ( INPUT first ,
00677 INPUT last ,
00678 const allocator_type& alloc = allocator_type () )
00679 : m_vct ( first , last , alloc )
00680 { std::sort ( m_vct.begin(), m_vct.end(), compare() ) ; }
00681
00683 ~VectorMap() { clear() ; }
00684
00685
00686
00687
00688
00689 VectorMap& operator= ( const VectorMap& right )
00690 {
00691 if ( &right == this ) { return *this ; }
00692 m_vct = right.m_vct ;
00693 return *this ;
00694 }
00695
00696 public:
00697
00698
00699
00700
00701
00703 const compare_type& compare () const
00704 {
00705 static const compare_type s_cmp = compare_type() ;
00706 return s_cmp ;
00707 }
00709 const key_compare& compare_key () const { return compare() ; }
00710
00712 friend std::ostream& operator<<
00713 ( std::ostream& str , const VectorMap& ) { return str ; }
00714
00715 protected:
00716
00717
00718
00719
00720
00726 template <class TYPE1, class TYPE2>
00727 bool compare ( const TYPE1& obj1 ,
00728 const TYPE2& obj2 ) const
00729 {
00730 return compare() ( obj1 , obj2 ) ;
00731 }
00732
00734 _iterator lower_bound ( const key_type& key )
00735 {
00736 return std::lower_bound
00737 ( m_vct.begin() , m_vct.end() , key , compare() ) ;
00738 } ;
00740 _iterator iter ( iterator p )
00741 {
00742 _iterator result = m_vct.begin() ;
00743 std::advance ( result , std::distance ( begin() , p ) ) ;
00744 return result ;
00745 };
00747 iterator iter ( _iterator p )
00748 {
00749 iterator result ( begin() ) ;
00750 std::advance ( result , std::distance ( m_vct.begin() , p ) ) ;
00751 return result ;
00752 }
00753
00754 private:
00755
00756 _vector m_vct ;
00757 };
00758 }
00759
00760 namespace std
00761 {
00766 template
00767 < class KEY ,
00768 class VALUE ,
00769 class KEYCOMPARE ,
00770 class ALLOCATOR >
00771 inline void swap
00772 ( GaudiUtils::VectorMap<KEY,VALUE,KEYCOMPARE,ALLOCATOR>& left ,
00773 GaudiUtils::VectorMap<KEY,VALUE,KEYCOMPARE,ALLOCATOR>& right )
00774 { left.swap( right ) ; }
00775 }
00776
00777
00778
00779
00780 #endif // GAUDIKERNEL_MAPS_H
00781