![]() |
|
|||
File indexing completed on 2025-03-13 09:10:06
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 // ============================================================================ 0012 #ifndef GAUDIKERNEL_VECTORMAP_H 0013 #define GAUDIKERNEL_VECTORMAP_H 1 0014 // ============================================================================ 0015 // Include files 0016 // ============================================================================ 0017 // STD & STL 0018 // ============================================================================ 0019 #include <algorithm> 0020 #include <functional> 0021 #include <initializer_list> 0022 #include <ostream> 0023 #include <utility> 0024 #include <vector> 0025 // ============================================================================ 0026 // GaudiKernel 0027 // ============================================================================ 0028 #include "GaudiKernel/MapBase.h" 0029 0030 // For parsers 0031 #include "GaudiKernel/StatusCode.h" 0032 #include "GaudiKernel/StringKey.h" 0033 // ============================================================================ 0034 namespace GaudiUtils { 0035 // ========================================================================== 0036 /** @class VectorMap GaudiKernel/VectorMap.h 0037 * 0038 * A bit modified version of 'Loki::AssocVector' associative 0039 * vector from Loki library by Andrei Alexandrescu 0040 * 0041 * The number of "non-const" operations is reduced, 0042 * e.g. all non-const iterators are not exported, 0043 * therefore it is almost impossible e.g. externally 0044 * re-sort the underlying sorted container. 0045 * 0046 * --------------------------- 0047 * The nominal CPU performance: 0048 * --------------------------- 0049 * Container insertion: O(N) 0050 * Container look-up: O(log(N)) (a'la std::map, but a bit faster) 0051 * 0052 * It could be used as a "light" and good alternative 0053 * for std::map associative container, in the case of 0054 * relatively rare insertion and frequent look-up. 0055 * 0056 * Due to helper base class Gaudi::Utils::MapBase, this class 0057 * is "python-friendly", and one can perform all python 0058 * manipulaitons 0059 * in intuitive way: 0060 * @code 0061 * 0062 * >>> m = ... ## get the map 0063 * >>> print m ## print the map a'la python class dict 0064 * ... 0065 * >>> for key in m : print key, m[key] ## iteration over the map 0066 * ... 0067 * >>> for key,value in m.iteritems() : print key, value 0068 * ... 0069 * >>> keys = m.keys() ## get the list of keys 0070 * >>> values = m.values () ## get the list of values 0071 * >> items = m.items () ## get the list of items 0072 * 0073 * >>> if 'one' in m ## check the presence of the key in map 0074 * 0075 * >>> v = m.get(key', None) ## return m[key] for existing key, else None 0076 * 0077 * >>> del m[key] ## erase the key form the map 0078 * 0079 * >>> value m[key] ## unchecked access through the key 0080 * ... 0081 * >>> m.update( key, value ) ## update/insert key/value pair 0082 * 0083 * @endcode 0084 * 0085 * @attention The syntax can be drastically simplified, if one 0086 * redefines the __setitem__ attribute: 0087 * 0088 * @code 0089 * 0090 * >>> type(m).__setitem__ = Gaudi.Utils.MapBase.__setitem__ 0091 * 0092 * >>> m[key] = value ## much more intuitive semantics for key insertion 0093 * 0094 * @endcode 0095 * In a similar way <c>__getitem__</c> and <c>__delitem__</c> methods 0096 * can be redefind 0097 * 0098 * To avoid the unnesessary expansion of dictionaries 0099 * it is highly recommended to exclude from dictionary the following methods: 0100 * - lower_bound 0101 * - upper_bound 0102 * - equal_range 0103 * - insert 0104 * 0105 * @see Gaudi::Utils::MapBase 0106 * 0107 * @author Vanya BELYAEV Ivan.Belyaev@lapp.in2p3.fr 0108 * @date 2005-07-23 0109 */ 0110 template <class KEY, class VALUE, class KEYCOMPARE = std::less<const KEY>, 0111 class ALLOCATOR = std::allocator<std::pair<KEY, VALUE>>> 0112 class VectorMap : public Gaudi::Utils::MapBase { 0113 public: 0114 // ======================================================================== 0115 /// the actual type of key 0116 typedef KEY key_type; 0117 /// the actual type of value 0118 typedef VALUE mapped_type; 0119 /// comparison of keys 0120 typedef KEYCOMPARE key_compare; 0121 /// the actual storage item 0122 typedef std::pair<key_type, mapped_type> value_type; 0123 // ======================================================================== 0124 public: 0125 // ======================================================================== 0126 /// allocator (could be useful for optimizations) 0127 typedef ALLOCATOR allocator_type; 0128 /// the types to conform STL 0129 typedef typename ALLOCATOR::value_type const& reference; 0130 /// the types to conform STL 0131 typedef typename ALLOCATOR::value_type const& const_reference; 0132 /// the types to conform STL 0133 typedef typename ALLOCATOR::size_type size_type; 0134 /// the types to conform STL 0135 typedef typename ALLOCATOR::difference_type difference_type; 0136 // ======================================================================== 0137 public: 0138 // ======================================================================== 0139 /// the actual storage container (no export) 0140 typedef std::vector<value_type, allocator_type> _vector; 0141 // ======================================================================== 0142 protected: 0143 // ======================================================================== 0144 /// the regular iterator (no export) 0145 typedef typename _vector::iterator _iterator; 0146 // ======================================================================== 0147 public: 0148 // ======================================================================== 0149 /// visible const_iterator (exported) 0150 typedef typename _vector::const_iterator iterator; 0151 /// visible const_iterator (exported) 0152 typedef typename _vector::const_iterator const_iterator; 0153 /// visible reverse const_iterator (exported) 0154 typedef std::reverse_iterator<iterator> reverse_iterator; 0155 /// visible reverse const_iterator (exported) 0156 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 0157 /// visible iterator pait 0158 typedef std::pair<iterator, iterator> iterators; 0159 /// visible iterator pait 0160 typedef std::pair<iterator, bool> result_type; 0161 // ======================================================================== 0162 public: 0163 // ======================================================================== 0164 /** @struct _compare_type 0165 * The actual structure used to compare the elements 0166 * Only "key" is important for comparison 0167 */ 0168 struct _compare_type : public key_compare { 0169 public: 0170 // ====================================================================== 0171 /// constructor from the key-comparison criteria 0172 _compare_type( const key_compare& cmp ) : key_compare( cmp ) {} 0173 /// default constructor 0174 _compare_type() : key_compare() {} 0175 /// compare keys: use key_compare 0176 bool operator()( const key_type& k1, const key_type& k2 ) const { 0177 return this->key_compare::operator()( k1, k2 ); 0178 } 0179 /// compare pairs (key,mapped): use compare by keys 0180 bool operator()( const value_type& v1, const value_type& v2 ) const { return operator()( v1.first, v2.first ); } 0181 /// compare key and pair (key,mapped): use compare by keys 0182 bool operator()( const key_type& k, const value_type& v ) const { return operator()( k, v.first ); } 0183 /// compare pair (key,mapped) and the key: use compare by keys 0184 bool operator()( const value_type& v, const key_type& k ) const { return operator()( v.first, k ); } 0185 // ====================================================================== 0186 }; 0187 // ======================================================================== 0188 /// the actual comparison criteria for valye_type objects 0189 typedef _compare_type compare_type; 0190 // ======================================================================== 0191 public: 0192 // ======================================================================== 0193 // sequential access (only const-versions!) 0194 // ======================================================================== 0195 /// "begin" iterator for sequential access (const-only version!) 0196 iterator begin() const { return m_vct.begin(); } 0197 /// "end" iterator for sequential access (const-only version!) 0198 iterator end() const { return m_vct.end(); } 0199 /// "rbegin" iterator for sequential access (const-only version!) 0200 reverse_iterator rbegin() const { return m_vct.rbegin(); } 0201 /// "rend" iterator for sequential access (const-only version!) 0202 reverse_iterator rend() const { return m_vct.rend(); } 0203 // ======================================================================== 0204 // list operations : erase & insert 0205 // ======================================================================== 0206 /** erase the element using the iterator 0207 * @param pos position of the element to be erased 0208 */ 0209 void erase( iterator pos ) { m_vct.erase( iter( pos ) ); } 0210 // ======================================================================== 0211 /** erase the element using the key 0212 * 0213 * @code 0214 * 0215 * GaudiUtils::VectorMap<K,V> m = ... ; 0216 * 0217 * ... 0218 * K key = ... ; 0219 * 0220 * std::cout << " # of erased elements " 0221 * << m.erase ( key ) << std::endl ; 0222 * @endcode 0223 * 0224 * @param key key for the element to be erased 0225 * @return number of erased elements (0 or 1) 0226 */ 0227 size_type erase( const key_type& key ) { 0228 iterator pos = find( key ); 0229 if ( end() == pos ) { return 0; } 0230 erase( pos ); 0231 return 1; 0232 } 0233 // ======================================================================== 0234 /** erase the sequence of elements using the iterators 0235 * @param first begin iterator of sub-sequence to be erased 0236 * @param end end iterator of the sub_sequence to be erased 0237 * @return number of erased elements 0238 */ 0239 size_type erase( iterator first, iterator last ) { 0240 m_vct.erase( iter( first ), iter( last ) ); 0241 return last - first; 0242 } 0243 // ======================================================================== 0244 /** erase the sequence of elements using the sequence of keys 0245 * 0246 * @code 0247 * 0248 * GaudiUtils::VectorMap<K,V> m = ... ; 0249 * 0250 * // some sequence of keys, to be removed 0251 * KEYS keys = ... ; 0252 * 0253 * std::cout 0254 * << " # keys to be removed: " << keys.size() 0255 * << " # keys removed: " << m.erase( keys.begin() , keys.end() ) 0256 * << std::endl ; 0257 * 0258 * @endcode 0259 * 0260 * @param first begin-iterator for the sequence of keys 0261 * @param last end-iterator for the sequence of keys 0262 * @return number of erased elements 0263 */ 0264 template <class TYPE> 0265 size_type erase( TYPE first, TYPE last ) { 0266 size_type res = 0; 0267 for ( ; first != last; ++first ) { res += erase( *first ); } 0268 return res; 0269 } 0270 // ======================================================================== 0271 /** insert the (key,value) pair into the container 0272 * 0273 * @attention there is no replacement for the existing key! 0274 * 0275 * It is STL-compliant behavior for associative containers. 0276 * 0277 * @code 0278 * 0279 * GaudiUtils::VectorMap<K,V> m ; 0280 * 0281 * K key = ... ; 0282 * V val1 = ... ; 0283 * V val2 = ... ; 0284 * 0285 * std::cout 0286 * << " Before insert: " << m[key] // should be: V() 0287 * << std::end ; 0288 * 0289 * // insert the value into the map: 0290 * const bool inserted1 = m.insert( key , val1 ).second ; 0291 * std::cout 0292 * << " 1st insert: " 0293 * << Gaudi::Utils::toString( inserted1 ) // should be: "True" 0294 * << " value: " << m[key] // should be: val1 0295 * << std::endl ; 0296 * 0297 * // try to re-insert another value with the same key: 0298 * const bool inserted2 = m.insert( key , val2 ).second ; 0299 * std::cout 0300 * << " 2nd insert: " 0301 * << Gaudi::Utils::toString( inserted2 ) // should be: "False" 0302 * << " value: " << m[key] // should be: val1 0303 * << std::endl ; 0304 * 0305 * @endcode 0306 * 0307 * @param key key value to be inserted 0308 * @param mapped value to be associated with the key 0309 * @return position of the inserted elements with the flag 0310 * which allows to distinguish the actual insertion 0311 */ 0312 result_type insert( const key_type& key, const mapped_type& mapped ) { return insert( value_type( key, mapped ) ); } 0313 // ======================================================================== 0314 /** insert the (key,value) pair into the container 0315 * 0316 * @attention there is no replacement for the existing element! 0317 * 0318 * It is STL-compliant behavior for associative containers. 0319 * 0320 * @code 0321 * 0322 * GaudiUtils::VectorMap<K,V> m ; 0323 * 0324 * K key = ... ; 0325 * V val1 = ... ; 0326 * V val2 = ... ; 0327 * 0328 * std::cout 0329 * << " Before insert: " << m[key] // should be: V() 0330 * << std::end ; 0331 * 0332 * // insert the value into the map: 0333 * const bool inserted1 = m.insert ( std::make_pair( key , val1 ) ).second ; 0334 * std::cout 0335 * << " 1st insert: " 0336 * << Gaudi::Utils::toString( inserted1 ) // should be: "True" 0337 * << " value: " << m[key] // should be: val1 0338 * << std::endl ; 0339 * 0340 * // try to re-insert another value with the same key: 0341 * const bool inserted2 = m.insert ( std::make_pair( key , val2 ) ).second ; 0342 * std::cout 0343 * << " 2nd insert: " 0344 * << Gaudi::Utils::toString( inserted2 ) // should be: "False" 0345 * << " value: " << m[key] // should be: val1 0346 * << std::endl ; 0347 * 0348 * @endcode 0349 * 0350 * @param value value to be inserted 0351 * @return position of the inserted elements with the flag 0352 * which allows to distinguish the actual insertion 0353 */ 0354 result_type insert( const value_type& value ) { 0355 bool found = true; 0356 _iterator result = lower_bound( value.first ); 0357 if ( end() == result || compare( value.first, result->first ) ) { 0358 result = m_vct.insert( result, value ); 0359 found = false; 0360 } 0361 return result_type( iter( result ), !found ); 0362 } 0363 // ======================================================================== 0364 /** insert the element with some guess about its new position 0365 * With the right guess the method could be more efficient 0366 * @attention there is no replacement for the existing element! 0367 * @param pos the guess about position where to insert the element 0368 * @param value value to be inserted 0369 * @return position of the inserted elements with the flag 0370 * which indicated the actual insertion 0371 */ 0372 result_type insert( iterator pos, const value_type& value ) { 0373 if ( pos != end() && compare( *pos, value ) && 0374 ( pos == end() - 1 || ( !compare( value, *( pos + 1 ) ) && compare( *( pos + 1 ), value ) ) ) ) { 0375 return result_type( m_vct.insert( iter( pos ), value ), true ); 0376 } 0377 return insert( value ); 0378 } 0379 // ======================================================================== 0380 /** insert the (key,value) pair into the container 0381 * With the right guess the method could be more efficient 0382 * @attention there is no replacement for the existing element! 0383 * @param pos the guess about position where to insert the element 0384 * @param key key value to be inserted 0385 * @param mapped value to be associated with the key 0386 * @return position of the inserted elements with the flag 0387 * which indicated the actual insertion 0388 */ 0389 result_type insert( iterator pos, const key_type& key, const mapped_type& mapped ) { 0390 return insert( pos, value_type( key, mapped ) ); 0391 } 0392 // ======================================================================== 0393 /** insert the sequence of elements into the container 0394 * @attention there is no replacement for the existing element! 0395 * @param first the begin iterator of the sequence 0396 * @param last the end iterator of the sequence 0397 */ 0398 template <class PAIRS> 0399 void insert( PAIRS first, PAIRS last ) { 0400 for ( ; first != last; ++first ) { insert( *first ); } 0401 } 0402 // ======================================================================== 0403 /** insert into the container the elements from 0404 * 2 "parallel" sequences 0405 * @attention there is no replacement for the existing element! 0406 * @param kf the begin iterator of the sequence of keys 0407 * @param kl the end iterator of the sequence of keys 0408 * @param vf the begin iterator of the sequence of values 0409 */ 0410 template <class KEYS, class VALUES> 0411 void insert( KEYS kf, KEYS kl, VALUES vf ) { 0412 for ( ; kf != kl; ++kf, ++vf ) { insert( *kf, *vf ); } 0413 } 0414 // ======================================================================== 0415 // map operations: lookup, count, ... 0416 // ======================================================================== 0417 /** find the element by key 0418 * 0419 * @code 0420 * 0421 * typedef GaudiUtils::VectorMap<K,V> Map ; 0422 * 0423 * Map m = ... ; 0424 * 0425 * K key = ...; 0426 * 0427 * // Is key in the container? 0428 * Map::iterator ifound = m.find( key ) ; 0429 * 0430 * if ( m.end() != ifound ) 0431 * { 0432 * std::cout << "The value is : " << ifound->second << std::endl ; 0433 * } 0434 * 0435 * @endcode 0436 * 0437 * @param key key to be searched 0438 * @return iterator to the element position in the container 0439 */ 0440 iterator find( const key_type& key ) const { 0441 iterator res = lower_bound( key ); 0442 if ( end() != res && compare( key, res->first ) ) { res = end(); } 0443 return res; 0444 } 0445 // ======================================================================== 0446 /** count number of elements with the certain key 0447 * 0448 * @code 0449 * 0450 * GaudiUtils::VectorMap<K,V> m = ... ; 0451 * 0452 * K key = ... ; 0453 * 0454 * std::cout << " # of elements for the key: " << m.count(key) << std::end ; 0455 * 0456 * @endcode 0457 * 0458 * @param key key to be searched 0459 * @return number of elements with the given key (0 or 1) 0460 */ 0461 size_type count( const key_type& key ) const { return end() == find( key ) ? 0 : 1; } 0462 // ======================================================================== 0463 iterator lower_bound( const key_type& key ) const { return std::lower_bound( begin(), end(), key, compare() ); } 0464 iterator upper_bound( const key_type& key ) const { return std::upper_bound( begin(), end(), key, compare() ); } 0465 iterators equal_range( const key_type& key ) const { return std::equal_range( begin(), end(), key, compare() ); } 0466 // ======================================================================== 0467 // general container operations : 0468 // ======================================================================== 0469 /// empty container ? 0470 bool empty() const { return m_vct.empty(); } 0471 /// number of elements 0472 size_type size() const { return m_vct.size(); } 0473 /// maximal allowed size 0474 size_type max_size() const { return m_vct.max_size(); } 0475 /// clear the container 0476 void clear() { m_vct.clear(); } 0477 /// reserve the space in the container for at least 'num' elements 0478 void reserve( size_type num ) { m_vct.reserve( num ); } 0479 // ======================================================================== 0480 /// swap function, which 'swaps' the content of two containers 0481 void swap( VectorMap& other ) { std::swap( m_vct, other.m_vct ); } 0482 // ======================================================================== 0483 // The basic comparison operators for container 0484 // ======================================================================== 0485 /// comparison criteria for containers 0486 bool operator==( const VectorMap& other ) const { return m_vct == other.m_vct; } 0487 /// comparison criteria for containers 0488 bool operator<( const VectorMap& other ) const { return m_vct < other.m_vct; } 0489 // ======================================================================== 0490 // The derived comparison operators for container 0491 // ======================================================================== 0492 friend bool operator>( const VectorMap& left, const VectorMap& right ) { return right < left; } 0493 friend bool operator!=( const VectorMap& left, const VectorMap& right ) { return !( left == right ); } 0494 friend bool operator>=( const VectorMap& left, const VectorMap& right ) { return !( left < right ); } 0495 friend bool operator<=( const VectorMap& left, const VectorMap& right ) { return !( right < left ); } 0496 // ======================================================================== 0497 /** forced insertion of the key/mapped pair 0498 * The method acts like "insert" but it *DOES* 0499 * overwrite the existing mapped value. 0500 * 0501 * @attention There is no STL analogue 0502 * 0503 * The method is added on request from ATLAS 0504 * (see Savannah report #21395 and #21394) 0505 * 0506 * @code 0507 * 0508 * GaudiUtils::VectorMap<K,V> m = ... ; 0509 * 0510 * K key = ... ; 0511 * V val1 = ... ; 0512 * V val2 = ... ; 0513 * 0514 * std::cout << "Value " << m[key] << std::endl ; // should be: V() 0515 * m.update ( key , val1 ) ; 0516 * std::cout << "Value " << m[key] << std::endl ; // should be: val1 0517 * m.update ( key , val2 ) ; 0518 * std::cout << "Value " << m[key] << std::endl ; // should be: val2 0519 * 0520 * @endcode 0521 * 0522 * @param key key value 0523 * @param mapped mapped value 0524 * @return true if the existing value has been replaced 0525 */ 0526 bool update( const key_type& key, const mapped_type& mapped ) { 0527 _iterator result = lower_bound( key ); 0528 if ( end() == result || compare( key, result->first ) ) { 0529 result = m_vct.insert( result, value_type( key, mapped ) ); 0530 return false; 0531 } else { 0532 result->second = mapped; 0533 } 0534 // 0535 return true; 0536 } 0537 // ======================================================================== 0538 /** forced insertion of the key/mapped pair 0539 * The method acts like "insert" but it *DOES* 0540 * overwrite the mapped value. 0541 * 0542 * @attention There is no STL analogue 0543 * 0544 * The method is added on request from ATLAS 0545 * (see Savannah report #21395 and #21394) 0546 * 0547 * @code 0548 * 0549 * GaudiUtils::VectorMap<K,V> m = ... ; 0550 * 0551 * K key = ... ; 0552 * V val1 = ... ; 0553 * V val2 = ... ; 0554 * 0555 * std::cout << "Value " << m[key] << std::endl ; // should be: V() 0556 * m.update ( std::make_pair ( key , val1 ) ) ; 0557 * std::cout << "Value " << m[key] << std::endl ; // should be: val1 0558 * m.update ( std::make_pair ( key , val2 ) ) ; 0559 * std::cout << "Value " << m[key] << std::endl ; // should be: val2 0560 * 0561 * @endcode 0562 * 0563 * @param val a pair of (key,value) 0564 * @return true if the existing value has been replaced 0565 */ 0566 bool update( const value_type& val ) { return update( val.first, val.second ); } 0567 // ======================================================================== 0568 /** access to element by key (const version) 0569 * there is no container increment for missing keys 0570 * 0571 * @attention The behavior different from std::map, 0572 * it is similar to GaudiUtils::Map 0573 * 0574 * The method is added on request from ATLAS 0575 * (see Savannah report #21395 and #21394) 0576 * For typical usage of this class in LHCb context 0577 * as "ExtraInfo" field I would like to recommend 0578 * to AVOID this method 0579 * 0580 * @code 0581 * 0582 * GaudiUtils::VectorMap<K,V> m = ... ; 0583 * 0584 * // OK: 0585 * K key = ... ; 0586 * std::cout << " Value: " << m(key) << std::end ; // it is OK! 0587 * 0588 * // ERROR: 0589 * V value = ... ; 0590 * m(key) = value ; // ERROR! 0591 * 0592 * @endcode 0593 * 0594 * @see GaudiUtils::Map 0595 * @param key key value 0596 * @return mapped value for existing key and the 0597 * default value for non-existing key 0598 */ 0599 const mapped_type& operator()( const key_type& key ) const { 0600 static const mapped_type s_default = mapped_type(); 0601 iterator res = find( key ); 0602 if ( end() == res ) { return s_default; } 0603 return res->second; 0604 } 0605 // ======================================================================== 0606 /** access to element by key (const version) 0607 * there is no container increment for missing keys 0608 * 0609 * @attention The behavior different from std::map, 0610 * it is similar to GaudiUtils::Map 0611 * 0612 * The method is added on request from ATLAS 0613 * (see Savannah report #21395 and #21394) 0614 * For typical usage of this class in LHCb context 0615 * as "ExtraInfo" field I would like to recommend 0616 * to AVOID this method 0617 * 0618 * @code 0619 * 0620 * GaudiUtils::VectorMap<K,V> m = ... ; 0621 * 0622 * // OK: 0623 * K key = ... ; 0624 * std::cout << " Value: " << m[key] << std::end ; // it is OK! 0625 * 0626 * // ERROR: 0627 * V value = ... ; 0628 * m[key] = value ; // ERROR! 0629 * 0630 * @endcode 0631 * 0632 * @see GaudiUtils::Map 0633 * @param key key value 0634 * @return mapped value 0635 */ 0636 const mapped_type& operator[]( const key_type& key ) const { return ( *this )( key ); } 0637 // ======================================================================== 0638 /** checked access to elements by key 0639 * throw std::out_of_range exception for non-existing keys 0640 * 0641 * @code 0642 * 0643 * GaudiUtils::VectorMap<K,V> m = ... ; 0644 * 0645 * // OK: 0646 * K key = ... ; 0647 * std::cout << " Value: " << m.at(key) << std::end ; // it is OK! 0648 * 0649 * @endcode 0650 * 0651 * @exception std::out_of_range for non-existing keys 0652 * @param key key value 0653 * @return mapped value 0654 */ 0655 const mapped_type& at( const key_type& key ) const { 0656 iterator res = find( key ); 0657 if ( end() == res ) { this->throw_out_of_range_exception(); } 0658 return res->second; 0659 } 0660 // ======================================================================== 0661 public: 0662 // ======================================================================== 0663 // Constructors, destructors, etc. 0664 // ======================================================================== 0665 /** default constructor from the the allocator 0666 * @param cmp comparison criteria for the key 0667 * @param alloc allocator to be used 0668 */ 0669 VectorMap( const allocator_type& alloc = allocator_type() ) : m_vct( alloc ) {} 0670 // ======================================================================== 0671 /** templated constructor from "convertible" sequence 0672 * @param first 'begin'-iterator for the convertible sequence 0673 * @param last 'end'-iterator for the convertible sequence 0674 * @param cmp comparison criteria for the key 0675 * @param alloc allocator to be used 0676 */ 0677 template <class INPUT> 0678 VectorMap( INPUT first, INPUT last, const allocator_type& alloc = allocator_type() ) : m_vct( first, last, alloc ) { 0679 std::sort( m_vct.begin(), m_vct.end(), compare() ); 0680 } 0681 // ======================================================================== 0682 /** tconstructor from initializer list 0683 * @param list 0684 * @param cmp comparison criteria for the key 0685 * @param alloc allocator to be used 0686 */ 0687 VectorMap( std::initializer_list<value_type> first, const allocator_type& alloc = allocator_type() ) 0688 : m_vct( first, alloc ) { 0689 std::sort( m_vct.begin(), m_vct.end(), compare() ); 0690 } 0691 // ======================================================================== 0692 public: 0693 // ======================================================================== 0694 // The specific public accessors 0695 // ======================================================================== 0696 /// get the comparison criteria itself 0697 const compare_type& compare() const { 0698 static const compare_type s_cmp = compare_type(); 0699 return s_cmp; 0700 } 0701 /// get the comparison criteria for keys 0702 const key_compare& compare_key() const { return compare(); } 0703 /// printout to ostream - not implemented 0704 friend std::ostream& operator<<( std::ostream& str, const VectorMap& /* obj */ ) { return str; } 0705 // ======================================================================== 0706 public: 0707 // ======================================================================== 0708 /// merge two maps 0709 inline VectorMap& merge( const VectorMap& right ) { 0710 for ( const auto& i : right ) { update( i.first, i.second ); } 0711 return *this; 0712 } 0713 /// merge two maps 0714 template <class K1, class K2, class K3, class K4> 0715 inline VectorMap& merge( const VectorMap<K1, K2, K3, K4>& right ) { 0716 for ( const auto& i : right ) { update( i.first, i.second ); } 0717 return *this; 0718 } 0719 // ======================================================================== 0720 public: 0721 // ======================================================================== 0722 /** useful method for python decoration: 0723 * @param index (INPUT) the index 0724 * @return the key at given index 0725 * @exception std::out_of_range for invalid index 0726 */ 0727 const key_type& key_at( const size_t index ) const { 0728 if ( index >= size() ) { this->throw_out_of_range_exception(); } 0729 auto it = this->begin(); 0730 std::advance( it, index ); 0731 return it->first; 0732 } 0733 /** useful method for python decoration: 0734 * @param index (INPUT) the index 0735 * @return the value at given index 0736 * @exception std::out_of_range for invalid index 0737 */ 0738 const mapped_type& value_at( const size_t index ) const { 0739 if ( index >= size() ) { this->throw_out_of_range_exception(); } 0740 auto it = this->begin(); 0741 std::advance( it, index ); 0742 return it->second; 0743 } 0744 // ======================================================================== 0745 protected: 0746 // ======================================================================== 0747 // Pure technical helper functions 0748 // ======================================================================== 0749 /** compare the objects using the comaprison criteria 0750 * @param obj the first object 0751 * @param obj the second object 0752 * @return result of (obj1,obj2) comparison 0753 */ 0754 template <class TYPE1, class TYPE2> 0755 bool compare( const TYPE1& obj1, const TYPE2& obj2 ) const { 0756 return compare()( obj1, obj2 ); 0757 } 0758 // ======================================================================== 0759 /// 'lower-bound' - non-const version 0760 _iterator lower_bound( const key_type& key ) { 0761 return std::lower_bound( m_vct.begin(), m_vct.end(), key, compare() ); 0762 } 0763 // ======================================================================== 0764 /// the conversion from 'const' to 'non-const' iterator 0765 _iterator iter( iterator p ) { 0766 auto result = m_vct.begin(); 0767 std::advance( result, std::distance( begin(), p ) ); 0768 return result; 0769 } 0770 // ======================================================================== 0771 /// the conversion from 'non-const' to 'const' iterator 0772 iterator iter( _iterator p ) { 0773 auto result = begin(); 0774 std::advance( result, std::distance( m_vct.begin(), p ) ); 0775 return result; 0776 } 0777 // ======================================================================== 0778 private: 0779 // ======================================================================== 0780 /// the underlying sorted vector of (key,mapped) pairs 0781 _vector m_vct; // the underlying sorted vector of (key,mapped) pairs 0782 // ======================================================================== 0783 }; 0784 // ========================================================================== 0785 } // end of namespace GaudiUtils 0786 // ============================================================================ 0787 namespace std { 0788 // ========================================================================== 0789 /** the definition of specialized algorithm for swapping 0790 * @param left object to be swapped 0791 * @param right object to be swapped 0792 */ 0793 template <class KEY, class VALUE, class KEYCOMPARE, class ALLOCATOR> 0794 inline void swap( GaudiUtils::VectorMap<KEY, VALUE, KEYCOMPARE, ALLOCATOR>& left, 0795 GaudiUtils::VectorMap<KEY, VALUE, KEYCOMPARE, ALLOCATOR>& right ) { 0796 left.swap( right ); 0797 } 0798 // =========================================================================== 0799 } // end of namespace std 0800 // ============================================================================ 0801 // ============================================================================ 0802 namespace Gaudi { 0803 // ========================================================================== 0804 namespace Parsers { 0805 // ======================================================================== 0806 /** parse the key from the string 0807 * @see Gaudi::Parsers 0808 * @see Gaudi::Parsers::parse 0809 * @see Gaudi::VectorMap 0810 * @attention: this function is needed to use it as property 0811 * @param result (OUTPUT) the parsing result 0812 * @param input the input string 0813 * @return status code 0814 */ 0815 GAUDI_API StatusCode parse( GaudiUtils::VectorMap<std::string, double>& result, const std::string& input ); 0816 // ======================================================================== 0817 /** parse the vector of keys from the string 0818 * @see Gaudi::Parsers 0819 * @see Gaudi::Parsers::parse 0820 * @see Gaudi::VectorMap 0821 * @see Gaudi::StringKey 0822 * @attention: this function is needed to use it as property 0823 * @param result (OUTPUT) the parsing result 0824 * @param input the input string 0825 * @return status code 0826 */ 0827 GAUDI_API StatusCode parse( GaudiUtils::VectorMap<Gaudi::StringKey, double>& result, const std::string& input ); 0828 // ======================================================================== 0829 } // namespace Parsers 0830 // ========================================================================== 0831 } // end of namespace Gaudi 0832 0833 // ============================================================================ 0834 // The END 0835 // ============================================================================ 0836 #endif // GAUDIKERNEL_MAPS_H
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |