numeric.h 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #pragma once
  2. #include <util/generic/typelist.h>
  3. #include <util/system/defaults.h>
  4. /*
  5. * original url (now dead): http://www.cris.com/~Ttwang/tech/inthash.htm
  6. * copy: https://gist.github.com/badboy/6267743
  7. */
  8. static constexpr ui8 IntHashImpl(ui8 key8) noexcept {
  9. size_t key = key8;
  10. key += ~(key << 15);
  11. key ^= (key >> 10);
  12. key += (key << 3);
  13. key ^= (key >> 6);
  14. key += ~(key << 11);
  15. key ^= (key >> 16);
  16. return static_cast<ui8>(key);
  17. }
  18. static constexpr ui16 IntHashImpl(ui16 key16) noexcept {
  19. size_t key = key16;
  20. key += ~(key << 15);
  21. key ^= (key >> 10);
  22. key += (key << 3);
  23. key ^= (key >> 6);
  24. key += ~(key << 11);
  25. key ^= (key >> 16);
  26. return static_cast<ui16>(key);
  27. }
  28. static constexpr ui32 IntHashImpl(ui32 key) noexcept {
  29. key += ~(key << 15);
  30. key ^= (key >> 10);
  31. key += (key << 3);
  32. key ^= (key >> 6);
  33. key += ~(key << 11);
  34. key ^= (key >> 16);
  35. return key;
  36. }
  37. static constexpr ui64 IntHashImpl(ui64 key) noexcept {
  38. key += ~(key << 32);
  39. key ^= (key >> 22);
  40. key += ~(key << 13);
  41. key ^= (key >> 8);
  42. key += (key << 3);
  43. key ^= (key >> 15);
  44. key += ~(key << 27);
  45. key ^= (key >> 31);
  46. return key;
  47. }
  48. template <class T>
  49. static constexpr T IntHash(T t) noexcept {
  50. using TCvt = TFixedWidthUnsignedInt<T>;
  51. return IntHashImpl((TCvt)(t));
  52. }
  53. /*
  54. * can handle floats && pointers
  55. */
  56. template <class T>
  57. static constexpr size_t NumericHash(T t) noexcept {
  58. using TCvt = TFixedWidthUnsignedInt<T>;
  59. union Y_HIDDEN {
  60. T t;
  61. TCvt cvt;
  62. } u{t};
  63. return (size_t)IntHash(u.cvt);
  64. }
  65. template <class T>
  66. static constexpr T CombineHashes(T l, T r) noexcept {
  67. return IntHash(l) ^ r;
  68. }