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