numeric.h 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #pragma once
  2. #include <util/generic/typelist.h>
  3. #include <util/system/defaults.h>
  4. #include <type_traits>
  5. /*
  6. * original url (now dead): http://www.cris.com/~Ttwang/tech/inthash.htm
  7. * copy: https://gist.github.com/badboy/6267743
  8. */
  9. static constexpr ui8 IntHashImpl(ui8 key8) noexcept {
  10. size_t key = key8;
  11. key += ~(key << 15);
  12. key ^= (key >> 10);
  13. key += (key << 3);
  14. key ^= (key >> 6);
  15. key += ~(key << 11);
  16. key ^= (key >> 16);
  17. return static_cast<ui8>(key);
  18. }
  19. static constexpr ui16 IntHashImpl(ui16 key16) noexcept {
  20. size_t key = key16;
  21. key += ~(key << 15);
  22. key ^= (key >> 10);
  23. key += (key << 3);
  24. key ^= (key >> 6);
  25. key += ~(key << 11);
  26. key ^= (key >> 16);
  27. return static_cast<ui16>(key);
  28. }
  29. static constexpr ui32 IntHashImpl(ui32 key) noexcept {
  30. key += ~(key << 15);
  31. key ^= (key >> 10);
  32. key += (key << 3);
  33. key ^= (key >> 6);
  34. key += ~(key << 11);
  35. key ^= (key >> 16);
  36. return key;
  37. }
  38. static constexpr ui64 IntHashImpl(ui64 key) noexcept {
  39. key += ~(key << 32);
  40. key ^= (key >> 22);
  41. key += ~(key << 13);
  42. key ^= (key >> 8);
  43. key += (key << 3);
  44. key ^= (key >> 15);
  45. key += ~(key << 27);
  46. key ^= (key >> 31);
  47. return key;
  48. }
  49. template <class T>
  50. static constexpr T IntHash(T t) noexcept {
  51. using TCvt = TFixedWidthUnsignedInt<T>;
  52. return IntHashImpl((TCvt)(t));
  53. }
  54. /*
  55. * can handle floats && pointers
  56. */
  57. template <class T>
  58. static constexpr size_t NumericHash(T t) noexcept {
  59. if constexpr (std::is_floating_point<T>::value) {
  60. if (t == T(0)) { // the negative zero is equal to the positive zero, but has different bitwise representation
  61. t = T(0); // make sure that the hash will be the same for both kind of zeros
  62. }
  63. }
  64. using TCvt = TFixedWidthUnsignedInt<T>;
  65. union Y_HIDDEN {
  66. T t;
  67. TCvt cvt;
  68. } u{t};
  69. return (size_t)IntHash(u.cvt);
  70. }
  71. template <class T>
  72. [[nodiscard]] static constexpr T CombineHashes(T l, T r) noexcept {
  73. return IntHash(l) ^ r;
  74. }