The Battle for Wesnoth  1.19.5+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  const std::string& str() const;
108  const char* c_str() const { return str().c_str(); }
109  bool translatable() const { return translatable_; }
110 
111  // Warning: value() may contain platform dependent prefix bytes !
112  // Consider base_str() for a more reliable untranslated string
113  const std::string& value() const { return value_; }
114  std::string base_str() const;
115 
116  std::size_t hash_value() const;
117 
118 private:
119  std::string value_;
120  mutable std::string translated_value_;
121  mutable unsigned translation_timestamp_;
123  static inline std::vector<std::string> id_to_textdomain;
124  static inline std::map<std::string, unsigned int> textdomain_to_id;
125 };
126 
127 inline std::size_t hash_value(const t_string_base& str) { return str.hash_value(); }
128 std::ostream& operator<<(std::ostream&, const t_string_base&);
129 
130 class t_string
131 {
132 public:
135 
136  /** Default implementation, but defined out-of-line for efficiency reasons. */
137  t_string();
138 
139  /** Default implementation, but defined out-of-line for efficiency reasons. */
140  ~t_string();
141 
142  /** Default implementation, but defined out-of-line for efficiency reasons. */
143  t_string(const t_string&);
144 
145  t_string(t_string&&) noexcept = default;
146 
147  /** Default implementation, but defined out-of-line for efficiency reasons. */
148  t_string& operator=(const t_string&);
149 
150  t_string& operator=(t_string&&) noexcept = default;
151 
152  t_string(const base &);
153  t_string(const char *);
154  t_string(const std::string &);
155  t_string(std::string&&);
156  t_string(const std::string &str, const std::string &textdomain);
157  t_string(const std::string& sing, const std::string& pl, int count, const std::string& textdomain);
158 
159  t_string& operator=(const char *o);
160 
161  static t_string from_serialized(const std::string& string) { return t_string(base::from_serialized(string)); }
162  std::string to_serialized() const { return get().to_serialized(); }
163 
164  operator const t_string_base &() const { return get(); }
165 
166  t_string operator+(const t_string& o) const { return get() + o.get(); }
167  t_string operator+(const std::string& o) const { return get() + o; }
168  t_string operator+(const char* o) const { return get() + o; }
169 
170 private:
171  template<typename T>
172  void increase_impl(const T& other)
173  {
174  base * nw = new base(get());
175  *nw += other;
176  val_.reset(nw);
177  }
178 
179 public:
180  t_string& operator+=(const t_string& o) { increase_impl(o.get()); return *this; }
181  t_string& operator+=(const std::string& o) { increase_impl(o); return *this; }
182  t_string& operator+=(const char* o) { increase_impl(o); return *this; }
183 
184  bool operator==(const t_string& o) const { return get() == o.get(); }
185  bool operator==(const std::string& o) const { return get() == o; }
186  bool operator==(const char* o) const { return get() == o; }
187 
188  bool operator!=(const t_string& o) const { return !operator==(o); }
189  bool operator!=(const std::string& o) const { return !operator==(o); }
190  bool operator!=(const char* o) const { return !operator==(o); }
191 
192  bool operator<(const t_string& o) const { return get() < o.get(); }
193 
194  bool empty() const { return get().empty(); }
195  std::string::size_type size() const { return get().size(); }
196 
197  operator const std::string&() const { return get(); }
198  const std::string& str() const { return get().str(); }
199  const char* c_str() const { return get().c_str(); }
200  bool translatable() const { return get().translatable(); }
201  const std::string& value() const { return get().value(); }
202  std::string base_str() const { return get().base_str(); }
203 
204  static void add_textdomain(const std::string &name, const std::string &path);
205  static void reset_translations();
206 
207  const t_string_base& get() const { return *val_; }
208  void swap(t_string& other) { val_.swap(other.val_); }
209 
210 private:
211  //never null
212  std::shared_ptr<const t_string_base> val_;
213 };
214 
215 /** Implement non-member swap function for std::swap (calls @ref t_string::swap). */
216 void swap(t_string& lhs, t_string& rhs);
217 
218 inline std::ostream& operator<<(std::ostream& os, const t_string& str) { return os << str.get(); }
219 inline bool operator==(const std::string &a, const t_string& b) { return b == a; }
220 inline bool operator==(const char *a, const t_string& b) { return b == a; }
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 t_string operator+(const std::string &a, const t_string& b) { return t_string(a) + b; }
224 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:122
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:124
bool operator!=(const std::string &that) const
Definition: tstring.hpp:96
std::string translated_value_
Definition: tstring.hpp:120
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:109
std::string value_
Definition: tstring.hpp:119
std::string base_str() const
Definition: tstring.cpp:365
const std::string & value() const
Definition: tstring.hpp:113
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:123
~t_string_base()
Default implementation, but defined out-of-line for efficiency reasons.
Definition: tstring.cpp:229
unsigned translation_timestamp_
Definition: tstring.hpp:121
bool translatable_
Definition: tstring.hpp:122
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:108
static void reset_translations()
Definition: tstring.cpp:665
static t_string from_serialized(const std::string &string)
Definition: tstring.hpp:161
static void add_textdomain(const std::string &name, const std::string &path)
Definition: tstring.cpp:657
t_string_base::walker walker
Definition: tstring.hpp:134
void swap(t_string &other)
Definition: tstring.hpp:208
const std::string & value() const
Definition: tstring.hpp:201
bool operator==(const t_string &o) const
Definition: tstring.hpp:184
bool translatable() const
Definition: tstring.hpp:200
t_string operator+(const t_string &o) const
Definition: tstring.hpp:166
~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:180
std::shared_ptr< const t_string_base > val_
Definition: tstring.hpp:212
t_string & operator+=(const std::string &o)
Definition: tstring.hpp:181
bool operator==(const std::string &o) const
Definition: tstring.hpp:185
t_string operator+(const char *o) const
Definition: tstring.hpp:168
bool empty() const
Definition: tstring.hpp:194
t_string(t_string &&) noexcept=default
t_string operator+(const std::string &o) const
Definition: tstring.hpp:167
bool operator==(const char *o) const
Definition: tstring.hpp:186
bool operator!=(const std::string &o) const
Definition: tstring.hpp:189
const std::string & str() const
Definition: tstring.hpp:198
t_string_base base
Definition: tstring.hpp:133
std::string base_str() const
Definition: tstring.hpp:202
std::string to_serialized() const
Definition: tstring.hpp:162
void increase_impl(const T &other)
Definition: tstring.hpp:172
t_string & operator+=(const char *o)
Definition: tstring.hpp:182
const t_string_base & get() const
Definition: tstring.hpp:207
t_string()
Default implementation, but defined out-of-line for efficiency reasons.
Definition: tstring.cpp:600
const char * c_str() const
Definition: tstring.hpp:199
bool operator!=(const char *o) const
Definition: tstring.hpp:190
std::string::size_type size() const
Definition: tstring.hpp:195
bool operator<(const t_string &o) const
Definition: tstring.hpp:192
bool operator!=(const t_string &o) const
Definition: tstring.hpp:188
std::string path
Definition: filesystem.cpp:90
static map_location::direction nw
bool operator==(const std::string &a, const t_string &b)
Definition: tstring.hpp:219
bool operator!=(const std::string &a, const t_string &b)
Definition: tstring.hpp:221
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:223
std::size_t hash_value(const t_string_base &str)
Definition: tstring.hpp:127
std::ostream & operator<<(std::ostream &, const t_string_base &)
Definition: tstring.cpp:675
#define b