Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <string_view>
- struct Name{
- Name() = default;
- constexpr bool operator==(Name other) const noexcept {
- return other.id == id;
- }
- constexpr bool operator!=(Name other) const noexcept {
- return other.id != id;
- }
- constexpr bool operator<(Name other) const noexcept {
- return (uintptr_t)id < (uintptr_t)other.id;
- }
- Name(const char* str) noexcept;
- Name(std::string_view str) noexcept;
- std::string_view to_sv() const noexcept;
- std::string to_string() const noexcept;
- const char* c_str() const noexcept { return id; }
- static constexpr const char iv[] = "INVALID";
- const char* id = iv;
- bool is_invalid() const noexcept;
- };
- namespace std {
- template<> struct hash<Name> {
- typedef Name argument_type;
- size_t operator()(argument_type const& s) const {
- return hash<const char*>()(s.id);
- }
- };
- }
- namespace eastl {
- template<> struct hash<Name> {
- typedef Name argument_type;
- size_t operator()(argument_type const& s) const {
- return hash<const char*>()(s.id);
- }
- };
- }
- //cpp
- #include "Name.hpp"
- #include <mutex>
- struct Intern {
- static constexpr size_t arr_siz = 2048;
- const char* add(std::string_view s) {
- std::lock_guard _(lock);
- auto hash = hash::fnv1a::hash(s.data(), s.size());
- if (auto it = map.find(hash); it != map.end())
- return it->second;
- for (auto& [size, bf] : buffers) {
- auto buffer = string_view(bf->data(), bf->size());
- auto pos = buffer.find(s);
- while (pos != string::npos && buffer[pos + s.size()] != '\0')
- pos = buffer.find(s, pos + 1);
- if (pos == std::string_view::npos){
- if ((size + s.size() + 1) < bf->size()) {
- auto osize = size;
- s.copy(bf->data() + size, s.size());
- *(bf->data() + size + s.size()) = '\0';
- size += s.size() + 1;
- map.emplace(hash, bf->data() + osize);
- return bf->data() + osize;
- }
- } else {
- return bf->data() + pos;
- }
- }
- buffers.resize(buffers.size() + 1);
- auto& [nsize, nbuf] = buffers.back();
- nbuf = new array<char, arr_siz>;
- s.copy(nbuf->data(), s.size());
- *(nbuf->data() + s.size()) = '\0';
- nsize += s.size() + 1;
- map.emplace(hash, nbuf->data());
- return nbuf->data();
- }
- Intern() {
- buffers.resize(1);
- buffers[0].first = 1;
- buffers[0].second = new array<char, arr_siz>;
- buffers[0].second->at(0) = '\0';
- }
- // to store the strings
- vector<pair<size_t, array<char, arr_siz>*>> buffers;
- unordered_map<u32, const char*> map;
- std::mutex lock;
- };
- static Intern g_intern;
- Name::Name(const char* str) noexcept {
- id = g_intern.add(str);
- }
- Name::Name(std::string_view str) noexcept {
- id = g_intern.add(str);
- }
- std::string_view Name::to_sv() const noexcept {
- return id;
- }
- std::string Name::to_string() const noexcept {
- return string(id);
- }
- bool Name::is_invalid() const noexcept {
- return id == &iv[0];
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement