Symphony Of Empires
string.hpp
Go to the documentation of this file.
1 // Eng3D - General purpouse game engine
2 // Copyright (C) 2021, Eng3D contributors
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <https://www.gnu.org/licenses/>.
16 //
17 // ----------------------------------------------------------------------------
18 // Name:
19 // string.hpp
20 //
21 // Abstract:
22 // Provides automatic pooling of strings and string formatting utilities.
23 // ----------------------------------------------------------------------------
24 
25 #pragma once
26 
27 #include <string>
28 #include <vector>
29 #include <cstdint>
30 #include <mutex>
31 #include <memory>
32 #include <compare>
33 #include <iterator>
34 #include <stdexcept>
35 #include "eng3d/utils.hpp"
36 
37 namespace Eng3D {
39  struct StringRef {
40  constexpr StringRef() = default;
41  StringRef(const std::string_view str);
42  constexpr StringRef(size_t _id)
43  : id{ _id }
44  {
45 
46  }
47  StringRef& operator=(const std::string& rhs) {
48  *this = StringRef(rhs);
49  return *this;
50  }
51  const std::string_view get_string() const;
52  constexpr bool operator==(const StringRef&) const noexcept = default;
53  constexpr auto operator<=>(const StringRef&) const noexcept = default;
54 
55  const char* c_str() const {
56  return this->get_string().data();
57  }
58 
59  operator std::string() const {
60  return std::string(this->get_string());
61  }
62 
63  size_t get_id() const { return id; }
64  size_t id = 0;
65  };
66 
67  class State;
70  class StringManager {
71  Eng3D::State& s;
72  public:
74  ~StringManager() = default;
75 
76  Eng3D::StringRef insert(const std::string& str) {
77  const std::scoped_lock lock(strings_mutex);
78  const auto id = strings.size();
79  std::copy(str.begin(), str.end(), std::back_inserter(strings));
80  strings.push_back('\0');
81  return Eng3D::StringRef(id);
82  }
83 
84  const std::string_view get_by_id(const Eng3D::StringRef ref) const {
85  const std::scoped_lock lock(strings_mutex);
86  return &strings[ref.get_id()];
87  }
88 
89  std::vector<char> strings;
90  static StringManager& get_instance();
91  mutable std::mutex strings_mutex;
92  };
93 
99  template<typename ... Args>
100  std::string string_format(const std::string_view format, Args&& ... args) {
101 #pragma clang diagnostic push
102 #pragma clang diagnostic ignored "-Wformat-security"
103  int size_s = std::snprintf(nullptr, 0, format.data(), std::forward<decltype(args)>(args)...) + 1; // Extra space for '\0'
104  if(size_s <= 0)
105  CXX_THROW(std::runtime_error, "Error during formatting");
106  size_t size = static_cast<size_t>(size_s);
107  std::unique_ptr<char[]> buf = std::make_unique<char[]>(size);
108  std::snprintf(buf.get(), size, format.data(), args ...);
109  return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
110 #pragma clang diagnostic pop
111  }
112 }
114 
115 namespace Eng3D::Locale {
116  void from_file(const std::string& filename);
117  std::string translate(const std::string_view str);
118 }
120 
121 namespace Eng3D {
127  template<typename ... Args>
128  std::string translate_format(const std::string_view format, Args&& ... args) {
129  return Eng3D::string_format(Eng3D::Locale::translate(format), std::forward<decltype(args)>(args)...);
130  }
131 }
The string pool manager (singleton), used mainly for translation purpouses. But also helps to reduce ...
Definition: string.hpp:70
const std::string_view get_by_id(const Eng3D::StringRef ref) const
Definition: string.hpp:84
~StringManager()=default
std::mutex strings_mutex
Definition: string.hpp:91
static StringManager & get_instance()
Definition: string.cpp:53
StringManager(Eng3D::State &_s)
Definition: string.cpp:47
std::vector< char > strings
Definition: string.hpp:89
Eng3D::StringRef insert(const std::string &str)
Definition: string.hpp:76
void from_file(const std::string &filename)
Definition: string.cpp:59
std::string translate(const std::string_view str)
Definition: string.cpp:76
std::string string_format(const std::string_view format, Args &&... args)
String formatter.
Definition: string.hpp:100
std::string translate_format(const std::string_view format, Args &&... args)
String formatter, with translation.
Definition: string.hpp:128
A reference to a string on the global string pool.
Definition: string.hpp:39
constexpr bool operator==(const StringRef &) const noexcept=default
const char * c_str() const
Definition: string.hpp:55
constexpr auto operator<=>(const StringRef &) const noexcept=default
size_t get_id() const
Definition: string.hpp:63
constexpr StringRef()=default
const std::string_view get_string() const
Definition: string.cpp:38
constexpr StringRef(size_t _id)
Definition: string.hpp:42
StringRef & operator=(const std::string &rhs)
Definition: string.hpp:47
#define CXX_THROW(class,...)
Definition: utils.hpp:98