123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- #ifndef CERES_INTERNAL_PAIR_HASH_H_
- #define CERES_INTERNAL_PAIR_HASH_H_
- #include <cstddef>
- #include <cstdint>
- #include <functional>
- #include <utility>
- #include "ceres/internal/export.h"
- namespace ceres::internal {
- #if defined(_WIN32) && !defined(__MINGW64__) && !defined(__MINGW32__)
- #define GG_LONGLONG(x) x##I64
- #define GG_ULONGLONG(x) x##UI64
- #else
- #define GG_LONGLONG(x) x##LL
- #define GG_ULONGLONG(x) x##ULL
- #endif
- inline void hash_mix(uint32_t& a, uint32_t& b, uint32_t& c) {
- a -= b; a -= c; a ^= (c>>13);
- b -= c; b -= a; b ^= (a<<8);
- c -= a; c -= b; c ^= (b>>13);
- a -= b; a -= c; a ^= (c>>12);
- b -= c; b -= a; b ^= (a<<16);
- c -= a; c -= b; c ^= (b>>5);
- a -= b; a -= c; a ^= (c>>3);
- b -= c; b -= a; b ^= (a<<10);
- c -= a; c -= b; c ^= (b>>15);
- }
- inline void hash_mix(uint64_t& a, uint64_t& b, uint64_t& c) {
- a -= b; a -= c; a ^= (c>>43);
- b -= c; b -= a; b ^= (a<<9);
- c -= a; c -= b; c ^= (b>>8);
- a -= b; a -= c; a ^= (c>>38);
- b -= c; b -= a; b ^= (a<<23);
- c -= a; c -= b; c ^= (b>>5);
- a -= b; a -= c; a ^= (c>>35);
- b -= c; b -= a; b ^= (a<<49);
- c -= a; c -= b; c ^= (b>>11);
- }
- inline uint32_t Hash32NumWithSeed(uint32_t num, uint32_t c) {
-
- uint32_t b = 0x9e3779b9UL;
- hash_mix(num, b, c);
- return c;
- }
- inline uint64_t Hash64NumWithSeed(uint64_t num, uint64_t c) {
-
- uint64_t b = GG_ULONGLONG(0xe08c1d668b756f82);
- hash_mix(num, b, c);
- return c;
- }
- struct pair_hash {
- public:
- template <typename T>
- std::size_t operator()(const std::pair<T, T>& p) const {
- const std::size_t h1 = std::hash<T>()(p.first);
- const std::size_t h2 = std::hash<T>()(p.second);
-
- return (sizeof(h1) <= sizeof(uint32_t)) ? Hash32NumWithSeed(h1, h2)
- : Hash64NumWithSeed(h1, h2);
- }
- };
- }
- #endif
|