Hash.h
// Hash.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2019
#pragma once
#ifndef Ceda_cxUtils_Hash_H
#define Ceda_cxUtils_Hash_H
#include "cxUtils.h"
#include "BasicTypes.h"
#include "HPTime.h"
#include "xdeque.h"
#include "xvector.h"
#include <functional>
#include <deque>
#include <list>
#include <vector>
#include <map>
#include <set>
#include <string>
namespace ceda
{
typedef uint64 hash_t;
class HashArchive
{
public:
// Allow implicit conversions to/from a uint64
HashArchive(hash_t v) : hash_(v) {}
operator hash_t() const { return hash_; }
private:
hash_t hash_;
};
template<typename It>
inline HashArchive HashRange(HashArchive ar, It begin, It end)
{
while(begin != end)
{
ar = ar << *begin;
++begin;
}
return ar;
}
inline hash_t HashValue(bool v) { return (hash_t)v; }
inline hash_t HashValue(char v) { return (hash_t)v; }
inline hash_t HashValue(signed char v) { return (hash_t)v; }
inline hash_t HashValue(unsigned char v) { return (hash_t)v; }
//inline hash_t HashValue(char8_t v) { return (hash_t)v; }
inline hash_t HashValue(char16_t v) { return (hash_t)v; }
inline hash_t HashValue(char32_t v) { return (hash_t)v; }
inline hash_t HashValue(wchar_t v) { return (hash_t)v; }
inline hash_t HashValue(short v) { return (hash_t)v; }
inline hash_t HashValue(unsigned short v) { return (hash_t)v; }
inline hash_t HashValue(int v) { return (hash_t)v; }
inline hash_t HashValue(unsigned int v) { return (hash_t)v; }
inline hash_t HashValue(long v) { return (hash_t)v; }
inline hash_t HashValue(unsigned long v) { return (hash_t)v; }
inline hash_t HashValue(long long v) { return (hash_t)v; }
inline hash_t HashValue(unsigned long long v) { return (hash_t)v; }
inline hash_t HashValue(float v) { return *reinterpret_cast<const uint32*>(&v); }
inline hash_t HashValue(double v) { return *reinterpret_cast<const uint64*>(&v); }
inline hash_t HashValue(long double v) { return *reinterpret_cast<const uint64*>(&v); }
/*
template <typename T>
hash_t HashCombine(hash_t seed, const T& v)
{
std::hash<T> hasher;
return seed ^ (hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
}
*/
template <typename T>
hash_t HashCombine(hash_t seed, const T& v)
{
return seed ^ (HashValue(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
}
inline HashArchive operator<<(HashArchive ar, bool f) { return HashCombine(ar,f); }
inline HashArchive operator<<(HashArchive ar, int8 f) { return HashCombine(ar,f); }
inline HashArchive operator<<(HashArchive ar, uint8 f) { return HashCombine(ar,f); }
inline HashArchive operator<<(HashArchive ar, int16 f) { return HashCombine(ar,f); }
inline HashArchive operator<<(HashArchive ar, uint16 f) { return HashCombine(ar,f); }
inline HashArchive operator<<(HashArchive ar, int32 f) { return HashCombine(ar,f); }
inline HashArchive operator<<(HashArchive ar, uint32 f) { return HashCombine(ar,f); }
inline HashArchive operator<<(HashArchive ar, int64 f) { return HashCombine(ar,f); }
inline HashArchive operator<<(HashArchive ar, uint64 f) { return HashCombine(ar,f); }
inline HashArchive operator<<(HashArchive ar, float32 f) { return HashCombine(ar,f); }
inline HashArchive operator<<(HashArchive ar, float64 f) { return HashCombine(ar,f); }
inline HashArchive operator<<(HashArchive ar, char f) { return HashCombine(ar,f); }
template <typename T,typename A>
HashArchive operator<<(HashArchive ar, const std::vector<T,A>& x)
{
return HashRange(ar, x.begin(), x.end());
}
HashArchive operator<<(HashArchive ar, const std::string& x)
{
return HashRange(ar, x.begin(), x.end());
}
template <typename T,typename A>
HashArchive operator<<(HashArchive ar, const std::deque<T,A>& x)
{
return HashRange(ar, x.begin(), x.end());
}
template <typename T,typename A>
HashArchive operator<<(HashArchive ar, const std::list<T,A>& x)
{
return HashRange(ar, x.begin(), x.end());
}
HashArchive operator<<(HashArchive ar, const HPTime& x)
{
return ar << x.m_ticks;
}
template <typename U, typename V>
HashArchive operator<<(HashArchive ar, const std::pair<U,V>& x)
{
return ar << x.first << x.second;
}
template <typename K,typename T,typename P,typename A>
HashArchive operator<<(HashArchive ar, const std::map<K,T,P,A>& x)
{
return HashRange(ar, x.begin(), x.end());
}
template <typename K,typename P,typename A>
HashArchive operator<<(HashArchive ar, const std::set<K,P,A>& x)
{
return HashRange(ar, x.begin(), x.end());
}
template <typename T,ssize_t pageSize>
HashArchive operator<<(HashArchive ar, const xdeque<T,pageSize>& x)
{
return HashRange(ar, x.begin(), x.end());
}
template <typename T>
HashArchive operator<<(HashArchive ar, const xvector<T>& x)
{
return HashRange(ar, x.begin(), x.end());
}
} // namespace ceda
#endif // include guard