The Battle for Wesnoth  1.19.8+dev
tstring.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2004 - 2024
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  void next() { begin_ = end_; update(); }
35  bool eos() const { return begin_ == string_.size(); }
36  bool last() const { return end_ == string_.size(); }
37  bool translatable() const { return translatable_; }
38  bool countable() const { return countable_; }
39  int count() const { return count_; }
40  const std::string& textdomain() const { return textdomain_; }
41  std::string::const_iterator begin() const { return string_.begin() + begin_; }
42  std::string::const_iterator end() const { return string_.begin() + end_; }
43  std::string::const_iterator plural_begin() const;
44  std::string::const_iterator plural_end() const;
45 
46  private:
47  void update();
48 
49  const std::string& string_;
50  std::string::size_type begin_;
51  std::string::size_type end_;
52  std::string textdomain_;
54  int count_;
55  };
56 
57  friend class walker;
58 
59  t_string_base();
60 
61  /** Default implementation, but defined out-of-line for efficiency reasons. */
63 
64  /** Default implementation, but defined out-of-line for efficiency reasons. */
66  t_string_base(t_string_base&&) noexcept = default;
67  t_string_base(const std::string& string);
68  t_string_base(std::string&& string);
69  t_string_base(const std::string& string, const std::string& textdomain);
70  t_string_base(const std::string& sing, const std::string& pl, int count, const std::string& textdomain);
71  t_string_base(const char* string);
72 
73  static t_string_base from_serialized(const std::string& string);
74  std::string to_serialized() const;
75 
76  /** Default implementation, but defined out-of-line for efficiency reasons. */
77  t_string_base& operator=(const t_string_base&);
78  t_string_base& operator=(t_string_base&&) noexcept = default;
79  t_string_base& operator=(const std::string&);
80  t_string_base& operator=(const char*);
81 
82  t_string_base operator+(const t_string_base&) const;
83  t_string_base operator+(const std::string&) const;
84  t_string_base operator+(const char*) const;
85 
86  t_string_base& operator+=(const t_string_base&);
87  t_string_base& operator+=(const std::string&);
88  t_string_base& operator+=(const char*);
89 
90  bool operator==(const t_string_base &) const;
91  bool operator==(const std::string &) const;
92  bool operator==(const char* string) const;
93 
94  bool operator!=(const t_string_base &that) const
95  { return !operator==(that); }
96  bool operator!=(const std::string &that) const
97  { return !operator==(that); }
98  bool operator!=(const char *that) const
99  { return !operator==(that); }
100 
101  bool operator<(const t_string_base& string) const;
102 
103  bool empty() const { return value_.empty(); }
104  std::string::size_type size() const { return str().size(); }
105 
106  operator const std::string&() const { return str(); }
107  operator std::string_view() const { return str(); }
108  const std::string& str() const;
109  const char* c_str() const { return str().c_str(); }
110  bool translatable() const { return translatable_; }
111 
112  // Warning: value() may contain platform dependent prefix bytes !
113  // Consider base_str() for a more reliable untranslated string
114  const std::string& value() const { return value_; }
115  std::string base_str() const;
116 
117  std::size_t hash_value() const;
118 
119 private:
120  std::string value_;
121  mutable std::string translated_value_;
122  mutable unsigned translation_timestamp_;
124  static inline std::vector<std::string> id_to_textdomain;
125  static inline std::map<std::string, unsigned int> textdomain_to_id;
126 };
127 
128 inline std::size_t hash_value(const t_string_base& str) { return str.hash_value(); }
129 std::ostream& operator<<(std::ostream&, const t_string_base&);
130 
131 class t_string
132 {
133 public:
136 
137  /** Default implementation, but defined out-of-line for efficiency reasons. */
138  t_string();
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(const t_string&);
145 
146  t_string(t_string&&) noexcept = default;
147 
148  /** Default implementation, but defined out-of-line for efficiency reasons. */
149  t_string& operator=(const t_string&);
150 
151  t_string& operator=(t_string&&) noexcept = default;
152 
153  t_string(const base &);
154  t_string(const char *);
155  t_string(const std::string &);
156  t_string(std::string&&);
157  t_string(const std::string &str, const std::string &textdomain);
158  t_string(const std::string& sing, const std::string& pl, int count, const std::string& textdomain);
159 
160  t_string& operator=(const char *o);
161 
162  static t_string from_serialized(const std::string& string) { return t_string(base::from_serialized(string)); }
163  std::string to_serialized() const { return get().to_serialized(); }
164 
165  operator const t_string_base &() const { return get(); }
166 
167  t_string operator+(const t_string& o) const { return get() + o.get(); }
168  t_string operator+(const std::string& o) const { return get() + o; }
169  t_string operator+(const char* o) const { return get() + o; }
170 
171 private:
172  template<typename T>
173  void increase_impl(const T& other)
174  {
175  base * nw = new base(get());
176  *nw += other;
177  val_.reset(nw);
178  }
179 
180 public:
181  t_string& operator+=(const t_string& o) { increase_impl(o.get()); return *this; }
182  t_string& operator+=(const std::string& o) { increase_impl(o); return *this; }
183  t_string& operator+=(const char* o) { increase_impl(o); return *this; }
184 
185  bool operator==(const t_string& o) const { return get() == o.get(); }
186  bool operator==(const std::string& o) const { return get() == o; }
187  bool operator==(const char* o) const { return get() == o; }
188 
189  bool operator!=(const t_string& o) const { return !operator==(o); }
190  bool operator!=(const std::string& o) const { return !operator==(o); }
191  bool operator!=(const char* o) const { return !operator==(o); }
192 
193  bool operator<(const t_string& o) const { return get() < o.get(); }
194 
195  bool empty() const { return get().empty(); }
196  std::string::size_type size() const { return get().size(); }
197 
198  operator const std::string&() const { return get(); }
199  const std::string& str() const { return get().str(); }
200  operator std::string_view() const { return get().str(); }
201  const char* c_str() const { return get().c_str(); }
202  bool translatable() const { return get().translatable(); }
203  const std::string& value() const { return get().value(); }
204  std::string base_str() const { return get().base_str(); }
205 
206  static void add_textdomain(const std::string &name, const std::string &path);
207  static void reset_translations();
208 
209  const t_string_base& get() const { return *val_; }
210  void swap(t_string& other) { val_.swap(other.val_); }
211 
212 private:
213  //never null
214  std::shared_ptr<const t_string_base> val_;
215 };
216 
217 /** Implement non-member swap function for std::swap (calls @ref t_string::swap). */
218 void swap(t_string& lhs, t_string& rhs);
219 
220 inline std::ostream& operator<<(std::ostream& os, const t_string& str) { return os << str.get(); }
221 inline bool operator==(const std::string &a, const t_string& b) { return b == a; }
222 inline bool operator==(const char *a, const t_string& b) { return b == a; }
223 inline bool operator!=(const std::string &a, const t_string& b) { return b != a; }
224 inline bool operator!=(const char *a, const t_string& b) { return b != a; }
225 inline t_string operator+(const std::string &a, const t_string& b) { return t_string(a) + b; }
226 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:41
bool countable() const
Definition: tstring.hpp:38
std::string::const_iterator end() const
Definition: tstring.hpp:42
std::string::size_type begin_
Definition: tstring.hpp:50
bool last() const
Definition: tstring.hpp:36
std::string::const_iterator plural_end() const
Definition: tstring.cpp:206
const std::string & textdomain() const
Definition: tstring.hpp:40
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:39
bool translatable() const
Definition: tstring.hpp:37
const std::string & string_
Definition: tstring.hpp:49
std::string::size_type end_
Definition: tstring.hpp:51
std::string textdomain_
Definition: tstring.hpp:52
bool eos() const
Definition: tstring.hpp:35
Helper class for translatable strings.
Definition: tstring.hpp:27
bool operator!=(const char *that) const
Definition: tstring.hpp:98
bool last_untranslatable_
Definition: tstring.hpp:123
std::string::size_type size() const
Definition: tstring.hpp:104
t_string_base(t_string_base &&) noexcept=default
static std::map< std::string, unsigned int > textdomain_to_id
Definition: tstring.hpp:125
bool operator!=(const std::string &that) const
Definition: tstring.hpp:96
std::string translated_value_
Definition: tstring.hpp:121
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:110
std::string value_
Definition: tstring.hpp:120
std::string base_str() const
Definition: tstring.cpp:365
const std::string & value() const
Definition: tstring.hpp:114
bool empty() const
Definition: tstring.hpp:103
bool operator<(const t_string_base &string) const
Definition: tstring.cpp:562
static std::vector< std::string > id_to_textdomain
Definition: tstring.hpp:124
~t_string_base()
Default implementation, but defined out-of-line for efficiency reasons.
Definition: tstring.cpp:229
unsigned translation_timestamp_
Definition: tstring.hpp:122
bool translatable_
Definition: tstring.hpp:123
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:109
static void reset_translations()
Definition: tstring.cpp:665
static t_string from_serialized(const std::string &string)
Definition: tstring.hpp:162
static void add_textdomain(const std::string &name, const std::string &path)
Definition: tstring.cpp:657
t_string_base::walker walker
Definition: tstring.hpp:135
void swap(t_string &other)
Definition: tstring.hpp:210
const std::string & value() const
Definition: tstring.hpp:203
bool operator==(const t_string &o) const
Definition: tstring.hpp:185
bool translatable() const
Definition: tstring.hpp:202
t_string operator+(const t_string &o) const
Definition: tstring.hpp:167
~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:181
std::shared_ptr< const t_string_base > val_
Definition: tstring.hpp:214
t_string & operator+=(const std::string &o)
Definition: tstring.hpp:182
bool operator==(const std::string &o) const
Definition: tstring.hpp:186
t_string operator+(const char *o) const
Definition: tstring.hpp:169
bool empty() const
Definition: tstring.hpp:195
t_string(t_string &&) noexcept=default
t_string operator+(const std::string &o) const
Definition: tstring.hpp:168
bool operator==(const char *o) const
Definition: tstring.hpp:187
bool operator!=(const std::string &o) const
Definition: tstring.hpp:190
const std::string & str() const
Definition: tstring.hpp:199
t_string_base base
Definition: tstring.hpp:134
std::string base_str() const
Definition: tstring.hpp:204
std::string to_serialized() const
Definition: tstring.hpp:163
void increase_impl(const T &other)
Definition: tstring.hpp:173
t_string & operator+=(const char *o)
Definition: tstring.hpp:183
const t_string_base & get() const
Definition: tstring.hpp:209
t_string()
Default implementation, but defined out-of-line for efficiency reasons.
Definition: tstring.cpp:600
const char * c_str() const
Definition: tstring.hpp:201
bool operator!=(const char *o) const
Definition: tstring.hpp:191
std::string::size_type size() const
Definition: tstring.hpp:196
bool operator<(const t_string &o) const
Definition: tstring.hpp:193
bool operator!=(const t_string &o) const
Definition: tstring.hpp:189
std::string path
Definition: filesystem.cpp:92
static map_location::direction nw
bool operator==(const std::string &a, const t_string &b)
Definition: tstring.hpp:221
bool operator!=(const std::string &a, const t_string &b)
Definition: tstring.hpp:223
void swap(t_string &lhs, t_string &rhs)
Implement non-member swap function for std::swap (calls t_string::swap).
Definition: tstring.cpp:670
t_string operator+(const std::string &a, const t_string &b)
Definition: tstring.hpp:225
std::size_t hash_value(const t_string_base &str)
Definition: tstring.hpp:128
std::ostream & operator<<(std::ostream &, const t_string_base &)
Definition: tstring.cpp:675
#define b