![]() |
|
|||
File indexing completed on 2025-02-21 10:00:36
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 #ifndef GAUDIKERNEL_STRINGKEY_H 0012 #define GAUDIKERNEL_STRINGKEY_H 1 0013 // ============================================================================ 0014 // Include files 0015 // ============================================================================ 0016 // STD & STL 0017 // ============================================================================ 0018 #include <algorithm> 0019 #include <functional> 0020 #include <iosfwd> 0021 #include <string> 0022 #include <vector> 0023 // ============================================================================ 0024 // GaudiKernel 0025 // ============================================================================ 0026 #include "GaudiKernel/Kernel.h" 0027 #include "GaudiKernel/StatusCode.h" 0028 // ============================================================================ 0029 namespace Gaudi { 0030 // ========================================================================== 0031 /** @class StringKey GaudiKernel/StringKey.h 0032 * The helper class to represent the efficient "key" for access. 0033 * Essentially it is a bit modified version ("boost-free") of the 0034 * original class 0035 * stringKey by Gerhard Raven, which is heavily used now in HLT 0036 * 0037 * @attention NEVER use the actual hash value for anything stored in 0038 * files, as it is not guaranteed that the hashing scheme will remain 0039 * the same. 0040 * 0041 * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl 0042 * @date 2009-04-08 0043 */ 0044 class GAUDI_API StringKey { 0045 public: 0046 // ======================================================================== 0047 /// constructor from plain C-string, perform hashing 0048 StringKey( const char* key = "" ) : StringKey{ std::string{ key } } {} 0049 // 0050 /// constructor from std::string, perform hashing 0051 StringKey( std::string key ); // constructor, perform hashing 0052 // ======================================================================== 0053 public: 0054 // ======================================================================== 0055 /// the actual string 0056 const std::string& str() const { return m_str; } 0057 /// implicit cast to std::string 0058 operator const std::string&() const { return str(); } 0059 /// empty key? 0060 bool empty() const { return m_str.empty(); } 0061 /// empty key? 0062 bool operator!() const { return empty(); } 0063 // ======================================================================== 0064 public: 0065 // ======================================================================== 0066 /** equality Key 0067 * for efficiency reason compare the hash-values first 0068 */ 0069 friend bool operator==( const StringKey& lhs, const StringKey& rhs ) { 0070 return lhs.m_hash == rhs.m_hash && lhs.m_str == rhs.m_str; 0071 } 0072 /** equality, without hashing string 0073 * rely on the native string equality 0074 */ 0075 friend bool operator==( const StringKey& lhs, const std::string& rhs ) { return lhs.m_str == rhs; } 0076 friend bool operator==( const std::string& lhs, const StringKey& rhs ) { return rhs == lhs; } 0077 friend bool operator==( const StringKey& lhs, std::string_view rhs ) { return lhs.m_str == rhs; } 0078 friend bool operator==( std::string_view lhs, const StringKey& rhs ) { return rhs == lhs; } 0079 // ======================================================================== 0080 public: // non-equality 0081 // ======================================================================== 0082 /// non equality Key 0083 friend bool operator!=( const StringKey& lhs, const StringKey& rhs ) { return !( lhs == rhs ); } 0084 /// non-equality string 0085 friend bool operator!=( const StringKey& lhs, std::string_view rhs ) { return !( lhs == rhs ); } 0086 friend bool operator!=( const StringKey& lhs, const std::string& rhs ) { return !( lhs == rhs ); } 0087 friend bool operator!=( std::string_view lhs, const StringKey& rhs ) { return !( lhs == rhs ); } 0088 friend bool operator!=( const std::string& lhs, const StringKey& rhs ) { return !( lhs == rhs ); } 0089 // ======================================================================== 0090 // ordering 0091 // ======================================================================== 0092 public: 0093 /** less key 0094 * It can be used as a key for std::map, e.g. 0095 * <code>std::map<StringKey,double></code> 0096 * Note that with such maps one can gain if using prehashed key: 0097 * @code 0098 * 0099 * typedef std::map<StringKey,double> MAP ; 0100 * 0101 * const StringKey& key = ... ; 0102 * 0103 * const MAP& m = ... ; 0104 * 0105 * // EFFICIENT: 0106 * MAP::const_iterator i1 = m.find ( key ) ; 0107 * 0108 * // CAN BE VERY INEFICIENT: 0109 * MAP::const_iterator i2 = m_find( "SomeLongKey,_e.g._TES_Locaiton" ); 0110 * 0111 * @endcode 0112 */ 0113 friend bool operator<( const StringKey& lhs, const StringKey& rhs ) { 0114 return lhs.m_hash == rhs.m_hash ? lhs.m_str < rhs.m_str : lhs.m_hash < rhs.m_hash; 0115 } 0116 /// greater key 0117 friend bool operator>( const StringKey& lhs, const StringKey& rhs ) { return rhs < lhs; } 0118 /// less or equal key 0119 friend bool operator<=( const StringKey& lhs, const StringKey& rhs ) { return !( lhs > rhs ); } 0120 /// greater or equal key 0121 friend bool operator>=( const StringKey& lhs, const StringKey& rhs ) { return !( lhs < rhs ); } 0122 // ======================================================================== 0123 // few helper methods for indirect usage, mainly for Python 0124 // ======================================================================== 0125 public: 0126 /** the actual access to the hash 0127 * @attention NEVER use the actual hash value for anything stored in 0128 * files, as it is not guaranteed that the hashing scheme 0129 * will remain the same. 0130 * The two reason for this function are: 0131 * - transparent usage of this object for hashmap-like containers 0132 * - Python 0133 * @reutrn the actual hash value 0134 */ 0135 std::size_t __hash__() const { return m_hash; } 0136 // ======================================================================== 0137 /// the representation of the object 0138 std::string __str__() const; // the representation of the object 0139 /// the representation of the object 0140 std::string __repr__() const; // the representation of the object 0141 /// equality operator for python 0142 bool __eq__( const StringKey& right ) const; 0143 /// equality operators for python 0144 bool __eq__( std::string_view right ) const; 0145 /// non-equality operator for python 0146 bool __neq__( const StringKey& right ) const; 0147 /// non-equality operator for python 0148 bool __neq__( const std::string_view right ) const; 0149 // ======================================================================== 0150 public: 0151 // ======================================================================== 0152 /// string representation (for properties) 0153 std::string toString() const; // string representation (for properties) 0154 // ======================================================================== 0155 private: 0156 // ======================================================================== 0157 /// the actual string: 0158 std::string m_str; // the actual string 0159 /// the hash: 0160 std::size_t m_hash; // the hash 0161 // ======================================================================== 0162 }; 0163 // ========================================================================== 0164 /** hash-function: heeded for boost::hash 0165 * @attention NEVER use the actual hash value for anything stored in 0166 * files, as it is not guaranteed that the hashing scheme will remain 0167 * the same. The only reason for this function is Python and 0168 * transparent usage of this object for hashmap-like containers 0169 * @see Gaudi::Hash 0170 * @return the actual hash value 0171 * @author Vanya BELYAEV Iavn.Belyaev@nikhef.nl 0172 * @date 2009-10-07 0173 */ 0174 inline std::size_t hash_value( const Gaudi::StringKey& key ) { return key.__hash__(); } 0175 // ========================================================================== 0176 } // end of namespace Gaudi 0177 // interoperability with std::string and const char* 0178 inline std::string operator+( const std::string& lhs, const Gaudi::StringKey& rhs ) { return lhs + rhs.str(); } 0179 inline std::string operator+( const char* lhs, const Gaudi::StringKey& rhs ) { return lhs + rhs.str(); } 0180 inline std::string operator+( const Gaudi::StringKey& lhs, const std::string& rhs ) { return lhs.str() + rhs; } 0181 inline std::string operator+( const Gaudi::StringKey& lhs, const char* rhs ) { return lhs.str() + rhs; } 0182 // ============================================================================ 0183 // Streaming value -> string 0184 // ============================================================================ 0185 namespace Gaudi { 0186 // ========================================================================== 0187 namespace Utils { 0188 // ======================================================================== 0189 /** send the object to stream (needed to use it as property) 0190 * @see Gaudi::StringKey 0191 * @see Gaudi::Utils::toString 0192 * @see Gaudi::Utils::toStream 0193 * @param key (INPUT) the object to be printed 0194 * @param s (OUTPUT) the stream 0195 * @return the stream 0196 * @author Vanya BELYAEV Iavn.Belyaev@nikhef.nl 0197 * @date 2009-10-07 0198 */ 0199 GAUDI_API std::ostream& toStream( const Gaudi::StringKey& key, std::ostream& s ); 0200 // ======================================================================== 0201 } // namespace Utils 0202 // ========================================================================== 0203 /** printout of the object 0204 * reply on the native printout for the string 0205 * @author Vanya BELYAEV Iavn.Belyaev@nikhef.nl 0206 * @date 2009-10-07 0207 */ 0208 inline std::ostream& operator<<( std::ostream& o, const Gaudi::StringKey& key ) { return o << key.str(); } 0209 // ========================================================================== 0210 } // end of namespace Gaudi 0211 // ============================================================================ 0212 // Parsing : string -> value 0213 // ============================================================================ 0214 namespace Gaudi { 0215 // ========================================================================== 0216 namespace Parsers { 0217 // ======================================================================== 0218 /** parse the key from the string 0219 * @see Gaudi::Parsers 0220 * @see Gaudi::Parsers::parse 0221 * @see Gaudi::StringKey 0222 * @attention: this function is needed to use it as property 0223 * @param result (OUTPUT) the parsing result 0224 * @param input the input string 0225 * @return status code 0226 */ 0227 GAUDI_API StatusCode parse( Gaudi::StringKey& result, const std::string& input ); 0228 // ======================================================================== 0229 /** parse the vector of keys from the string 0230 * @see Gaudi::Parsers 0231 * @see Gaudi::Parsers::parse 0232 * @see Gaudi::StringKey 0233 * @attention: this function is needed to use it as property 0234 * @param result (OUTPUT) the parsing result 0235 * @param input the input string 0236 * @return status code 0237 */ 0238 GAUDI_API StatusCode parse( std::vector<Gaudi::StringKey>& result, const std::string& input ); 0239 // ======================================================================== 0240 } // namespace Parsers 0241 // ========================================================================== 0242 } // end of namespace Gaudi 0243 // ============================================================================ 0244 namespace std { 0245 /// specialization of hash function used in C++11 collections like 0246 /// std::unordered_map 0247 /// \see https://its.cern.ch/jira/browse/GAUDI-973 0248 template <> 0249 struct hash<Gaudi::StringKey> { 0250 inline std::size_t operator()( Gaudi::StringKey const& s ) const { return hash_value( s ); } 0251 }; 0252 } // namespace std 0253 // ============================================================================ 0254 #endif // GAUDIKERNEL_STRINGKEY_H
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |