strings_bank.h 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #ifndef __STRINGS_BANK_H
  2. #define __STRINGS_BANK_H
  3. #include <cstdint>
  4. #include <stdexcept>
  5. #include <unordered_map>
  6. constexpr uint64_t fnv64a_hash(const char* s, size_t len) {
  7. return (*s == '\0' ?
  8. 0xcbf29ce484222325ULL :
  9. (fnv64a_hash(s + 1, len - 1) ^ (uint64_t)(*s)) * 0x100000001b3ULL);
  10. }
  11. constexpr uint64_t operator"" _hash(const char* s, size_t len) {
  12. return fnv64a_hash(s, len);
  13. }
  14. struct StringsBank {
  15. std::unordered_map<uint64_t,std::string> bank;
  16. const std::string& get(uint64_t hash, const std::string& str) const {
  17. auto i = bank.find(hash);
  18. if (i == bank.end())
  19. return str;
  20. return i->second;
  21. }
  22. void set(uint64_t hash, const std::string& str) {
  23. auto i = bank.find(hash);
  24. if (i != bank.end())
  25. throw std::runtime_error("Duplicate strings bank hash for: '" + str + "'");
  26. bank[hash] = str;
  27. }
  28. };
  29. inline StringsBank& __strings__() {
  30. static StringsBank ret;
  31. return ret;
  32. }
  33. inline const StringsBank& strings() {
  34. return __strings__();
  35. }
  36. inline void init_strings_copy(uint64_t hash, const std::string& to) {
  37. __strings__().set(hash, to);
  38. }
  39. struct hash_and_string {
  40. uint64_t hash;
  41. const char* str;
  42. constexpr hash_and_string(uint64_t h, const char* s) : hash(h), str(s) {}
  43. operator std::string() const {
  44. return strings().get(hash, str);
  45. }
  46. };
  47. constexpr hash_and_string operator"" _m(const char* s, size_t len) {
  48. return hash_and_string(fnv64a_hash(s, len), s);
  49. }
  50. #endif