File indexing completed on 2025-02-23 09:21:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
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
0044
0045 namespace G4::hashing
0046 {
0047 namespace crc32
0048 {
0049
0050
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
0079
0080
0081
0082
0083 uint32_t Hash(const char* str, size_t len);
0084
0085
0086
0087 namespace detail
0088 {
0089
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
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
0104 template<>
0105 constexpr uint32_t Crc32<size_t(-1)>(const char* )
0106 {
0107 return 0xFFFFFFFF;
0108 }
0109 }
0110
0111
0112
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
0121 uint32_t Hash(const std::string& str);
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144 }
0145
0146
0147
0148
0149
0150 namespace fnv
0151 {
0152
0153
0154 #define fnv_offset_basis 0xcbf29ce484222325U
0155 #define fnv_prime 0x100000001b3U
0156
0157
0158
0159
0160 size_t Hash(const std::string& str);
0161
0162
0163
0164 namespace detail
0165 {
0166
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
0174 template<>
0175 constexpr size_t Fnv<-1>(const char*, size_t, size_t hash)
0176 {
0177 return hash;
0178 }
0179 }
0180
0181
0182
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
0206
0207
0208
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 }
0217
0218
0219
0220
0221
0222 namespace larson
0223 {
0224
0225
0226 namespace detail
0227 {
0228
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
0236 template<>
0237 constexpr size_t Larson<-1>(const char*, size_t, size_t hash)
0238 {
0239 return hash;
0240 }
0241 }
0242
0243
0244
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
0253 size_t Hash(const char* str, unsigned int seed = 0);
0254
0255 size_t Hash(std::string str, unsigned int seed = 0);
0256 }
0257
0258
0259
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
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 }
0293 }
0294
0295 using namespace G4::hashing::literals;
0296
0297
0298
0299 #endif