Back to home page

EIC code displayed by LXR

 
 

    


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