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
00023 #include "GaudiKernel/StatusCode.h"
00024 #include "GaudiKernel/StringKey.h"
00025
00026 namespace GaudiUtils
00027 {
00028
00103 template
00104 <
00105 class KEY ,
00106 class VALUE ,
00107 class KEYCOMPARE=std::less<const KEY> ,
00108 class ALLOCATOR=std::allocator<std::pair<KEY,VALUE> >
00109 >
00110 class VectorMap : public Gaudi::Utils::MapBase
00111 {
00112 public:
00113
00115 typedef KEY key_type ;
00117 typedef VALUE mapped_type ;
00119 typedef KEYCOMPARE key_compare ;
00121 typedef std::pair<key_type,mapped_type> value_type ;
00122
00123 public:
00124
00126 typedef ALLOCATOR allocator_type ;
00128 typedef typename ALLOCATOR::const_reference reference ;
00130 typedef typename ALLOCATOR::const_reference const_reference ;
00132 typedef typename ALLOCATOR::size_type size_type ;
00134 typedef typename ALLOCATOR::difference_type difference_type ;
00135
00136 public:
00137
00139 typedef std::vector<value_type,allocator_type> _vector ;
00140
00141 protected:
00142
00144 typedef typename _vector::iterator _iterator ;
00145
00146 public:
00147
00149 typedef typename _vector::const_iterator iterator ;
00151 typedef typename _vector::const_iterator const_iterator ;
00153 typedef std::reverse_iterator<iterator> reverse_iterator ;
00155 typedef std::reverse_iterator<const_iterator> const_reverse_iterator ;
00157 typedef std::pair<iterator,iterator> iterators ;
00159 typedef std::pair<iterator,bool> result_type ;
00160
00161 public:
00162
00167 struct _compare_type : public key_compare
00168 {
00169 public:
00170
00172 _compare_type ( const key_compare& cmp ) : key_compare ( cmp ) {}
00174 _compare_type () : key_compare ( ) {}
00176 bool operator () ( const key_type& k1 , const key_type& k2 ) const
00177 { return this->key_compare::operator() ( k1 , k2 ) ; }
00179 bool operator() ( const value_type& v1 , const value_type& v2 ) const
00180 { return operator() ( v1.first, v2.first ); }
00182 bool operator() ( const key_type& k , const value_type& v ) const
00183 { return operator() ( k , v.first ) ; }
00185 bool operator() ( const value_type& v , const key_type & k ) const
00186 { return operator() ( v.first , k ) ; }
00187
00188 };
00189
00191 typedef _compare_type compare_type ;
00192
00193 public:
00194
00195
00196
00198 iterator begin () const { return m_vct . begin () ; }
00200 iterator end () const { return m_vct . end () ; }
00202 reverse_iterator rbegin () const { return m_vct . rbegin () ; }
00204 reverse_iterator rend () const { return m_vct . rend () ; }
00205
00206
00207
00211 void erase ( iterator pos ) { m_vct.erase ( iter ( pos ) ) ; }
00212
00229 size_type erase ( const key_type& key )
00230 {
00231 iterator pos = find ( key ) ;
00232 if ( end() == pos ) { return 0 ; }
00233 erase ( pos ) ;
00234 return 1 ;
00235 }
00236
00242 size_type erase ( iterator first ,
00243 iterator last )
00244 {
00245 m_vct.erase ( iter ( first ) , iter ( last ) ) ;
00246 return last - first ;
00247 }
00248
00269 template <class TYPE>
00270 size_type erase ( TYPE first , TYPE last )
00271 {
00272 size_type res = 0 ;
00273 for ( ; first != last ; ++first ) { res += erase ( *first ) ; }
00274 return res ;
00275 }
00276
00318 result_type insert
00319 ( const key_type& key ,
00320 const mapped_type& mapped )
00321 { return insert ( value_type ( key , mapped ) ) ; }
00322
00363 result_type insert
00364 ( const value_type& value )
00365 {
00366 bool found = true ;
00367 _iterator result = lower_bound ( value.first ) ;
00368 if ( end() == result || compare( value.first , result -> first ) )
00369 { result = m_vct.insert ( result , value ) ; found = false ; }
00370 return result_type ( iter ( result ) , !found ) ;
00371 }
00372
00381 result_type insert
00382 ( iterator pos ,
00383 const value_type& value )
00384 {
00385 if ( pos != end() && compare ( *pos , value ) &&
00386 ( pos == end() - 1 ||
00387 ( !compare ( value , *( pos + 1 ) )
00388 && compare ( *( pos + 1 ) , value ) ) ) )
00389 { return result_type( m_vct.insert ( iter ( pos ) , value ) , true ) ; }
00390 return insert ( value ) ;
00391 }
00392
00402 result_type insert
00403 ( iterator pos ,
00404 const key_type& key ,
00405 const mapped_type& mapped )
00406 { return insert ( pos , value_type ( key , mapped ) ) ; }
00407
00413 template <class PAIRS>
00414 void insert
00415 ( PAIRS first ,
00416 PAIRS last )
00417 { for ( ; first != last ; ++first ) { insert ( *first ) ; } }
00418
00426 template <class KEYS, class VALUES> void insert
00427 ( KEYS kf ,
00428 KEYS kl ,
00429 VALUES vf )
00430 { for ( ; kf != kl ; ++kf, ++vf ) { insert ( *kf , *vf ) ; } }
00431
00432
00433
00457 iterator find ( const key_type& key ) const
00458 {
00459 iterator res = lower_bound ( key ) ;
00460 if ( end() != res && compare ( key , res->first ) )
00461 { res = end(); }
00462 return res ;
00463 }
00464
00480 size_type count ( const key_type& key ) const
00481 { return end() == find ( key ) ? 0 : 1 ; }
00482
00483 iterator lower_bound ( const key_type& key ) const
00484 { return std::lower_bound ( begin () , end () , key , compare () ) ; }
00485 iterator upper_bound ( const key_type& key ) const
00486 { return std::upper_bound ( begin () , end () , key , compare () ) ; }
00487 iterators equal_range ( const key_type& key ) const
00488 { return std::equal_range ( begin () , end () , key , compare () ) ; }
00489
00490
00491
00493 bool empty () const { return m_vct . empty () ; }
00495 size_type size () const { return m_vct . size () ; }
00497 size_type max_size () const { return m_vct . max_size () ; }
00499 void clear () { m_vct.clear () ; }
00501 void reserve ( size_type num ) { m_vct.reserve ( num ) ; }
00502
00504 void swap ( VectorMap& other )
00505 {
00506 std::swap ( m_vct , other.m_vct ) ;
00507 }
00508
00509
00510
00512 bool operator== ( const VectorMap& other ) const
00513 { return m_vct == other.m_vct ; }
00515 bool operator< ( const VectorMap& other ) const
00516 { return m_vct < other.m_vct ; }
00517
00518
00519
00520 friend bool operator> ( const VectorMap& left ,
00521 const VectorMap& right )
00522 { return right < left ; }
00523 friend bool operator!= ( const VectorMap& left ,
00524 const VectorMap& right )
00525 { return !( left == right ) ; }
00526 friend bool operator>= ( const VectorMap& left ,
00527 const VectorMap& right )
00528 { return !( left < right ) ; }
00529 friend bool operator<= ( const VectorMap& left ,
00530 const VectorMap& right )
00531 { return !( right < left ) ; }
00532
00562 bool update
00563 ( const key_type& key ,
00564 const mapped_type& mapped )
00565 {
00566 _iterator result = lower_bound ( key ) ;
00567 if ( end() == result || compare ( key , result -> first ) )
00568 {
00569 result = m_vct.insert ( result , value_type(key,mapped) ) ;
00570 return false ;
00571 }
00572 else { result->second = mapped ; }
00573
00574 return true ;
00575 }
00576
00605 bool update ( const value_type& val )
00606 { return update ( val.first , val.second ) ; }
00607
00639 const mapped_type& operator() ( const key_type& key ) const
00640 {
00641 static const mapped_type s_default = mapped_type() ;
00642 iterator res = find ( key ) ;
00643 if ( end() == res ) { return s_default ; }
00644 return res->second ;
00645 }
00646
00677 const mapped_type& operator[] ( const key_type& key ) const
00678 { return (*this)( key ) ; }
00679
00697 const mapped_type& at ( const key_type& key ) const
00698 {
00699 iterator res = find ( key ) ;
00700 if ( end() == res ) { this->throw_out_of_range_exception () ; }
00701 return res->second ;
00702 }
00703
00704 public:
00705
00706
00707
00712 VectorMap ( const allocator_type& alloc = allocator_type () )
00713 : m_vct ( alloc )
00714 {}
00715
00719 VectorMap ( const VectorMap& right )
00720 : Gaudi::Utils::MapBase(right), m_vct ( right.m_vct )
00721 {}
00722
00729 template <class INPUT>
00730 VectorMap ( INPUT first ,
00731 INPUT last ,
00732 const allocator_type& alloc = allocator_type () )
00733 : m_vct ( first , last , alloc )
00734 { std::sort ( m_vct.begin(), m_vct.end(), compare() ) ; }
00735
00737 ~VectorMap() { clear() ; }
00738
00739
00740
00741
00742
00743 VectorMap& operator= ( const VectorMap& right )
00744 {
00745 if ( &right == this ) { return *this ; }
00746 m_vct = right.m_vct ;
00747 return *this ;
00748 }
00749
00750 public:
00751
00752
00753
00755 const compare_type& compare () const
00756 {
00757 static const compare_type s_cmp = compare_type() ;
00758 return s_cmp ;
00759 }
00761 const key_compare& compare_key () const { return compare() ; }
00763 friend std::ostream& operator<<
00764 ( std::ostream& str , const VectorMap& ) { return str ; }
00765
00766 public:
00767
00769 inline VectorMap& merge ( const VectorMap& right )
00770 {
00771 for ( const_iterator it = right.begin() ; right.end() != it ; ++it )
00772 { update ( it->first , it->second ) ; }
00773
00774 return *this ;
00775 }
00777 template <class K1,class K2, class K3,class K4>
00778 inline VectorMap& merge ( const VectorMap<K1,K2,K3,K4>& right )
00779 {
00780 for ( typename VectorMap<K1,K2,K3,K4>::const_iterator it =
00781 right.begin() ; right.end() != it ; ++it )
00782 { update ( it->first , it->second ) ; }
00783
00784 return *this ;
00785 }
00786
00787 public:
00788
00794 const key_type& key_at ( const size_t index ) const
00795 {
00796 if ( index >= size() )
00797 { this->throw_out_of_range_exception () ; }
00798 const_iterator it = this->begin() ;
00799 std::advance ( it , index ) ;
00800 return it -> first ;
00801 }
00807 const mapped_type& value_at ( const size_t index ) const
00808 {
00809 if ( index >= size() )
00810 { this->throw_out_of_range_exception () ; }
00811 const_iterator it = this->begin() ;
00812 std::advance ( it , index ) ;
00813 return it -> second ;
00814 }
00815
00816 protected:
00817
00818
00819
00825 template <class TYPE1, class TYPE2>
00826 bool compare ( const TYPE1& obj1 ,
00827 const TYPE2& obj2 ) const
00828 {
00829 return compare() ( obj1 , obj2 ) ;
00830 }
00831
00833 _iterator lower_bound ( const key_type& key )
00834 {
00835 return std::lower_bound
00836 ( m_vct.begin() , m_vct.end() , key , compare() ) ;
00837 }
00838
00840 _iterator iter ( iterator p )
00841 {
00842 _iterator result = m_vct.begin() ;
00843 std::advance ( result , std::distance ( begin() , p ) ) ;
00844 return result ;
00845 }
00846
00848 iterator iter ( _iterator p )
00849 {
00850 iterator result ( begin() ) ;
00851 std::advance ( result , std::distance ( m_vct.begin() , p ) ) ;
00852 return result ;
00853 }
00854
00855 private:
00856
00858 _vector m_vct ;
00859
00860 };
00861
00862 }
00863
00864 namespace std
00865 {
00866
00871 template
00872 < class KEY ,
00873 class VALUE ,
00874 class KEYCOMPARE ,
00875 class ALLOCATOR >
00876 inline void swap
00877 ( GaudiUtils::VectorMap<KEY,VALUE,KEYCOMPARE,ALLOCATOR>& left ,
00878 GaudiUtils::VectorMap<KEY,VALUE,KEYCOMPARE,ALLOCATOR>& right )
00879 { left.swap( right ) ; }
00880
00881 }
00882
00883
00884 namespace Gaudi
00885 {
00886
00887 namespace Parsers
00888 {
00889
00899 GAUDI_API StatusCode parse
00900 ( GaudiUtils::VectorMap<std::string, double>& result ,
00901 const std::string& input ) ;
00902
00913 GAUDI_API StatusCode parse
00914 ( GaudiUtils::VectorMap<Gaudi::StringKey, double>& result ,
00915 const std::string& input ) ;
00916
00917 }
00918
00919 }
00920
00921
00922
00923
00924
00925 #endif // GAUDIKERNEL_MAPS_H
00926