#ifndef PORYGONLANG_HASHEDSTRING_HPP #define PORYGONLANG_HASHEDSTRING_HPP #include #include #include "StringUtils.hpp" namespace Porygon::Utilities{ class HashedString{ const uint32_t _hash; const std::shared_ptr _string; explicit HashedString(const std::u16string& s) : _hash(ConstHash(s.c_str())),_string(nullptr){ } explicit HashedString(uint32_t hash) : _hash(hash), _string(nullptr){ } public: explicit HashedString(const std::u16string* s) : _hash(ConstHash(s->c_str())), _string(std::shared_ptr(s)) { } inline static HashedString CreateLookup(const std::u16string& s){ return HashedString(s); } inline static HashedString CreateLookup(uint32_t hash){ return HashedString(hash); } HashedString(const HashedString& b) = default; inline static uint32_t constexpr ConstHash(char16_t const *input) { return *input ? static_cast(*input) + 33 * ConstHash(input + 1) : 5381; } inline static uint32_t constexpr ConstHash(char const *input) { return *input ? static_cast(*input) + 33 * ConstHash(input + 1) : 5381; } inline const uint32_t GetHash() const{ return _hash; } inline const std::shared_ptr GetString() const{ return _string; } inline const std::string GetDebugString() const{ if (_string){ return Utilities::StringUtils::FromUTF8(*_string.get()); } return std::to_string(_hash); } inline bool operator==(const HashedString& b) const{ return _hash == b._hash; } inline bool operator!=(const HashedString& b) const{ return _hash != b._hash; } inline bool operator<(const HashedString& b) const{ return _hash < b._hash; } inline bool operator>(const HashedString& b) const{ return _hash > b._hash; } std::size_t operator()(const HashedString& k) const { return _hash; } }; } namespace std { template <> struct hash { std::size_t operator()(const Porygon::Utilities::HashedString& k) const{ return k.GetHash(); } }; }; #endif //PORYGONLANG_HASHEDSTRING_HPP