// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // // // // MolecularDNAHashing.hh // Geant4 // // Created by Mathieu Karamitros // // #ifndef MolecularDNAHashing_h #define MolecularDNAHashing_h #include #include #include #include //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... namespace G4::hashing { namespace crc32 { //-------------------------------------------------------------------------- // Generate CRC lookup table //-------------------------------------------------------------------------- template struct f : f<((c & 1) ? 0xedb88320 : 0) ^ (c >> 1), k - 1> {}; template struct f { enum { value = c }; }; #define _A_(x) _B_(x) _B_(x + 128llu) #define _B_(x) _C_(x) _C_(x + 64llu) #define _C_(x) _D_(x) _D_(x + 32llu) #define _D_(x) _E_(x) _E_(x + 16llu) #define _E_(x) _F_(x) _F_(x + 8llu) #define _F_(x) _G_(x) _G_(x + 4llu) #define _G_(x) _H_(x) _H_(x + 2llu) #define _H_(x) _I_(x) _I_(x + 1llu) #define _I_(x) f::value, static constexpr unsigned fCrc_table[] = {_A_(0llu)}; //-------------------------------------------------------------------------- // CRC32 ALGO //-------------------------------------------------------------------------- //-------------------------------- // RUN TIME ALGO uint32_t Hash(const char* str, size_t len); //-------------------------------------------------------------------------- // Details for compilation time namespace detail { // CRC32 Table (zlib polynomial) template constexpr uint32_t Combine_crc32(const char* str, uint32_t part) { return (part >> 8) ^ fCrc_table[(part ^ str[idx]) & 0x000000FF]; } // recursion template constexpr uint32_t Crc32(const char* str) { return Combine_crc32(str, Crc32(str)); } // stop-recursion template<> constexpr uint32_t Crc32(const char* /*str*/) { return 0xFFFFFFFF; } } // namespace detail //-------------------------------------------------------------------------- // use COMPILATION TIME CRC32 as a hash function template constexpr uint32_t Hash(const char (&str)[len]) { return (detail::Crc32(str)) ^ 0xFFFFFFFF; } //-------------------------------------------------------------------------- // std::string hasher for convenience uint32_t Hash(const std::string& str); // in window // warning C4717: 'G4::hashing::crc32::crc32_hasher::operator()': // recursive on all control paths, function will cause runtime stack overflow /* template struct crc32_hasher { template uint32_t constexpr operator()(const char (&str)[len]) const { return hash(str); } uint32_t operator()(T str) const { return hash(str); } }; template uint32_t constexpr hash(T&& t) { return crc32_hasher::type>()(std::forward(t)); } */ } // namespace crc32 //-------------------------------------------------------------------------- // fnv ALGO //-------------------------------------------------------------------------- namespace fnv { // Fowler / Noll / Vo (fnv) Hash - 1a // magic numbers from http://www.isthe.com/chongo/tech/comp/fnv/ #define fnv_offset_basis 0xcbf29ce484222325U #define fnv_prime 0x100000001b3U // 64 bits // 224 + 28 + 0x93 //------------------------------------------------------------------------ // Run time size_t Hash(const std::string& str); //-------------------------------------------------------------------------- // Details for compilation time namespace detail { // recursion template constexpr size_t Fnv(const char* str, size_t len, size_t hash) { return Fnv(str, len, (hash ^ (str[len - idx])) * fnv_prime); } // stop-recursion template<> constexpr size_t Fnv<-1>(const char*, size_t, size_t hash) { return hash; } } // namespace detail //------------------------------------------------------------------------ // COMPILATION TIME template constexpr size_t Hash(const char (&str)[len]) { return detail::Fnv(str, len - 2, fnv_offset_basis); } //------------------------------------------------------------------------ template struct fnv_hasher; template struct fnv_hasher { template size_t constexpr operator()(const char (&str)[len]) const { return Hash(str); } size_t operator()(const T& str) const { return Hash(str); } }; // template<> // size_t fnv_hasher::operator()(const std::string& str) // const{ // return hash(str.c_str()); // } template size_t constexpr Hash(T&& t) { return fnv_hasher::type>()(std::forward(t)); } } // namespace fnv //-------------------------------------------------------------------------- // LARSON //-------------------------------------------------------------------------- namespace larson { //------------------------------------------------------------------------ // Details for compilation time namespace detail { // recursion template constexpr size_t Larson(const char* str, size_t len, size_t hash) { return Larson(str, len + 1, hash * 101 + str[len]); } // stop-recursion template<> constexpr size_t Larson<-1>(const char*, size_t, size_t hash) { return hash; } } // namespace detail //------------------------------------------------------------------------ // COMPILATION TIME template constexpr size_t Cthash(const char (&str)[len], unsigned int seed = 0) { return detail::Larson(str, 0, seed); } //------------------------------------------------------------------------ // RUN TIME size_t Hash(const char* str, unsigned int seed = 0); size_t Hash(std::string str, unsigned int seed = 0); } // namespace larson //-------------------------------------------------------------------------- // DEFAULT STRING HASHER //-------------------------------------------------------------------------- template struct hasher { std::size_t constexpr operator()(char const* input) const { return *input ? static_cast(*input) + 33 * (*this)(input + 1) : 5381; } std::size_t operator()(const std::string& str) const { return (*this)(str.c_str()); } }; template std::size_t constexpr Hash(T&& t) { return hasher::type>()(std::forward(t)); } // not necessary template<> std::size_t constexpr Hash(const char*&& str) { return hasher()(str); } inline namespace literals { std::size_t constexpr operator""_hash(const char* s, size_t) { return hasher()(s); } } // namespace literals } // namespace G4::hashing using namespace G4::hashing::literals; //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... #endif