Advertisement
Tainel

src/base/features/hash.hpp

May 26th, 2023 (edited)
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.99 KB | Source Code | 0 0
  1. #pragma once
  2.  
  3. #include"base/dependencies/index.hpp"
  4.  
  5. #include"integers.hpp"
  6. #include"random.hpp"
  7. #include"shortcuts.hpp"
  8.  
  9. // Merge two hash values.
  10. size_t hash_merge(size_t const l,size_t const r){
  11.     constexpr u64 k=0x9ddfea08eb382d69;
  12.     u64 h=r;
  13.     h=(h^l)*k,h^=(h>>47);
  14.     h=(h^l)*k,h^=(h>>47);
  15.     return static_cast<size_t>(h*k);
  16. }
  17.  
  18. // Pair hash specialization.
  19. template<class Fst,class Snd>struct hash<pair<Fst,Snd>>{
  20.     // Calculate the hash of the given pair.
  21.     size_t operator()(pair<Fst,Snd>const&p)const{
  22.         size_t h=2;
  23.         h=hash_merge(h,hash<Fst>{}(p.first));
  24.         h=hash_merge(h,hash<Snd>{}(p.second));
  25.         return h;
  26.     }
  27. };
  28.  
  29. // Tuple hash specialization.
  30. template<class...Types>struct hash<tuple<Types...>>{
  31.     // Calculate the hash of the given tuple.
  32.     size_t operator()(tuple<Types...>const&t)const{
  33.         return apply([](Types const&...args){
  34.             size_t h=sizeof...(Types);
  35.             ((h=hash_merge(h,hash<Types>{}(args))),...);
  36.             return h;
  37.         },t);
  38.     }
  39. };
  40.  
  41. // Array hash specialization.
  42. template<class Type,size_t Size>struct hash<array<Type,Size>>{
  43.     // Calculate the hash of the given array.
  44.     size_t operator()(array<Type,Size>const&a)const{
  45.         hash<Type>const hasher;
  46.         size_t h=Size;
  47.         FORE(e,a){h=hash_merge(h,hasher(e));}
  48.         return h;
  49.     }
  50. };
  51.  
  52. // Valarray hash specialization.
  53. template<class Type>struct hash<valarray<Type>>{
  54.     // Calculate the hash of the given valarray.
  55.     size_t operator()(valarray<Type>const&va)const{
  56.         hash<Type>const hasher;
  57.         size_t h=SIZE(va);
  58.         FORE(e,va){h=hash_merge(h,hasher(e));}
  59.         return h;
  60.     }
  61. };
  62.  
  63. // Hash randomizer functor.
  64. template<class Type>struct rhash{
  65.     // Calculate the randomized hash of the given object.
  66.     size_t operator()(Type const&x)const{
  67.         static u64 const noise=random_seed();
  68.         return static_cast<size_t>(splitmix64(hash<Type>{}(x)+noise));
  69.     }
  70. private:
  71.     // Unsigned 64-bit mixer.
  72.     static u64 splitmix64(u64 n){
  73.         n+=0x9e3779b97f4a7c15;
  74.         n=(n^(n>>30))*0xbf58476d1ce4e5b9;
  75.         n=(n^(n>>27))*0x94d049bb133111eb;
  76.         return n^(n>>31);
  77.     }
  78. };
  79.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement