Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-23 09:21:58

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 //
0027 //
0028 //  MolecularDNAHashing.hh
0029 //  Geant4
0030 //
0031 //  Created by Mathieu Karamitros
0032 //
0033 //
0034 
0035 #ifndef MolecularDNAHashing_h
0036 #define MolecularDNAHashing_h
0037 
0038 #include <cstdint>
0039 #include <string>
0040 #include <type_traits>
0041 #include <utility>
0042 
0043 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0044 
0045 namespace G4::hashing
0046 {
0047 namespace crc32
0048 {
0049 //--------------------------------------------------------------------------
0050 // Generate CRC lookup table
0051 //--------------------------------------------------------------------------
0052 
0053 template<unsigned long long c, int k = 8>
0054 struct f : f<((c & 1) ? 0xedb88320 : 0) ^ (c >> 1), k - 1>
0055 {};
0056 template<unsigned long long c>
0057 struct f<c, 0>
0058 {
0059     enum
0060     {
0061       value = c
0062     };
0063 };
0064 
0065 #define _A_(x) _B_(x) _B_(x + 128llu)
0066 #define _B_(x) _C_(x) _C_(x + 64llu)
0067 #define _C_(x) _D_(x) _D_(x + 32llu)
0068 #define _D_(x) _E_(x) _E_(x + 16llu)
0069 #define _E_(x) _F_(x) _F_(x + 8llu)
0070 #define _F_(x) _G_(x) _G_(x + 4llu)
0071 #define _G_(x) _H_(x) _H_(x + 2llu)
0072 #define _H_(x) _I_(x) _I_(x + 1llu)
0073 #define _I_(x) f<x>::value,
0074 
0075 static constexpr unsigned fCrc_table[] = {_A_(0llu)};
0076 
0077 //--------------------------------------------------------------------------
0078 // CRC32 ALGO
0079 //--------------------------------------------------------------------------
0080 
0081 //--------------------------------
0082 // RUN TIME ALGO
0083 uint32_t Hash(const char* str, size_t len);
0084 
0085 //--------------------------------------------------------------------------
0086 // Details for compilation time
0087 namespace detail
0088 {
0089 // CRC32 Table (zlib polynomial)
0090 template<size_t idx>
0091 constexpr uint32_t Combine_crc32(const char* str, uint32_t part)
0092 {
0093   return (part >> 8) ^ fCrc_table[(part ^ str[idx]) & 0x000000FF];
0094 }
0095 
0096 // recursion
0097 template<size_t idx>
0098 constexpr uint32_t Crc32(const char* str)
0099 {
0100   return Combine_crc32<idx>(str, Crc32<idx - 1>(str));
0101 }
0102 
0103 // stop-recursion
0104 template<>
0105 constexpr uint32_t Crc32<size_t(-1)>(const char* /*str*/)
0106 {
0107   return 0xFFFFFFFF;
0108 }
0109 }  // namespace detail
0110 
0111 //--------------------------------------------------------------------------
0112 // use COMPILATION TIME CRC32 as a hash function
0113 template<size_t len>
0114 constexpr uint32_t Hash(const char (&str)[len])
0115 {
0116   return (detail::Crc32<len - 2>(str)) ^ 0xFFFFFFFF;
0117 }
0118 
0119 //--------------------------------------------------------------------------
0120 // std::string hasher for convenience
0121 uint32_t Hash(const std::string& str);
0122 // in window
0123 // warning C4717: 'G4::hashing::crc32::crc32_hasher<G4String>::operator()': recursive on all control
0124 // paths, function will cause runtime stack overflow
0125 /*
0126 template <typename T>
0127 struct crc32_hasher
0128 {
0129   template <size_t len>
0130   uint32_t constexpr operator()(const char (&str)[len]) const
0131   {
0132     return hash(str);
0133   }
0134 
0135   uint32_t operator()(T str) const { return hash(str); }
0136 };
0137 
0138 template <typename T>
0139 uint32_t constexpr hash(T&& t)
0140 {
0141   return crc32_hasher<typename std::decay<T>::type>()(std::forward<T>(t));
0142 }
0143 */
0144 }  // namespace crc32
0145 
0146 //--------------------------------------------------------------------------
0147 // fnv ALGO
0148 //--------------------------------------------------------------------------
0149 
0150 namespace fnv
0151 {
0152 // Fowler / Noll / Vo (fnv) Hash - 1a
0153 // magic numbers from http://www.isthe.com/chongo/tech/comp/fnv/
0154 #define fnv_offset_basis 0xcbf29ce484222325U
0155 #define fnv_prime 0x100000001b3U  // 64 bits
0156 // 224 + 28 + 0x93
0157 
0158 //------------------------------------------------------------------------
0159 // Run time
0160 size_t Hash(const std::string& str);
0161 
0162 //--------------------------------------------------------------------------
0163 // Details for compilation time
0164 namespace detail
0165 {
0166 // recursion
0167 template<int idx>
0168 constexpr size_t Fnv(const char* str, size_t len, size_t hash)
0169 {
0170   return Fnv<idx - 1>(str, len, (hash ^ (str[len - idx])) * fnv_prime);
0171 }
0172 
0173 // stop-recursion
0174 template<>
0175 constexpr size_t Fnv<-1>(const char*, size_t, size_t hash)
0176 {
0177   return hash;
0178 }
0179 }  // namespace detail
0180 
0181 //------------------------------------------------------------------------
0182 // COMPILATION TIME
0183 template<size_t len>
0184 constexpr size_t Hash(const char (&str)[len])
0185 {
0186   return detail::Fnv<len - 2>(str, len - 2, fnv_offset_basis);
0187 }
0188 
0189 //------------------------------------------------------------------------
0190 template<class>
0191 struct fnv_hasher;
0192 
0193 template<typename T>
0194 struct fnv_hasher
0195 {
0196     template<size_t len>
0197     size_t constexpr operator()(const char (&str)[len]) const
0198     {
0199       return Hash(str);
0200     }
0201 
0202     size_t operator()(const T& str) const { return Hash(str); }
0203 };
0204 
0205 //      template<>
0206 //      size_t fnv_hasher<std::string>::operator()(const std::string& str)
0207 //      const{
0208 //          return hash(str.c_str());
0209 //      }
0210 
0211 template<typename T>
0212 size_t constexpr Hash(T&& t)
0213 {
0214   return fnv_hasher<typename std::decay<T>::type>()(std::forward<T>(t));
0215 }
0216 }  // namespace fnv
0217 
0218 //--------------------------------------------------------------------------
0219 // LARSON
0220 //--------------------------------------------------------------------------
0221 
0222 namespace larson
0223 {
0224 //------------------------------------------------------------------------
0225 // Details for compilation time
0226 namespace detail
0227 {
0228 // recursion
0229 template<int idx>
0230 constexpr size_t Larson(const char* str, size_t len, size_t hash)
0231 {
0232   return Larson<idx - 1>(str, len + 1, hash * 101 + str[len]);
0233 }
0234 
0235 // stop-recursion
0236 template<>
0237 constexpr size_t Larson<-1>(const char*, size_t, size_t hash)
0238 {
0239   return hash;
0240 }
0241 }  // namespace detail
0242 
0243 //------------------------------------------------------------------------
0244 // COMPILATION TIME
0245 template<size_t len>
0246 constexpr size_t Cthash(const char (&str)[len], unsigned int seed = 0)
0247 {
0248   return detail::Larson<len - 2>(str, 0, seed);
0249 }
0250 
0251 //------------------------------------------------------------------------
0252 // RUN TIME
0253 size_t Hash(const char* str, unsigned int seed = 0);
0254 
0255 size_t Hash(std::string str, unsigned int seed = 0);
0256 }  // namespace larson
0257 
0258 //--------------------------------------------------------------------------
0259 // DEFAULT STRING HASHER
0260 //--------------------------------------------------------------------------
0261 
0262 template<typename T>
0263 struct hasher
0264 {
0265     std::size_t constexpr operator()(char const* input) const
0266     {
0267       return *input ? static_cast<std::size_t>(*input) + 33 * (*this)(input + 1) : 5381;
0268     }
0269 
0270     std::size_t operator()(const std::string& str) const { return (*this)(str.c_str()); }
0271 };
0272 
0273 template<typename T>
0274 std::size_t constexpr Hash(T&& t)
0275 {
0276   return hasher<typename std::decay<T>::type>()(std::forward<T>(t));
0277 }
0278 
0279 // not necessary
0280 template<>
0281 std::size_t constexpr Hash<const char*>(const char*&& str)
0282 {
0283   return hasher<std::string>()(str);
0284 }
0285 
0286 inline namespace literals
0287 {
0288 std::size_t constexpr operator"" _hash(const char* s, size_t)
0289 {
0290   return hasher<std::string>()(s);
0291 }
0292 }  // namespace literals
0293 }  // namespace G4::hashing
0294 
0295 using namespace G4::hashing::literals;
0296 
0297 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0298 
0299 #endif