z3-z3-4.13.0.src.util.hash.h Maven / Gradle / Ivy
The newest version!
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
hash.h
Abstract:
Basic hash computation support.
Author:
Leonardo de Moura (leonardo) 2006-09-11.
Revision History:
--*/
#pragma once
#include
#include "util/util.h"
#define mix(a,b,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 unsigned hash_u(unsigned a) {
a = (a+0x7ed55d16) + (a<<12);
a = (a^0xc761c23c) ^ (a>>19);
a = (a+0x165667b1) + (a<<5);
a = (a+0xd3a2646c) ^ (a<<9);
a = (a+0xfd7046c5) + (a<<3);
a = (a^0xb55a4f09) ^ (a>>16);
return a;
}
inline unsigned hash_ull(unsigned long long a) {
a = (~a) + (a << 18);
a ^= (a >> 31);
a += (a << 2) + (a << 4);
a ^= (a >> 11);
a += (a << 6);
a ^= (a >> 22);
return static_cast(a);
}
inline unsigned combine_hash(unsigned h1, unsigned h2) {
h2 -= h1; h2 ^= (h1 << 8);
h1 -= h2; h2 ^= (h1 << 16);
h2 -= h1; h2 ^= (h1 << 10);
return h2;
}
inline unsigned hash_u_u(unsigned a, unsigned b) {
return combine_hash(hash_u(a), hash_u(b));
}
unsigned string_hash(const char * str, unsigned len, unsigned init_value);
inline unsigned unsigned_ptr_hash(unsigned const* vec, unsigned len, unsigned init_value) {
return string_hash((char const*)(vec), len*4, init_value);
}
template
unsigned get_composite_hash(Composite app, unsigned n, GetKindHashProc const & khasher = GetKindHashProc(), GetChildHashProc const & chasher = GetChildHashProc()) {
unsigned a, b, c;
unsigned kind_hash = khasher(app);
a = b = 0x9e3779b9;
c = 11;
switch (n) {
case 0:
return c;
case 1:
a += kind_hash;
b = chasher(app, 0);
mix(a, b, c);
return c;
case 2:
a += kind_hash;
b += chasher(app, 0);
c += chasher(app, 1);
mix(a, b, c);
return c;
case 3:
a += chasher(app, 0);
b += chasher(app, 1);
c += chasher(app, 2);
mix(a, b, c);
a += kind_hash;
mix(a, b, c);
return c;
default:
while (n >= 3) {
n--;
a += chasher(app, n);
n--;
b += chasher(app, n);
n--;
c += chasher(app, n);
mix(a, b, c);
}
a += kind_hash;
switch (n) {
case 2:
b += chasher(app, 1);
Z3_fallthrough;
case 1:
c += chasher(app, 0);
}
mix(a, b, c);
return c;
}
}
template
struct default_kind_hash_proc { unsigned operator()(Composite const & c) const { return 17; } };
struct int_hash {
typedef int data_t;
unsigned operator()(int x) const { return static_cast(x); }
};
struct unsigned_hash {
typedef unsigned data_t;
unsigned operator()(unsigned x) const { return x; }
};
struct size_t_hash {
typedef size_t data_t;
unsigned operator()(size_t x) const { return static_cast(x); }
};
struct uint64_hash {
typedef uint64_t data_t;
unsigned operator()(uint64_t x) const { return static_cast(x); }
};
struct bool_hash {
typedef bool data_t;
unsigned operator()(bool x) const { return static_cast(x); }
};
template
struct obj_hash {
typedef T data_t;
unsigned operator()(const T & e) const {
return e.hash();
}
};
template
struct obj_ptr_hash {
typedef T * data_t;
unsigned operator()(T * a) const {
return a->hash();
}
};
template
struct obj_ptr_pair_hash {
typedef std::pair data_t;
unsigned operator()(data_t const & d) const {
return combine_hash(d.first->hash(), d.second->hash());
}
};
template
struct triple {
T1 first;
T2 second;
T3 third;
triple(): first(T1()), second(T2()), third(T3()) {}
triple(T1 f, T2 s, T3 t): first(f), second(s), third(t) {}
bool operator==(triple const& other) const {
return
first == other.first &&
second == other.second &&
third == other.third;
}
};
template
struct triple_hash : private Hash1 {
Hash2 m_hash2;
Hash3 m_hash3;
typedef triple data_t;
triple_hash(Hash1 const & h1 = Hash1(), Hash2 const & h2 = Hash2(), Hash3 const & h3 = Hash3()):
Hash1(h1),
m_hash2(h2),
m_hash3(h3) {
}
unsigned operator()(std::pair const & p) const {
return combine_hash(combine_hash(Hash1::operator()(p.first), m_hash2.operator()(p.second)), m_hash3.operator()(p.third));
}
};
template
struct obj_ptr_triple_hash {
typedef triple data_t;
unsigned operator()(data_t const & d) const {
return combine_hash(combine_hash(d.first->hash(), d.second->hash()), d.third->hash());
}
};
template
struct pair_hash : private Hash1 {
Hash2 m_hash2;
typedef std::pair data_t;
pair_hash(Hash1 const & h1 = Hash1(), Hash2 const & h2 = Hash2()):
Hash1(h1),
m_hash2(h2) {
}
unsigned operator()(std::pair const & p) const {
return combine_hash(Hash1::operator()(p.first), m_hash2.operator()(p.second));
}
};
template
inline unsigned get_ptr_hash(T * ptr) {
return static_cast(reinterpret_cast(ptr));
}
template
struct ptr_hash {
typedef T * data_t;
unsigned operator()(T * ptr) const {
return get_ptr_hash(ptr);
}
};
inline unsigned mk_mix(unsigned a, unsigned b, unsigned c) {
mix(a, b, c);
return c;
}