#pragma once
#include <unordered_map>
#include <string>
#include <cstdint>

/**
 * name_t
 * @brief 一种用于存储字符串的类，使用哈希值作为唯一标识符
 * @note 应该尽量少的构造 name_t 对象, 因为每次构造都会在 name_map 中插入一个新的元素并 hash 字符串
 */
template<typename StringType>
struct name_t {
public:
	explicit name_t(const StringType& in_str) {
		hash_value_ = hash(in_str);
		name_map[hash_value_] = in_str;
	}

	[[nodiscard]] auto to_string() const {
		return name_map[hash_value_];
	}
private:
	static uint64_t hash(const StringType& str) {
		uint64_t hash = 5381;
		for (const auto c : str) {
			hash = (hash << 5) + hash + c; // hash * 33 + c
		}
		return hash;
	}
private:
	uint64_t hash_value_;
	inline static std::unordered_map<uint64_t, StringType> name_map;
};

using u8name_t = name_t<std::string>;
using u16name_t = name_t<std::u16string>;
using u32name_t = name_t<std::u32string>;
