Advertisement
Guest User

Untitled

a guest
Feb 17th, 2020
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.86 KB | None | 0 0
  1. #pragma once
  2. #include <string_view>
  3. struct Name{
  4.     Name() = default;
  5.     constexpr bool operator==(Name other) const noexcept {
  6.         return other.id == id;
  7.     }
  8.  
  9.     constexpr bool operator!=(Name other) const noexcept {
  10.         return other.id != id;
  11.     }
  12.  
  13.     constexpr bool operator<(Name other) const noexcept {
  14.         return (uintptr_t)id < (uintptr_t)other.id;
  15.     }
  16.  
  17.     Name(const char* str) noexcept;
  18.     Name(std::string_view str) noexcept;
  19.  
  20.     std::string_view to_sv() const noexcept;
  21.     std::string to_string() const noexcept;
  22.     const char* c_str() const noexcept { return id; }
  23.  
  24.     static constexpr const char iv[] = "INVALID";
  25.     const char* id = iv;
  26.  
  27.     bool is_invalid() const noexcept;
  28. };
  29.  
  30. namespace std {
  31.     template<> struct hash<Name> {
  32.         typedef Name argument_type;
  33.         size_t operator()(argument_type const& s) const {
  34.             return hash<const char*>()(s.id);
  35.         }
  36.     };
  37. }
  38.  
  39. namespace eastl {
  40.     template<> struct hash<Name> {
  41.         typedef Name argument_type;
  42.         size_t operator()(argument_type const& s) const {
  43.             return hash<const char*>()(s.id);
  44.         }
  45.     };
  46. }
  47.  
  48. //cpp
  49. #include "Name.hpp"
  50. #include <mutex>
  51.  
  52.  
  53. struct Intern {
  54.     static constexpr size_t arr_siz = 2048;
  55.  
  56.     const char* add(std::string_view s) {
  57.         std::lock_guard _(lock);
  58.  
  59.         auto hash = hash::fnv1a::hash(s.data(), s.size());
  60.         if (auto it = map.find(hash); it != map.end())
  61.             return it->second;
  62.  
  63.         for (auto& [size, bf] : buffers) {
  64.             auto buffer = string_view(bf->data(), bf->size());
  65.             auto pos = buffer.find(s);
  66.             while (pos != string::npos && buffer[pos + s.size()] != '\0')
  67.                 pos = buffer.find(s, pos + 1);
  68.             if (pos == std::string_view::npos){
  69.                 if ((size + s.size() + 1) < bf->size()) {
  70.                     auto osize = size;
  71.                     s.copy(bf->data() + size, s.size());
  72.                     *(bf->data() + size + s.size()) = '\0';
  73.                     size += s.size() + 1;
  74.                     map.emplace(hash, bf->data() + osize);
  75.                     return bf->data() + osize;
  76.                 }
  77.             } else {
  78.                 return bf->data() + pos;
  79.             }
  80.         }
  81.         buffers.resize(buffers.size() + 1);
  82.         auto& [nsize, nbuf] = buffers.back();
  83.         nbuf = new array<char, arr_siz>;
  84.         s.copy(nbuf->data(), s.size());
  85.         *(nbuf->data() + s.size()) = '\0';
  86.         nsize += s.size() + 1;
  87.         map.emplace(hash, nbuf->data());
  88.         return nbuf->data();
  89.     }
  90.  
  91.     Intern() {
  92.         buffers.resize(1);
  93.         buffers[0].first = 1;
  94.         buffers[0].second = new array<char, arr_siz>;
  95.         buffers[0].second->at(0) = '\0';
  96.     }
  97.  
  98.     // to store the strings
  99.     vector<pair<size_t, array<char, arr_siz>*>> buffers;
  100.     unordered_map<u32, const char*> map;
  101.     std::mutex lock;
  102. };
  103.  
  104. static Intern g_intern;
  105.  
  106. Name::Name(const char* str) noexcept {
  107.     id = g_intern.add(str);
  108. }
  109.  
  110. Name::Name(std::string_view str) noexcept {
  111.     id = g_intern.add(str);
  112. }
  113.  
  114. std::string_view Name::to_sv() const noexcept {
  115.     return id;
  116. }
  117.  
  118. std::string Name::to_string() const noexcept {
  119.     return string(id);
  120. }
  121.  
  122. bool Name::is_invalid() const noexcept {
  123.     return id == &iv[0];
  124. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement