summaryrefslogtreecommitdiffstats
path: root/source/core/slang-hash.h
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-05-31 17:20:37 -0400
committerGitHub <noreply@github.com>2019-05-31 17:20:37 -0400
commit6cbc3929a54d37bd23cb5efa8e3320ba02f78b2f (patch)
tree5a23cb47782e9e2a77762c90dd35da1005eba8d0 /source/core/slang-hash.h
parentb81ff3ef968d1cc4e954b31a1812b3c391d17b02 (diff)
Use slang- prefix on slang compiler and core source (#973)
* Prefixing source files in source/slang with slang- * Prefix source in source/slang with slang- prefix. * Rename core source files with slang- prefix. * Update project files. * Fix problems from automatic merge.
Diffstat (limited to 'source/core/slang-hash.h')
-rw-r--r--source/core/slang-hash.h153
1 files changed, 153 insertions, 0 deletions
diff --git a/source/core/slang-hash.h b/source/core/slang-hash.h
new file mode 100644
index 000000000..08a40491c
--- /dev/null
+++ b/source/core/slang-hash.h
@@ -0,0 +1,153 @@
+#ifndef SLANG_CORE_HASH_H
+#define SLANG_CORE_HASH_H
+
+#include "slang-math.h"
+#include <string.h>
+#include <type_traits>
+
+namespace Slang
+{
+ typedef int HashCode;
+
+ inline int GetHashCode(double key)
+ {
+ return FloatAsInt((float)key);
+ }
+ inline int GetHashCode(float key)
+ {
+ return FloatAsInt(key);
+ }
+ inline int GetHashCode(const char * buffer)
+ {
+ if (!buffer)
+ return 0;
+ int hash = 0;
+ int c;
+ auto str = buffer;
+ c = *str++;
+ while (c)
+ {
+ hash = c + (hash << 6) + (hash << 16) - hash;
+ c = *str++;
+ }
+ return hash;
+ }
+ inline int GetHashCode(char * buffer)
+ {
+ return GetHashCode(const_cast<const char *>(buffer));
+ }
+ inline int GetHashCode(const char * buffer, size_t numChars)
+ {
+ int hash = 0;
+ for (size_t i = 0; i < numChars; ++i)
+ {
+ hash = int(buffer[i]) + (hash << 6) + (hash << 16) - hash;
+ }
+ return hash;
+ }
+
+ inline uint64_t GetHashCode64(const char * buffer, size_t numChars)
+ {
+ // Use uints because hash requires wrap around behavior and int is undefined on over/underflows
+ uint64_t hash = 0;
+ for (size_t i = 0; i < numChars; ++i)
+ {
+ hash = uint64_t(int64_t(buffer[i])) + (hash << 6) + (hash << 16) - hash;
+ }
+ return hash;
+ }
+
+ template<int IsInt>
+ class Hash
+ {
+ public:
+ };
+ template<>
+ class Hash<1>
+ {
+ public:
+ template<typename TKey>
+ static int GetHashCode(TKey & key)
+ {
+ return (int)key;
+ }
+ };
+ template<>
+ class Hash<0>
+ {
+ public:
+ template<typename TKey>
+ static int GetHashCode(TKey & key)
+ {
+ return int(key.GetHashCode());
+ }
+ };
+ template<int IsPointer>
+ class PointerHash
+ {};
+ template<>
+ class PointerHash<1>
+ {
+ public:
+ template<typename TKey>
+ static int GetHashCode(TKey const& key)
+ {
+ return (int)((PtrInt)key) / 16; // sizeof(typename std::remove_pointer<TKey>::type);
+ }
+ };
+ template<>
+ class PointerHash<0>
+ {
+ public:
+ template<typename TKey>
+ static int GetHashCode(TKey & key)
+ {
+ return Hash<std::is_integral<TKey>::value || std::is_enum<TKey>::value>::GetHashCode(key);
+ }
+ };
+
+ template<typename TKey>
+ int GetHashCode(const TKey & key)
+ {
+ return PointerHash<std::is_pointer<TKey>::value>::GetHashCode(key);
+ }
+
+ template<typename TKey>
+ int GetHashCode(TKey & key)
+ {
+ return PointerHash<std::is_pointer<TKey>::value>::GetHashCode(key);
+ }
+
+ inline int combineHash(int left, int right)
+ {
+ return (left * 16777619) ^ right;
+ }
+
+ struct Hasher
+ {
+ public:
+ Hasher() {}
+
+ template<typename T>
+ void hashValue(T const& value)
+ {
+ m_hashCode = combineHash(m_hashCode, GetHashCode(value));
+ }
+
+ template<typename T>
+ void hashObject(T const& object)
+ {
+ m_hashCode = combineHash(m_hashCode, object->GetHashCode());
+ }
+
+ HashCode getResult() const
+ {
+ return m_hashCode;
+ }
+
+ private:
+ HashCode m_hashCode = 0;
+ };
+}
+
+#endif