forked from OpenXcom/OpenXcom
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLocalizedText.h
More file actions
154 lines (142 loc) · 4.46 KB
/
Copy pathLocalizedText.h
File metadata and controls
154 lines (142 loc) · 4.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#pragma once
/*
* Copyright 2010-2016 OpenXcom Developers.
*
* This file is part of OpenXcom.
*
* OpenXcom is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenXcom is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenXcom. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string>
#include <sstream>
/// @file
/** @def OX_REQUIRED_RESULT
* This is used to enable warning of unused results, to warn the user of costly function calls.
*/
#ifndef OX_REQUIRED_RESULT
# if defined(__GNUC_) && !defined(__INTEL_COMPILER) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
# define OX_REQUIRED_RESULT __attribute__ ((warn_unused_result))
# else
# define OX_REQUIRED_RESULT
# endif
#endif
namespace OpenXcom
{
/**
* A string that is already translated.
* Using this class allows argument substitution in the translated strings.
*/
class LocalizedText
{
public:
/// Create from existing string.
LocalizedText(const std::string &);
/// Create the empty string.
LocalizedText() : _nextArg(1) { /* Empty by design. */ }
/// Return constant string.
operator std::string const&() const OX_REQUIRED_RESULT;
/// Get a pointer to underlying char data.
const char *c_str() const OX_REQUIRED_RESULT { return _text.c_str(); }
// Argument substitution.
/// Replace next argument.
LocalizedText arg(const std::string &) const OX_REQUIRED_RESULT;
LocalizedText &arg(const std::string &) OX_REQUIRED_RESULT;
template <typename T> LocalizedText arg(T) const OX_REQUIRED_RESULT;
template <typename T> LocalizedText &arg(T) OX_REQUIRED_RESULT;
private:
std::string _text; ///< The actual localized text.
unsigned _nextArg; ///< The next argument ID.
LocalizedText(const std::string &, unsigned);
};
/**
* Create a LocalizedText from a localized std::string.
*/
inline LocalizedText::LocalizedText(const std::string &text)
: _text(text), _nextArg(0)
{
// Empty by design.
}
/**
* Create a LocalizedText with some arguments already replaced.
*/
inline LocalizedText::LocalizedText(const std::string &text, unsigned replaced)
: _text(text), _nextArg(replaced + 1)
{
// Empty by design.
}
/**
* Typecast to constant std::string reference.
* This is used to avoid copying when the string will not change.
*/
inline LocalizedText::operator std::string const&() const
{
return _text;
}
/**
* Replace the next argument placeholder with @a val.
* @tparam T The type of the replacement value. It should be streamable to std::owstringstream.
* @param val The value to place in the next placeholder's position.
* @return A translated string with all occurrences of the marker replaced by @a val.
*/
template <typename T>
LocalizedText LocalizedText::arg(T val) const
{
std::ostringstream os;
os << '{' << _nextArg << '}';
std::string marker(os.str());
size_t pos = _text.find(marker);
if (std::string::npos == pos)
return *this;
std::string ntext(_text);
os.str("");
os << val;
std::string tval(os.str());
for (/*empty*/ ; std::string::npos != pos; pos = ntext.find(marker, pos + tval.length()))
{
ntext.replace(pos, marker.length(), tval);
}
return LocalizedText(ntext, _nextArg);
}
/**
* Replace the next argument placeholder with @a val.
* @tparam T The type of the replacement value. It should be streamable to std::owstringstream.
* @param val The value to place in the next placeholder's position.
* @return The translated string with all occurrences of the marker replaced by @a val.
*/
template <typename T>
LocalizedText &LocalizedText::arg(T val)
{
std::ostringstream os;
os << '{' << _nextArg << '}';
std::string marker(os.str());
size_t pos = _text.find(marker);
if (std::string::npos != pos)
{
os.str("");
os << val;
std::string tval(os.str());
for (/*empty*/ ; std::string::npos != pos; pos = _text.find(marker, pos + tval.length()))
{
_text.replace(pos, marker.length(), tval);
}
++_nextArg;
}
return *this;
}
/// Allow streaming of LocalizedText objects.
inline std::ostream &operator<<(std::ostream &os, const LocalizedText &txt)
{
os << static_cast<std::string const &>(txt);
return os;
}
}