The Battle for Wesnoth  1.19.0-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(const std::string& string);
67  t_string_base(const std::string& string, const std::string& textdomain);
68  t_string_base(const std::string& sing, const std::string& pl, int count, const std::string& textdomain);
69  t_string_base(const char* string);
70 
71  static t_string_base from_serialized(const std::string& string);
72  std::string to_serialized() const;
73 
74  /** Default implementation, but defined out-of-line for efficiency reasons. */
76  t_string_base& operator=(const std::string&);
77  t_string_base& operator=(const char*);
78 
80  t_string_base operator+(const std::string&) const;
81  t_string_base operator+(const char*) const;
82 
84  t_string_base& operator+=(const std::string&);
85  t_string_base& operator+=(const char*);
86 
87  bool operator==(const t_string_base &) const;
88  bool operator==(const std::string &) const;
89  bool operator==(const char* string) const;
90 
91  bool operator!=(const t_string_base &that) const
92  { return !operator==(that); }
93  bool operator!=(const std::string &that) const
94  { return !operator==(that); }
95  bool operator!=(const char *that) const
96  { return !operator==(that); }
97 
98  bool operator<(const t_string_base& string) const;
99 
100  bool empty() const { return value_.empty(); }
101  std::string::size_type size() const { return str().size(); }
102 
103  operator const std::string&() const { return str(); }
104  const std::string& str() const;
105  const char* c_str() const { return str().c_str(); }
106  bool translatable() const { return translatable_; }
107 
108  // Warning: value() may contain platform dependent prefix bytes !
109  // Consider base_str() for a more reliable untranslated string
110  const std::string& value() const { return value_; }
111  std::string base_str() const;
112 
113  std::size_t hash_value() const;
114 
115 private:
116  std::string value_;
117  mutable std::string translated_value_;
118  mutable unsigned translation_timestamp_;
120  static inline std::vector<std::string> id_to_textdomain;
121  static inline std::map<std::string, unsigned int> textdomain_to_id;
122 };
123 
124 inline std::size_t hash_value(const t_string_base& str) { return str.hash_value(); }
125 std::ostream& operator<<(std::ostream&, const t_string_base&);
126 
127 class t_string
128 {
129 public:
132 
133  /** Default implementation, but defined out-of-line for efficiency reasons. */
134  t_string();
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(const t_string&);
141 
142  /** Default implementation, but defined out-of-line for efficiency reasons. */
143  t_string& operator=(const t_string&);
144 
145  t_string(const base &);
146  t_string(const char *);
147  t_string(const std::string &);
148  t_string(const std::string &str, const std::string &textdomain);
149  t_string(const std::string& sing, const std::string& pl, int count, const std::string& textdomain);
150 
151  t_string& operator=(const char *o);
152 
153  static t_string from_serialized(const std::string& string) { return t_string(base::from_serialized(string)); }
154  std::string to_serialized() const { return get().to_serialized(); }
155 
156  operator const t_string_base &() const { return get(); }
157 
158  t_string operator+(const t_string& o) const { return get() + o.get(); }
159  t_string operator+(const std::string& o) const { return get() + o; }
160  t_string operator+(const char* o) const { return get() + o; }
161 
162 private:
163  template<typename T>
164  void increase_impl(const T& other)
165  {
166  base * nw = new base(get());
167  *nw += other;
168  val_.reset(nw);
169  }
170 
171 public:
172  t_string& operator+=(const t_string& o) { increase_impl(o.get()); return *this; }
173  t_string& operator+=(const std::string& o) { increase_impl(o); return *this; }
174  t_string& operator+=(const char* o) { increase_impl(o); return *this; }
175 
176  bool operator==(const t_string& o) const { return get() == o.get(); }
177  bool operator==(const std::string& o) const { return get() == o; }
178  bool operator==(const char* o) const { return get() == o; }
179 
180  bool operator!=(const t_string& o) const { return !operator==(o); }
181  bool operator!=(const std::string& o) const { return !operator==(o); }
182  bool operator!=(const char* o) const { return !operator==(o); }
183 
184  bool operator<(const t_string& o) const { return get() < o.get(); }
185 
186  bool empty() const { return get().empty(); }
187  std::string::size_type size() const { return get().size(); }
188 
189  operator const std::string&() const { return get(); }
190  const std::string& str() const { return get().str(); }
191  const char* c_str() const { return get().c_str(); }
192  bool translatable() const { return get().translatable(); }
193  const std::string& value() const { return get().value(); }
194  std::string base_str() const { return get().base_str(); }
195 
196  static void add_textdomain(const std::string &name, const std::string &path);
197  static void reset_translations();
198 
199  const t_string_base& get() const { return *val_; }
200  void swap(t_string& other) { val_.swap(other.val_); }
201 
202 private:
203  //never null
204  std::shared_ptr<const t_string_base> val_;
205 };
206 
207 /** Implement non-member swap function for std::swap (calls @ref t_string::swap). */
208 void swap(t_string& lhs, t_string& rhs);
209 
210 inline std::ostream& operator<<(std::ostream& os, const t_string& str) { return os << str.get(); }
211 inline bool operator==(const std::string &a, const t_string& b) { return b == a; }
212 inline bool operator==(const char *a, const t_string& b) { return b == a; }
213 inline bool operator!=(const std::string &a, const t_string& b) { return b != a; }
214 inline bool operator!=(const char *a, const t_string& b) { return b != a; }
215 inline t_string operator+(const std::string &a, const t_string& b) { return t_string(a) + b; }
216 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:95
t_string_base & operator=(const t_string_base &)
Default implementation, but defined out-of-line for efficiency reasons.
Definition: tstring.cpp:389
bool last_untranslatable_
Definition: tstring.hpp:119
std::string::size_type size() const
Definition: tstring.hpp:101
static std::map< std::string, unsigned int > textdomain_to_id
Definition: tstring.hpp:121
bool operator!=(const std::string &that) const
Definition: tstring.hpp:93
std::string translated_value_
Definition: tstring.hpp:117
t_string_base & operator+=(const t_string_base &)
Definition: tstring.cpp:443
std::string to_serialized() const
Definition: tstring.cpp:366
bool operator!=(const t_string_base &that) const
Definition: tstring.hpp:91
bool operator==(const t_string_base &) const
Definition: tstring.cpp:538
bool translatable() const
Definition: tstring.hpp:106
std::string value_
Definition: tstring.hpp:116
std::string base_str() const
Definition: tstring.cpp:356
const std::string & value() const
Definition: tstring.hpp:110
bool empty() const
Definition: tstring.hpp:100
bool operator<(const t_string_base &string) const
Definition: tstring.cpp:553
static std::vector< std::string > id_to_textdomain
Definition: tstring.hpp:120
~t_string_base()
Default implementation, but defined out-of-line for efficiency reasons.
Definition: tstring.cpp:229
unsigned translation_timestamp_
Definition: tstring.hpp:118
bool translatable_
Definition: tstring.hpp:119
std::size_t hash_value() const
Definition: tstring.cpp:47
const std::string & str() const
Definition: tstring.cpp:558
static t_string_base from_serialized(const std::string &string)
Definition: tstring.cpp:331
const char * c_str() const
Definition: tstring.hpp:105
t_string_base operator+(const t_string_base &) const
Definition: tstring.cpp:422
static void reset_translations()
Definition: tstring.cpp:651
static t_string from_serialized(const std::string &string)
Definition: tstring.hpp:153
static void add_textdomain(const std::string &name, const std::string &path)
Definition: tstring.cpp:643
t_string_base::walker walker
Definition: tstring.hpp:131
void swap(t_string &other)
Definition: tstring.hpp:200
const std::string & value() const
Definition: tstring.hpp:193
bool operator==(const t_string &o) const
Definition: tstring.hpp:176
bool translatable() const
Definition: tstring.hpp:192
t_string operator+(const t_string &o) const
Definition: tstring.hpp:158
~t_string()
Default implementation, but defined out-of-line for efficiency reasons.
Definition: tstring.cpp:596
t_string & operator+=(const t_string &o)
Definition: tstring.hpp:172
std::shared_ptr< const t_string_base > val_
Definition: tstring.hpp:204
t_string & operator+=(const std::string &o)
Definition: tstring.hpp:173
bool operator==(const std::string &o) const
Definition: tstring.hpp:177
t_string operator+(const char *o) const
Definition: tstring.hpp:160
bool empty() const
Definition: tstring.hpp:186
t_string operator+(const std::string &o) const
Definition: tstring.hpp:159
bool operator==(const char *o) const
Definition: tstring.hpp:178
bool operator!=(const std::string &o) const
Definition: tstring.hpp:181
const std::string & str() const
Definition: tstring.hpp:190
t_string_base base
Definition: tstring.hpp:130
std::string base_str() const
Definition: tstring.hpp:194
t_string & operator=(const t_string &)
Default implementation, but defined out-of-line for efficiency reasons.
Definition: tstring.cpp:630
std::string to_serialized() const
Definition: tstring.hpp:154
void increase_impl(const T &other)
Definition: tstring.hpp:164
t_string & operator+=(const char *o)
Definition: tstring.hpp:174
const t_string_base & get() const
Definition: tstring.hpp:199
t_string()
Default implementation, but defined out-of-line for efficiency reasons.
Definition: tstring.cpp:591
const char * c_str() const
Definition: tstring.hpp:191
bool operator!=(const char *o) const
Definition: tstring.hpp:182
std::string::size_type size() const
Definition: tstring.hpp:187
bool operator<(const t_string &o) const
Definition: tstring.hpp:184
bool operator!=(const t_string &o) const
Definition: tstring.hpp:180
std::string path
Definition: filesystem.cpp:83
static map_location::DIRECTION nw
bool operator==(const std::string &a, const t_string &b)
Definition: tstring.hpp:211
bool operator!=(const std::string &a, const t_string &b)
Definition: tstring.hpp:213
void swap(t_string &lhs, t_string &rhs)
Implement non-member swap function for std::swap (calls t_string::swap).
Definition: tstring.cpp:656
t_string operator+(const std::string &a, const t_string &b)
Definition: tstring.hpp:215
std::size_t hash_value(const t_string_base &str)
Definition: tstring.hpp:124
std::ostream & operator<<(std::ostream &, const t_string_base &)
Definition: tstring.cpp:661
#define a
#define b