The Battle for Wesnoth  1.19.20+dev
tstring.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2004 - 2025
3  by Philippe Plantier <ayin@anathas.org>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #pragma once
17 
18 #include <memory>
19 #include <string>
20 #include <map>
21 #include <vector>
22 
23 /**
24  * Helper class for translatable strings.
25  */
27 {
28 public:
29  class walker
30  {
31  public:
32  explicit walker(const t_string_base& string);
33 
34  operator std::string() const { return std::string(string_.data() + begin_, end_ - begin_); }
35  operator std::string_view() const { return std::string_view(string_.data() + begin_, end_ - begin_); }
36 
37  void next() { begin_ = end_; update(); }
38  bool eos() const { return begin_ == string_.size(); }
39  bool last() const { return end_ == string_.size(); }
40  bool translatable() const { return translatable_; }
41  bool countable() const { return countable_; }
42  int count() const { return count_; }
43  const std::string& textdomain() const { return textdomain_; }
44  std::string::const_iterator begin() const { return string_.begin() + begin_; }
45  std::string::const_iterator end() const { return string_.begin() + end_; }
46  std::string::const_iterator plural_begin() const;
47  std::string::const_iterator plural_end() const;
48 
49  private:
50  void update();
51 
52  const std::string& string_;
53  std::string::size_type begin_;
54  std::string::size_type end_;
55  std::string textdomain_;
57  int count_;
58  };
59 
60  friend class walker;
61 
62  t_string_base();
63 
64  /** Default implementation, but defined out-of-line for efficiency reasons. */
66 
67  /** Default implementation, but defined out-of-line for efficiency reasons. */
69  t_string_base(t_string_base&&) noexcept = default;
70  explicit t_string_base(const std::string& string);
71  explicit t_string_base(std::string&& string);
72  t_string_base(const std::string& string, const std::string& textdomain);
73  t_string_base(const std::string& sing, const std::string& pl, int count, const std::string& textdomain);
74  explicit t_string_base(const char* string);
75 
76  static t_string_base from_serialized(const std::string& string);
77  std::string to_serialized() const;
78 
79  /** Default implementation, but defined out-of-line for efficiency reasons. */
80  t_string_base& operator=(const t_string_base&);
81  t_string_base& operator=(t_string_base&&) noexcept = default;
82  t_string_base& operator=(const std::string&);
83  t_string_base& operator=(const char*);
84 
85  t_string_base operator+(const t_string_base&) const;
86  t_string_base operator+(const std::string&) const;
87  t_string_base operator+(const char*) const;
88 
89  t_string_base& operator+=(const t_string_base&);
90  t_string_base& operator+=(const std::string&);
91  t_string_base& operator+=(const char*);
92 
93  bool operator==(const t_string_base &) const;
94  bool operator==(const std::string &) const;
95  bool operator==(const char* string) const;
96 
97  bool operator!=(const t_string_base &that) const
98  { return !operator==(that); }
99  bool operator!=(const std::string &that) const
100  { return !operator==(that); }
101  bool operator!=(const char *that) const
102  { return !operator==(that); }
103 
104  bool operator<(const t_string_base& string) const;
105 
106  bool empty() const { return value_.empty(); }
107  std::string::size_type size() const { return str().size(); }
108 
109  operator const std::string&() const { return str(); }
110  operator std::string_view() const { return str(); }
111  const std::string& str() const;
112  const char* c_str() const { return str().c_str(); }
113  bool translatable() const { return translatable_; }
114 
115  // Warning: value() may contain platform dependent prefix bytes !
116  // Consider base_str() for a more reliable untranslated string
117  const std::string& value() const { return value_; }
118  std::string base_str() const;
119 
120  std::size_t hash_value() const;
121 
122 private:
123  std::string value_;
124  mutable std::string translated_value_;
125  mutable unsigned translation_timestamp_;
127  static inline std::vector<std::string> id_to_textdomain;
128  static inline std::map<std::string, unsigned int> textdomain_to_id;
129 };
130 
131 inline std::size_t hash_value(const t_string_base& str) { return str.hash_value(); }
132 std::ostream& operator<<(std::ostream&, const t_string_base&);
133 
134 class t_string
135 {
136 public:
139 
140  /** Default implementation, but defined out-of-line for efficiency reasons. */
141  t_string();
142 
143  /** Default implementation, but defined out-of-line for efficiency reasons. */
144  ~t_string();
145 
146  /** Default implementation, but defined out-of-line for efficiency reasons. */
147  t_string(const t_string&);
148 
149  t_string(t_string&&) noexcept = default;
150 
151  /** Default implementation, but defined out-of-line for efficiency reasons. */
152  t_string& operator=(const t_string&);
153 
154  t_string& operator=(t_string&&) noexcept = default;
155 
156  explicit t_string(const base &);
157  t_string(const char *);
158  t_string(const std::string &);
159  t_string(std::string&&);
160  t_string(const std::string &str, const std::string &textdomain);
161  t_string(const std::string& sing, const std::string& pl, int count, const std::string& textdomain);
162 
163  t_string& operator=(const char *o);
164 
165  static t_string from_serialized(const std::string& string) { return t_string(base::from_serialized(string)); }
166  std::string to_serialized() const { return get().to_serialized(); }
167 
168  operator const t_string_base &() const { return get(); }
169 
170  t_string operator+(const t_string& o) const { return t_string(get() + o.get()); }
171  t_string operator+(const std::string& o) const { return t_string(get() + o); }
172  t_string operator+(const char* o) const { return t_string(get() + o); }
173 
174 private:
175  template<typename T>
176  void increase_impl(const T& other)
177  {
178  base * nw = new base(get());
179  *nw += other;
180  val_.reset(nw);
181  }
182 
183 public:
184  t_string& operator+=(const t_string& o) { increase_impl(o.get()); return *this; }
185  t_string& operator+=(const std::string& o) { increase_impl(o); return *this; }
186  t_string& operator+=(const char* o) { increase_impl(o); return *this; }
187 
188  bool operator==(const t_string& o) const { return get() == o.get(); }
189  bool operator==(const std::string& o) const { return get() == o; }
190  bool operator==(const char* o) const { return get() == o; }
191 
192 #ifndef __cpp_impl_three_way_comparison
193  bool operator!=(const t_string& o) const { return !operator==(o); }
194  bool operator!=(const std::string& o) const { return !operator==(o); }
195  bool operator!=(const char* o) const { return !operator==(o); }
196 #endif
197 
198  bool operator<(const t_string& o) const { return get() < o.get(); }
199 
200  bool empty() const { return get().empty(); }
201  std::string::size_type size() const { return get().size(); }
202 
203  operator const std::string&() const { return get(); }
204  const std::string& str() const { return get().str(); }
205  operator std::string_view() const { return get().str(); }
206  const char* c_str() const { return get().c_str(); }
207  bool translatable() const { return get().translatable(); }
208  const std::string& value() const { return get().value(); }
209  std::string base_str() const { return get().base_str(); }
210 
211  static void add_textdomain(const std::string &name, const std::string &path);
212  static void reset_translations();
213 
214  const t_string_base& get() const { return *val_; }
215  void swap(t_string& other) noexcept { val_.swap(other.val_); }
216 
217 private:
218  //never null
219  std::shared_ptr<const t_string_base> val_;
220 };
221 
222 /** Implement non-member swap function for std::swap (calls @ref t_string::swap). */
223 void swap(t_string& lhs, t_string& rhs) noexcept;
224 
225 inline std::ostream& operator<<(std::ostream& os, const t_string& str) { return os << str.get(); }
226 
227 #ifndef __cpp_impl_three_way_comparison
228 inline bool operator==(const std::string &a, const t_string& b) { return b == a; }
229 inline bool operator==(const char *a, const t_string& b) { return b == a; }
230 inline bool operator!=(const std::string &a, const t_string& b) { return b != a; }
231 inline bool operator!=(const char *a, const t_string& b) { return b != a; }
232 #endif
233 
234 inline t_string operator+(const std::string &a, const t_string& b) { return t_string(a) + b; }
235 inline t_string operator+(const char *a, const t_string& b) { return t_string(a) + b; }
std::string::const_iterator begin() const
Definition: tstring.hpp:44
bool countable() const
Definition: tstring.hpp:41
std::string::const_iterator end() const
Definition: tstring.hpp:45
std::string::size_type begin_
Definition: tstring.hpp:53
bool last() const
Definition: tstring.hpp:39
std::string::const_iterator plural_end() const
Definition: tstring.cpp:206
const std::string & textdomain() const
Definition: tstring.hpp:43
walker(const t_string_base &string)
Definition: tstring.cpp:56
std::string::const_iterator plural_begin() const
Definition: tstring.cpp:197
int count() const
Definition: tstring.hpp:42
bool translatable() const
Definition: tstring.hpp:40
const std::string & string_
Definition: tstring.hpp:52
std::string::size_type end_
Definition: tstring.hpp:54
std::string textdomain_
Definition: tstring.hpp:55
bool eos() const
Definition: tstring.hpp:38
Helper class for translatable strings.
Definition: tstring.hpp:27
bool operator!=(const char *that) const
Definition: tstring.hpp:101
bool last_untranslatable_
Definition: tstring.hpp:126
std::string::size_type size() const
Definition: tstring.hpp:107
t_string_base(t_string_base &&) noexcept=default
static std::map< std::string, unsigned int > textdomain_to_id
Definition: tstring.hpp:128
bool operator!=(const std::string &that) const
Definition: tstring.hpp:99
std::string translated_value_
Definition: tstring.hpp:124
std::string to_serialized() const
Definition: tstring.cpp:375
bool operator==(const t_string_base &) const
Definition: tstring.cpp:547
bool translatable() const
Definition: tstring.hpp:113
std::string value_
Definition: tstring.hpp:123
std::string base_str() const
Definition: tstring.cpp:365
const std::string & value() const
Definition: tstring.hpp:117
bool empty() const
Definition: tstring.hpp:106
bool operator<(const t_string_base &string) const
Definition: tstring.cpp:562
static std::vector< std::string > id_to_textdomain
Definition: tstring.hpp:127
~t_string_base()
Default implementation, but defined out-of-line for efficiency reasons.
Definition: tstring.cpp:229
unsigned translation_timestamp_
Definition: tstring.hpp:125
bool translatable_
Definition: tstring.hpp:126
std::size_t hash_value() const
Definition: tstring.cpp:47
const std::string & str() const
Definition: tstring.cpp:567
static t_string_base from_serialized(const std::string &string)
Definition: tstring.cpp:340
const char * c_str() const
Definition: tstring.hpp:112
static void reset_translations()
Definition: tstring.cpp:665
static t_string from_serialized(const std::string &string)
Definition: tstring.hpp:165
static void add_textdomain(const std::string &name, const std::string &path)
Definition: tstring.cpp:657
t_string_base::walker walker
Definition: tstring.hpp:138
const std::string & value() const
Definition: tstring.hpp:208
bool operator==(const t_string &o) const
Definition: tstring.hpp:188
void swap(t_string &other) noexcept
Definition: tstring.hpp:215
bool translatable() const
Definition: tstring.hpp:207
t_string operator+(const t_string &o) const
Definition: tstring.hpp:170
~t_string()
Default implementation, but defined out-of-line for efficiency reasons.
Definition: tstring.cpp:605
t_string & operator+=(const t_string &o)
Definition: tstring.hpp:184
std::shared_ptr< const t_string_base > val_
Definition: tstring.hpp:219
t_string & operator+=(const std::string &o)
Definition: tstring.hpp:185
bool operator==(const std::string &o) const
Definition: tstring.hpp:189
t_string operator+(const char *o) const
Definition: tstring.hpp:172
bool empty() const
Definition: tstring.hpp:200
t_string(t_string &&) noexcept=default
t_string operator+(const std::string &o) const
Definition: tstring.hpp:171
bool operator==(const char *o) const
Definition: tstring.hpp:190
bool operator!=(const std::string &o) const
Definition: tstring.hpp:194
const std::string & str() const
Definition: tstring.hpp:204
t_string_base base
Definition: tstring.hpp:137
std::string base_str() const
Definition: tstring.hpp:209
std::string to_serialized() const
Definition: tstring.hpp:166
void increase_impl(const T &other)
Definition: tstring.hpp:176
t_string & operator+=(const char *o)
Definition: tstring.hpp:186
const t_string_base & get() const
Definition: tstring.hpp:214
t_string()
Default implementation, but defined out-of-line for efficiency reasons.
Definition: tstring.cpp:600
const char * c_str() const
Definition: tstring.hpp:206
bool operator!=(const char *o) const
Definition: tstring.hpp:195
std::string::size_type size() const
Definition: tstring.hpp:201
bool operator<(const t_string &o) const
Definition: tstring.hpp:198
bool operator!=(const t_string &o) const
Definition: tstring.hpp:193
std::string path
Definition: filesystem.cpp:106
static map_location::direction nw
void swap(t_string &lhs, t_string &rhs) noexcept
Implement non-member swap function for std::swap (calls t_string::swap).
Definition: tstring.cpp:670
bool operator==(const std::string &a, const t_string &b)
Definition: tstring.hpp:228
bool operator!=(const std::string &a, const t_string &b)
Definition: tstring.hpp:230
t_string operator+(const std::string &a, const t_string &b)
Definition: tstring.hpp:234
std::size_t hash_value(const t_string_base &str)
Definition: tstring.hpp:131
std::ostream & operator<<(std::ostream &, const t_string_base &)
Definition: tstring.cpp:675
#define b