Chris@16
|
1 //
|
Chris@16
|
2 // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
|
Chris@16
|
3 //
|
Chris@16
|
4 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
5 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
6 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7 //
|
Chris@16
|
8 #ifndef BOOST_LOCALE_MESSAGE_HPP_INCLUDED
|
Chris@16
|
9 #define BOOST_LOCALE_MESSAGE_HPP_INCLUDED
|
Chris@16
|
10
|
Chris@16
|
11 #include <boost/locale/config.hpp>
|
Chris@16
|
12 #ifdef BOOST_MSVC
|
Chris@16
|
13 # pragma warning(push)
|
Chris@16
|
14 # pragma warning(disable : 4275 4251 4231 4660)
|
Chris@16
|
15 #endif
|
Chris@16
|
16 #include <locale>
|
Chris@16
|
17 #include <string>
|
Chris@16
|
18 #include <vector>
|
Chris@16
|
19 #include <set>
|
Chris@16
|
20 #include <memory>
|
Chris@16
|
21 #include <boost/locale/formatting.hpp>
|
Chris@16
|
22
|
Chris@16
|
23
|
Chris@16
|
24 namespace boost {
|
Chris@16
|
25 namespace locale {
|
Chris@16
|
26 ///
|
Chris@16
|
27 /// \defgroup message Message Formatting (translation)
|
Chris@16
|
28 ///
|
Chris@16
|
29 ///This module provides message translation functionality, i.e. allow your application to speak native language
|
Chris@16
|
30 ///
|
Chris@16
|
31 /// @{
|
Chris@16
|
32 ///
|
Chris@16
|
33
|
Chris@16
|
34 /// \cond INTERNAL
|
Chris@16
|
35
|
Chris@16
|
36 template<typename CharType>
|
Chris@16
|
37 struct base_message_format: public std::locale::facet
|
Chris@16
|
38 {
|
Chris@16
|
39 };
|
Chris@16
|
40
|
Chris@16
|
41 /// \endcond
|
Chris@16
|
42
|
Chris@16
|
43 ///
|
Chris@16
|
44 /// \brief This facet provides message formatting abilities
|
Chris@16
|
45 ///
|
Chris@16
|
46 template<typename CharType>
|
Chris@16
|
47 class message_format : public base_message_format<CharType>
|
Chris@16
|
48 {
|
Chris@16
|
49 public:
|
Chris@16
|
50
|
Chris@16
|
51 ///
|
Chris@16
|
52 /// Character type
|
Chris@16
|
53 ///
|
Chris@16
|
54 typedef CharType char_type;
|
Chris@16
|
55 ///
|
Chris@16
|
56 /// String type
|
Chris@16
|
57 ///
|
Chris@16
|
58 typedef std::basic_string<CharType> string_type;
|
Chris@16
|
59
|
Chris@16
|
60 ///
|
Chris@16
|
61 /// Default constructor
|
Chris@16
|
62 ///
|
Chris@16
|
63 message_format(size_t refs = 0) :
|
Chris@16
|
64 base_message_format<CharType>(refs)
|
Chris@16
|
65 {
|
Chris@16
|
66 }
|
Chris@16
|
67
|
Chris@16
|
68 ///
|
Chris@16
|
69 /// This function returns a pointer to the string for a message defined by a \a context
|
Chris@16
|
70 /// and identification string \a id. Both create a single key for message lookup in
|
Chris@16
|
71 /// a domain defined by \a domain_id.
|
Chris@16
|
72 ///
|
Chris@16
|
73 /// If \a context is NULL it is not considered to be a part of the key
|
Chris@16
|
74 ///
|
Chris@16
|
75 /// If a translated string is found, it is returned, otherwise NULL is returned
|
Chris@16
|
76 ///
|
Chris@16
|
77 ///
|
Chris@16
|
78 virtual char_type const *get(int domain_id,char_type const *context,char_type const *id) const = 0;
|
Chris@16
|
79 ///
|
Chris@16
|
80 /// This function returns a pointer to the string for a plural message defined by a \a context
|
Chris@16
|
81 /// and identification string \a single_id.
|
Chris@16
|
82 ///
|
Chris@16
|
83 /// If \a context is NULL it is not considered to be a part of the key
|
Chris@16
|
84 ///
|
Chris@16
|
85 /// Both create a single key for message lookup in
|
Chris@16
|
86 /// a domain defined \a domain_id. \a n is used to pick the correct translation string for a specific
|
Chris@16
|
87 /// number.
|
Chris@16
|
88 ///
|
Chris@16
|
89 /// If a translated string is found, it is returned, otherwise NULL is returned
|
Chris@16
|
90 ///
|
Chris@16
|
91 ///
|
Chris@16
|
92 virtual char_type const *get(int domain_id,char_type const *context,char_type const *single_id,int n) const = 0;
|
Chris@16
|
93
|
Chris@16
|
94 ///
|
Chris@16
|
95 /// Convert a string that defines \a domain to the integer id used by \a get functions
|
Chris@16
|
96 ///
|
Chris@16
|
97 virtual int domain(std::string const &domain) const = 0;
|
Chris@16
|
98
|
Chris@16
|
99 ///
|
Chris@16
|
100 /// Convert the string \a msg to target locale's encoding. If \a msg is already
|
Chris@16
|
101 /// in target encoding it would be returned otherwise the converted
|
Chris@16
|
102 /// string is stored in temporary \a buffer and buffer.c_str() is returned.
|
Chris@16
|
103 ///
|
Chris@16
|
104 /// Note: for char_type that is char16_t, char32_t and wchar_t it is no-op, returns
|
Chris@16
|
105 /// msg
|
Chris@16
|
106 ///
|
Chris@16
|
107 virtual char_type const *convert(char_type const *msg,string_type &buffer) const = 0;
|
Chris@16
|
108
|
Chris@16
|
109 #if defined (__SUNPRO_CC) && defined (_RWSTD_VER)
|
Chris@16
|
110 std::locale::id& __get_id (void) const { return id; }
|
Chris@16
|
111 #endif
|
Chris@16
|
112 protected:
|
Chris@16
|
113 virtual ~message_format()
|
Chris@16
|
114 {
|
Chris@16
|
115 }
|
Chris@16
|
116
|
Chris@16
|
117 };
|
Chris@16
|
118
|
Chris@16
|
119 /// \cond INTERNAL
|
Chris@16
|
120
|
Chris@16
|
121 namespace details {
|
Chris@16
|
122 inline bool is_us_ascii_char(char c)
|
Chris@16
|
123 {
|
Chris@16
|
124 // works for null terminated strings regardless char "signness"
|
Chris@16
|
125 return 0<c && c<0x7F;
|
Chris@16
|
126 }
|
Chris@16
|
127 inline bool is_us_ascii_string(char const *msg)
|
Chris@16
|
128 {
|
Chris@16
|
129 while(*msg) {
|
Chris@16
|
130 if(!is_us_ascii_char(*msg++))
|
Chris@16
|
131 return false;
|
Chris@16
|
132 }
|
Chris@16
|
133 return true;
|
Chris@16
|
134 }
|
Chris@16
|
135
|
Chris@16
|
136 template<typename CharType>
|
Chris@16
|
137 struct string_cast_traits {
|
Chris@16
|
138 static CharType const *cast(CharType const *msg,std::basic_string<CharType> &/*unused*/)
|
Chris@16
|
139 {
|
Chris@16
|
140 return msg;
|
Chris@16
|
141 }
|
Chris@16
|
142 };
|
Chris@16
|
143
|
Chris@16
|
144 template<>
|
Chris@16
|
145 struct string_cast_traits<char> {
|
Chris@16
|
146 static char const *cast(char const *msg,std::string &buffer)
|
Chris@16
|
147 {
|
Chris@16
|
148 if(is_us_ascii_string(msg))
|
Chris@16
|
149 return msg;
|
Chris@16
|
150 buffer.reserve(strlen(msg));
|
Chris@16
|
151 char c;
|
Chris@16
|
152 while((c=*msg++)!=0) {
|
Chris@16
|
153 if(is_us_ascii_char(c))
|
Chris@16
|
154 buffer+=c;
|
Chris@16
|
155 }
|
Chris@16
|
156 return buffer.c_str();
|
Chris@16
|
157 }
|
Chris@16
|
158 };
|
Chris@16
|
159 } // details
|
Chris@16
|
160
|
Chris@16
|
161 /// \endcond
|
Chris@16
|
162
|
Chris@16
|
163 ///
|
Chris@16
|
164 /// \brief This class represents a message that can be converted to a specific locale message
|
Chris@16
|
165 ///
|
Chris@16
|
166 /// It holds the original ASCII string that is queried in the dictionary when converting to the output string.
|
Chris@16
|
167 /// The created string may be UTF-8, UTF-16, UTF-32 or other 8-bit encoded string according to the target
|
Chris@16
|
168 /// character type and locale encoding.
|
Chris@16
|
169 ///
|
Chris@16
|
170 template<typename CharType>
|
Chris@16
|
171 class basic_message {
|
Chris@16
|
172 public:
|
Chris@16
|
173
|
Chris@16
|
174 typedef CharType char_type; ///< The character this message object is used with
|
Chris@16
|
175 typedef std::basic_string<char_type> string_type; ///< The string type this object can be used with
|
Chris@16
|
176 typedef message_format<char_type> facet_type; ///< The type of the facet the messages are fetched with
|
Chris@16
|
177
|
Chris@16
|
178 ///
|
Chris@16
|
179 /// Create default empty message
|
Chris@16
|
180 ///
|
Chris@16
|
181 basic_message() :
|
Chris@16
|
182 n_(0),
|
Chris@16
|
183 c_id_(0),
|
Chris@16
|
184 c_context_(0),
|
Chris@16
|
185 c_plural_(0)
|
Chris@16
|
186 {
|
Chris@16
|
187 }
|
Chris@16
|
188
|
Chris@16
|
189 ///
|
Chris@16
|
190 /// Create a simple message from 0 terminated string. The string should exist
|
Chris@16
|
191 /// until the message is destroyed. Generally useful with static constant strings
|
Chris@16
|
192 ///
|
Chris@16
|
193 explicit basic_message(char_type const *id) :
|
Chris@16
|
194 n_(0),
|
Chris@16
|
195 c_id_(id),
|
Chris@16
|
196 c_context_(0),
|
Chris@16
|
197 c_plural_(0)
|
Chris@16
|
198 {
|
Chris@16
|
199 }
|
Chris@16
|
200
|
Chris@16
|
201 ///
|
Chris@16
|
202 /// Create a simple plural form message from 0 terminated strings. The strings should exist
|
Chris@16
|
203 /// until the message is destroyed. Generally useful with static constant strings.
|
Chris@16
|
204 ///
|
Chris@16
|
205 /// \a n is the number, \a single and \a plural are singular and plural forms of the message
|
Chris@16
|
206 ///
|
Chris@16
|
207 explicit basic_message(char_type const *single,char_type const *plural,int n) :
|
Chris@16
|
208 n_(n),
|
Chris@16
|
209 c_id_(single),
|
Chris@16
|
210 c_context_(0),
|
Chris@16
|
211 c_plural_(plural)
|
Chris@16
|
212 {
|
Chris@16
|
213 }
|
Chris@16
|
214
|
Chris@16
|
215 ///
|
Chris@16
|
216 /// Create a simple message from 0 terminated strings, with context
|
Chris@16
|
217 /// information. The string should exist
|
Chris@16
|
218 /// until the message is destroyed. Generally useful with static constant strings
|
Chris@16
|
219 ///
|
Chris@16
|
220 explicit basic_message(char_type const *context,char_type const *id) :
|
Chris@16
|
221 n_(0),
|
Chris@16
|
222 c_id_(id),
|
Chris@16
|
223 c_context_(context),
|
Chris@16
|
224 c_plural_(0)
|
Chris@16
|
225 {
|
Chris@16
|
226 }
|
Chris@16
|
227
|
Chris@16
|
228 ///
|
Chris@16
|
229 /// Create a simple plural form message from 0 terminated strings, with context. The strings should exist
|
Chris@16
|
230 /// until the message is destroyed. Generally useful with static constant strings.
|
Chris@16
|
231 ///
|
Chris@16
|
232 /// \a n is the number, \a single and \a plural are singular and plural forms of the message
|
Chris@16
|
233 ///
|
Chris@16
|
234 explicit basic_message(char_type const *context,char_type const *single,char_type const *plural,int n) :
|
Chris@16
|
235 n_(n),
|
Chris@16
|
236 c_id_(single),
|
Chris@16
|
237 c_context_(context),
|
Chris@16
|
238 c_plural_(plural)
|
Chris@16
|
239 {
|
Chris@16
|
240 }
|
Chris@16
|
241
|
Chris@16
|
242
|
Chris@16
|
243 ///
|
Chris@16
|
244 /// Create a simple message from a string.
|
Chris@16
|
245 ///
|
Chris@16
|
246 explicit basic_message(string_type const &id) :
|
Chris@16
|
247 n_(0),
|
Chris@16
|
248 c_id_(0),
|
Chris@16
|
249 c_context_(0),
|
Chris@16
|
250 c_plural_(0),
|
Chris@16
|
251 id_(id)
|
Chris@16
|
252 {
|
Chris@16
|
253 }
|
Chris@16
|
254
|
Chris@16
|
255 ///
|
Chris@16
|
256 /// Create a simple plural form message from strings.
|
Chris@16
|
257 ///
|
Chris@16
|
258 /// \a n is the number, \a single and \a plural are single and plural forms of the message
|
Chris@16
|
259 ///
|
Chris@16
|
260 explicit basic_message(string_type const &single,string_type const &plural,int number) :
|
Chris@16
|
261 n_(number),
|
Chris@16
|
262 c_id_(0),
|
Chris@16
|
263 c_context_(0),
|
Chris@16
|
264 c_plural_(0),
|
Chris@16
|
265 id_(single),
|
Chris@16
|
266 plural_(plural)
|
Chris@16
|
267 {
|
Chris@16
|
268 }
|
Chris@16
|
269
|
Chris@16
|
270 ///
|
Chris@16
|
271 /// Create a simple message from a string with context.
|
Chris@16
|
272 ///
|
Chris@16
|
273 explicit basic_message(string_type const &context,string_type const &id) :
|
Chris@16
|
274 n_(0),
|
Chris@16
|
275 c_id_(0),
|
Chris@16
|
276 c_context_(0),
|
Chris@16
|
277 c_plural_(0),
|
Chris@16
|
278 id_(id),
|
Chris@16
|
279 context_(context)
|
Chris@16
|
280 {
|
Chris@16
|
281 }
|
Chris@16
|
282
|
Chris@16
|
283 ///
|
Chris@16
|
284 /// Create a simple plural form message from strings.
|
Chris@16
|
285 ///
|
Chris@16
|
286 /// \a n is the number, \a single and \a plural are single and plural forms of the message
|
Chris@16
|
287 ///
|
Chris@16
|
288 explicit basic_message(string_type const &context,string_type const &single,string_type const &plural,int number) :
|
Chris@16
|
289 n_(number),
|
Chris@16
|
290 c_id_(0),
|
Chris@16
|
291 c_context_(0),
|
Chris@16
|
292 c_plural_(0),
|
Chris@16
|
293 id_(single),
|
Chris@16
|
294 context_(context),
|
Chris@16
|
295 plural_(plural)
|
Chris@16
|
296 {
|
Chris@16
|
297 }
|
Chris@16
|
298
|
Chris@16
|
299 ///
|
Chris@16
|
300 /// Copy an object
|
Chris@16
|
301 ///
|
Chris@16
|
302 basic_message(basic_message const &other) :
|
Chris@16
|
303 n_(other.n_),
|
Chris@16
|
304 c_id_(other.c_id_),
|
Chris@16
|
305 c_context_(other.c_context_),
|
Chris@16
|
306 c_plural_(other.c_plural_),
|
Chris@16
|
307 id_(other.id_),
|
Chris@16
|
308 context_(other.context_),
|
Chris@16
|
309 plural_(other.plural_)
|
Chris@16
|
310 {
|
Chris@16
|
311 }
|
Chris@16
|
312
|
Chris@16
|
313 ///
|
Chris@16
|
314 /// Assign other message object to this one
|
Chris@16
|
315 ///
|
Chris@16
|
316 basic_message const &operator=(basic_message const &other)
|
Chris@16
|
317 {
|
Chris@16
|
318 if(this==&other) {
|
Chris@16
|
319 return *this;
|
Chris@16
|
320 }
|
Chris@16
|
321 basic_message tmp(other);
|
Chris@16
|
322 swap(tmp);
|
Chris@16
|
323 return *this;
|
Chris@16
|
324 }
|
Chris@16
|
325
|
Chris@16
|
326 ///
|
Chris@16
|
327 /// Swap two message objects
|
Chris@16
|
328 ///
|
Chris@16
|
329 void swap(basic_message &other)
|
Chris@16
|
330 {
|
Chris@16
|
331 std::swap(n_,other.n_);
|
Chris@16
|
332 std::swap(c_id_,other.c_id_);
|
Chris@16
|
333 std::swap(c_context_,other.c_context_);
|
Chris@16
|
334 std::swap(c_plural_,other.c_plural_);
|
Chris@16
|
335
|
Chris@16
|
336 id_.swap(other.id_);
|
Chris@16
|
337 context_.swap(other.context_);
|
Chris@16
|
338 plural_.swap(other.plural_);
|
Chris@16
|
339 }
|
Chris@16
|
340
|
Chris@16
|
341 ///
|
Chris@16
|
342 /// Message class can be explicitly converted to string class
|
Chris@16
|
343 ///
|
Chris@16
|
344
|
Chris@16
|
345 operator string_type () const
|
Chris@16
|
346 {
|
Chris@16
|
347 return str();
|
Chris@16
|
348 }
|
Chris@16
|
349
|
Chris@16
|
350 ///
|
Chris@16
|
351 /// Translate message to a string in the default global locale, using default domain
|
Chris@16
|
352 ///
|
Chris@16
|
353 string_type str() const
|
Chris@16
|
354 {
|
Chris@16
|
355 std::locale loc;
|
Chris@16
|
356 return str(loc,0);
|
Chris@16
|
357 }
|
Chris@16
|
358
|
Chris@16
|
359 ///
|
Chris@16
|
360 /// Translate message to a string in the locale \a locale, using default domain
|
Chris@16
|
361 ///
|
Chris@16
|
362 string_type str(std::locale const &locale) const
|
Chris@16
|
363 {
|
Chris@16
|
364 return str(locale,0);
|
Chris@16
|
365 }
|
Chris@16
|
366
|
Chris@16
|
367 ///
|
Chris@16
|
368 /// Translate message to a string using locale \a locale and message domain \a domain_id
|
Chris@16
|
369 ///
|
Chris@16
|
370 string_type str(std::locale const &locale,std::string const &domain_id) const
|
Chris@16
|
371 {
|
Chris@16
|
372 int id=0;
|
Chris@16
|
373 if(std::has_facet<facet_type>(locale))
|
Chris@16
|
374 id=std::use_facet<facet_type>(locale).domain(domain_id);
|
Chris@16
|
375 return str(locale,id);
|
Chris@16
|
376 }
|
Chris@16
|
377
|
Chris@16
|
378 ///
|
Chris@16
|
379 /// Translate message to a string using the default locale and message domain \a domain_id
|
Chris@16
|
380 ///
|
Chris@16
|
381 string_type str(std::string const &domain_id) const
|
Chris@16
|
382 {
|
Chris@16
|
383 int id=0;
|
Chris@16
|
384 std::locale loc;
|
Chris@16
|
385 if(std::has_facet<facet_type>(loc))
|
Chris@16
|
386 id=std::use_facet<facet_type>(loc).domain(domain_id);
|
Chris@16
|
387 return str(loc,id);
|
Chris@16
|
388 }
|
Chris@16
|
389
|
Chris@16
|
390
|
Chris@16
|
391 ///
|
Chris@16
|
392 /// Translate message to a string using locale \a loc and message domain index \a id
|
Chris@16
|
393 ///
|
Chris@16
|
394 string_type str(std::locale const &loc,int id) const
|
Chris@16
|
395 {
|
Chris@16
|
396 string_type buffer;
|
Chris@16
|
397 char_type const *ptr = write(loc,id,buffer);
|
Chris@16
|
398 if(ptr == buffer.c_str())
|
Chris@16
|
399 return buffer;
|
Chris@16
|
400 else
|
Chris@16
|
401 buffer = ptr;
|
Chris@16
|
402 return buffer;
|
Chris@16
|
403 }
|
Chris@16
|
404
|
Chris@16
|
405
|
Chris@16
|
406 ///
|
Chris@16
|
407 /// Translate message and write to stream \a out, using imbued locale and domain set to the
|
Chris@16
|
408 /// stream
|
Chris@16
|
409 ///
|
Chris@16
|
410 void write(std::basic_ostream<char_type> &out) const
|
Chris@16
|
411 {
|
Chris@16
|
412 std::locale const &loc = out.getloc();
|
Chris@16
|
413 int id = ios_info::get(out).domain_id();
|
Chris@16
|
414 string_type buffer;
|
Chris@16
|
415 out << write(loc,id,buffer);
|
Chris@16
|
416 }
|
Chris@16
|
417
|
Chris@16
|
418 private:
|
Chris@16
|
419 char_type const *plural() const
|
Chris@16
|
420 {
|
Chris@16
|
421 if(c_plural_)
|
Chris@16
|
422 return c_plural_;
|
Chris@16
|
423 if(plural_.empty())
|
Chris@16
|
424 return 0;
|
Chris@16
|
425 return plural_.c_str();
|
Chris@16
|
426 }
|
Chris@16
|
427 char_type const *context() const
|
Chris@16
|
428 {
|
Chris@16
|
429 if(c_context_)
|
Chris@16
|
430 return c_context_;
|
Chris@16
|
431 if(context_.empty())
|
Chris@16
|
432 return 0;
|
Chris@16
|
433 return context_.c_str();
|
Chris@16
|
434 }
|
Chris@16
|
435
|
Chris@16
|
436 char_type const *id() const
|
Chris@16
|
437 {
|
Chris@16
|
438 return c_id_ ? c_id_ : id_.c_str();
|
Chris@16
|
439 }
|
Chris@16
|
440
|
Chris@16
|
441 char_type const *write(std::locale const &loc,int domain_id,string_type &buffer) const
|
Chris@16
|
442 {
|
Chris@16
|
443 char_type const *translated = 0;
|
Chris@16
|
444 static const char_type empty_string[1] = {0};
|
Chris@16
|
445
|
Chris@16
|
446 char_type const *id = this->id();
|
Chris@16
|
447 char_type const *context = this->context();
|
Chris@16
|
448 char_type const *plural = this->plural();
|
Chris@16
|
449
|
Chris@16
|
450 if(*id == 0)
|
Chris@16
|
451 return empty_string;
|
Chris@16
|
452
|
Chris@16
|
453 facet_type const *facet = 0;
|
Chris@16
|
454 if(std::has_facet<facet_type>(loc))
|
Chris@16
|
455 facet = &std::use_facet<facet_type>(loc);
|
Chris@16
|
456
|
Chris@16
|
457 if(facet) {
|
Chris@16
|
458 if(!plural) {
|
Chris@16
|
459 translated = facet->get(domain_id,context,id);
|
Chris@16
|
460 }
|
Chris@16
|
461 else {
|
Chris@16
|
462 translated = facet->get(domain_id,context,id,n_);
|
Chris@16
|
463 }
|
Chris@16
|
464 }
|
Chris@16
|
465
|
Chris@16
|
466 if(!translated) {
|
Chris@16
|
467 char_type const *msg = plural ? ( n_ == 1 ? id : plural) : id;
|
Chris@16
|
468
|
Chris@16
|
469 if(facet) {
|
Chris@16
|
470 translated = facet->convert(msg,buffer);
|
Chris@16
|
471 }
|
Chris@16
|
472 else {
|
Chris@16
|
473 translated = details::string_cast_traits<char_type>::cast(msg,buffer);
|
Chris@16
|
474 }
|
Chris@16
|
475 }
|
Chris@16
|
476 return translated;
|
Chris@16
|
477 }
|
Chris@16
|
478
|
Chris@16
|
479 /// members
|
Chris@16
|
480
|
Chris@16
|
481 int n_;
|
Chris@16
|
482 char_type const *c_id_;
|
Chris@16
|
483 char_type const *c_context_;
|
Chris@16
|
484 char_type const *c_plural_;
|
Chris@16
|
485 string_type id_;
|
Chris@16
|
486 string_type context_;
|
Chris@16
|
487 string_type plural_;
|
Chris@16
|
488 };
|
Chris@16
|
489
|
Chris@16
|
490
|
Chris@16
|
491 ///
|
Chris@16
|
492 /// Convenience typedef for char
|
Chris@16
|
493 ///
|
Chris@16
|
494 typedef basic_message<char> message;
|
Chris@16
|
495 ///
|
Chris@16
|
496 /// Convenience typedef for wchar_t
|
Chris@16
|
497 ///
|
Chris@16
|
498 typedef basic_message<wchar_t> wmessage;
|
Chris@16
|
499 #ifdef BOOST_HAS_CHAR16_T
|
Chris@16
|
500 ///
|
Chris@16
|
501 /// Convenience typedef for char16_t
|
Chris@16
|
502 ///
|
Chris@16
|
503 typedef basic_message<char16_t> u16message;
|
Chris@16
|
504 #endif
|
Chris@16
|
505 #ifdef BOOST_HAS_CHAR32_T
|
Chris@16
|
506 ///
|
Chris@16
|
507 /// Convenience typedef for char32_t
|
Chris@16
|
508 ///
|
Chris@16
|
509 typedef basic_message<char32_t> u32message;
|
Chris@16
|
510 #endif
|
Chris@16
|
511
|
Chris@16
|
512 ///
|
Chris@16
|
513 /// Translate message \a msg and write it to stream
|
Chris@16
|
514 ///
|
Chris@16
|
515 template<typename CharType>
|
Chris@16
|
516 std::basic_ostream<CharType> &operator<<(std::basic_ostream<CharType> &out,basic_message<CharType> const &msg)
|
Chris@16
|
517 {
|
Chris@16
|
518 msg.write(out);
|
Chris@16
|
519 return out;
|
Chris@16
|
520 }
|
Chris@16
|
521
|
Chris@16
|
522 ///
|
Chris@16
|
523 /// \anchor boost_locale_translate_family \name Indirect message translation function family
|
Chris@16
|
524 /// @{
|
Chris@16
|
525
|
Chris@16
|
526 ///
|
Chris@16
|
527 /// \brief Translate a message, \a msg is not copied
|
Chris@16
|
528 ///
|
Chris@16
|
529 template<typename CharType>
|
Chris@16
|
530 inline basic_message<CharType> translate(CharType const *msg)
|
Chris@16
|
531 {
|
Chris@16
|
532 return basic_message<CharType>(msg);
|
Chris@16
|
533 }
|
Chris@16
|
534 ///
|
Chris@16
|
535 /// \brief Translate a message in context, \a msg and \a context are not copied
|
Chris@16
|
536 ///
|
Chris@16
|
537 template<typename CharType>
|
Chris@16
|
538 inline basic_message<CharType> translate( CharType const *context,
|
Chris@16
|
539 CharType const *msg)
|
Chris@16
|
540 {
|
Chris@16
|
541 return basic_message<CharType>(context,msg);
|
Chris@16
|
542 }
|
Chris@16
|
543 ///
|
Chris@16
|
544 /// \brief Translate a plural message form, \a single and \a plural are not copied
|
Chris@16
|
545 ///
|
Chris@16
|
546 template<typename CharType>
|
Chris@16
|
547 inline basic_message<CharType> translate( CharType const *single,
|
Chris@16
|
548 CharType const *plural,
|
Chris@16
|
549 int n)
|
Chris@16
|
550 {
|
Chris@16
|
551 return basic_message<CharType>(single,plural,n);
|
Chris@16
|
552 }
|
Chris@16
|
553 ///
|
Chris@16
|
554 /// \brief Translate a plural message from in constext, \a context, \a single and \a plural are not copied
|
Chris@16
|
555 ///
|
Chris@16
|
556 template<typename CharType>
|
Chris@16
|
557 inline basic_message<CharType> translate( CharType const *context,
|
Chris@16
|
558 CharType const *single,
|
Chris@16
|
559 CharType const *plural,
|
Chris@16
|
560 int n)
|
Chris@16
|
561 {
|
Chris@16
|
562 return basic_message<CharType>(context,single,plural,n);
|
Chris@16
|
563 }
|
Chris@16
|
564
|
Chris@16
|
565 ///
|
Chris@16
|
566 /// \brief Translate a message, \a msg is copied
|
Chris@16
|
567 ///
|
Chris@16
|
568 template<typename CharType>
|
Chris@16
|
569 inline basic_message<CharType> translate(std::basic_string<CharType> const &msg)
|
Chris@16
|
570 {
|
Chris@16
|
571 return basic_message<CharType>(msg);
|
Chris@16
|
572 }
|
Chris@16
|
573
|
Chris@16
|
574 ///
|
Chris@16
|
575 /// \brief Translate a message in context,\a context and \a msg is copied
|
Chris@16
|
576 ///
|
Chris@16
|
577 template<typename CharType>
|
Chris@16
|
578 inline basic_message<CharType> translate( std::basic_string<CharType> const &context,
|
Chris@16
|
579 std::basic_string<CharType> const &msg)
|
Chris@16
|
580 {
|
Chris@16
|
581 return basic_message<CharType>(context,msg);
|
Chris@16
|
582 }
|
Chris@16
|
583 ///
|
Chris@16
|
584 /// \brief Translate a plural message form in constext, \a context, \a single and \a plural are copied
|
Chris@16
|
585 ///
|
Chris@16
|
586 template<typename CharType>
|
Chris@16
|
587 inline basic_message<CharType> translate( std::basic_string<CharType> const &context,
|
Chris@16
|
588 std::basic_string<CharType> const &single,
|
Chris@16
|
589 std::basic_string<CharType> const &plural,
|
Chris@16
|
590 int n)
|
Chris@16
|
591 {
|
Chris@16
|
592 return basic_message<CharType>(context,single,plural,n);
|
Chris@16
|
593 }
|
Chris@16
|
594
|
Chris@16
|
595 ///
|
Chris@16
|
596 /// \brief Translate a plural message form, \a single and \a plural are copied
|
Chris@16
|
597 ///
|
Chris@16
|
598
|
Chris@16
|
599 template<typename CharType>
|
Chris@16
|
600 inline basic_message<CharType> translate( std::basic_string<CharType> const &single,
|
Chris@16
|
601 std::basic_string<CharType> const &plural,
|
Chris@16
|
602 int n)
|
Chris@16
|
603 {
|
Chris@16
|
604 return basic_message<CharType>(single,plural,n);
|
Chris@16
|
605 }
|
Chris@16
|
606
|
Chris@16
|
607 /// @}
|
Chris@16
|
608
|
Chris@16
|
609 ///
|
Chris@16
|
610 /// \anchor boost_locale_gettext_family \name Direct message translation functions family
|
Chris@16
|
611 ///
|
Chris@16
|
612
|
Chris@16
|
613 ///
|
Chris@16
|
614 /// Translate message \a id according to locale \a loc
|
Chris@16
|
615 ///
|
Chris@16
|
616 template<typename CharType>
|
Chris@16
|
617 std::basic_string<CharType> gettext(CharType const *id,
|
Chris@16
|
618 std::locale const &loc=std::locale())
|
Chris@16
|
619 {
|
Chris@16
|
620 return basic_message<CharType>(id).str(loc);
|
Chris@16
|
621 }
|
Chris@16
|
622 ///
|
Chris@16
|
623 /// Translate plural form according to locale \a loc
|
Chris@16
|
624 ///
|
Chris@16
|
625 template<typename CharType>
|
Chris@16
|
626 std::basic_string<CharType> ngettext( CharType const *s,
|
Chris@16
|
627 CharType const *p,
|
Chris@16
|
628 int n,
|
Chris@16
|
629 std::locale const &loc=std::locale())
|
Chris@16
|
630 {
|
Chris@16
|
631 return basic_message<CharType>(s,p,n).str(loc);
|
Chris@16
|
632 }
|
Chris@16
|
633 ///
|
Chris@16
|
634 /// Translate message \a id according to locale \a loc in domain \a domain
|
Chris@16
|
635 ///
|
Chris@16
|
636 template<typename CharType>
|
Chris@16
|
637 std::basic_string<CharType> dgettext( char const *domain,
|
Chris@16
|
638 CharType const *id,
|
Chris@16
|
639 std::locale const &loc=std::locale())
|
Chris@16
|
640 {
|
Chris@16
|
641 return basic_message<CharType>(id).str(loc,domain);
|
Chris@16
|
642 }
|
Chris@16
|
643
|
Chris@16
|
644 ///
|
Chris@16
|
645 /// Translate plural form according to locale \a loc in domain \a domain
|
Chris@16
|
646 ///
|
Chris@16
|
647 template<typename CharType>
|
Chris@16
|
648 std::basic_string<CharType> dngettext( char const *domain,
|
Chris@16
|
649 CharType const *s,
|
Chris@16
|
650 CharType const *p,
|
Chris@16
|
651 int n,
|
Chris@16
|
652 std::locale const &loc=std::locale())
|
Chris@16
|
653 {
|
Chris@16
|
654 return basic_message<CharType>(s,p,n).str(loc,domain);
|
Chris@16
|
655 }
|
Chris@16
|
656 ///
|
Chris@16
|
657 /// Translate message \a id according to locale \a loc in context \a context
|
Chris@16
|
658 ///
|
Chris@16
|
659 template<typename CharType>
|
Chris@16
|
660 std::basic_string<CharType> pgettext( CharType const *context,
|
Chris@16
|
661 CharType const *id,
|
Chris@16
|
662 std::locale const &loc=std::locale())
|
Chris@16
|
663 {
|
Chris@16
|
664 return basic_message<CharType>(context,id).str(loc);
|
Chris@16
|
665 }
|
Chris@16
|
666 ///
|
Chris@16
|
667 /// Translate plural form according to locale \a loc in context \a context
|
Chris@16
|
668 ///
|
Chris@16
|
669 template<typename CharType>
|
Chris@16
|
670 std::basic_string<CharType> npgettext( CharType const *context,
|
Chris@16
|
671 CharType const *s,
|
Chris@16
|
672 CharType const *p,
|
Chris@16
|
673 int n,
|
Chris@16
|
674 std::locale const &loc=std::locale())
|
Chris@16
|
675 {
|
Chris@16
|
676 return basic_message<CharType>(context,s,p,n).str(loc);
|
Chris@16
|
677 }
|
Chris@16
|
678 ///
|
Chris@16
|
679 /// Translate message \a id according to locale \a loc in domain \a domain in context \a context
|
Chris@16
|
680 ///
|
Chris@16
|
681 template<typename CharType>
|
Chris@16
|
682 std::basic_string<CharType> dpgettext( char const *domain,
|
Chris@16
|
683 CharType const *context,
|
Chris@16
|
684 CharType const *id,
|
Chris@16
|
685 std::locale const &loc=std::locale())
|
Chris@16
|
686 {
|
Chris@16
|
687 return basic_message<CharType>(context,id).str(loc,domain);
|
Chris@16
|
688 }
|
Chris@16
|
689 ///
|
Chris@16
|
690 /// Translate plural form according to locale \a loc in domain \a domain in context \a context
|
Chris@16
|
691 ///
|
Chris@16
|
692 template<typename CharType>
|
Chris@16
|
693 std::basic_string<CharType> dnpgettext(char const *domain,
|
Chris@16
|
694 CharType const *context,
|
Chris@16
|
695 CharType const *s,
|
Chris@16
|
696 CharType const *p,
|
Chris@16
|
697 int n,
|
Chris@16
|
698 std::locale const &loc=std::locale())
|
Chris@16
|
699 {
|
Chris@16
|
700 return basic_message<CharType>(context,s,p,n).str(loc,domain);
|
Chris@16
|
701 }
|
Chris@16
|
702
|
Chris@16
|
703 ///
|
Chris@16
|
704 /// \cond INTERNAL
|
Chris@16
|
705 ///
|
Chris@16
|
706
|
Chris@16
|
707 template<>
|
Chris@16
|
708 struct BOOST_LOCALE_DECL base_message_format<char> : public std::locale::facet
|
Chris@16
|
709 {
|
Chris@16
|
710 base_message_format(size_t refs = 0) : std::locale::facet(refs)
|
Chris@16
|
711 {
|
Chris@16
|
712 }
|
Chris@16
|
713 static std::locale::id id;
|
Chris@16
|
714 };
|
Chris@16
|
715
|
Chris@16
|
716 template<>
|
Chris@16
|
717 struct BOOST_LOCALE_DECL base_message_format<wchar_t> : public std::locale::facet
|
Chris@16
|
718 {
|
Chris@16
|
719 base_message_format(size_t refs = 0) : std::locale::facet(refs)
|
Chris@16
|
720 {
|
Chris@16
|
721 }
|
Chris@16
|
722 static std::locale::id id;
|
Chris@16
|
723 };
|
Chris@16
|
724
|
Chris@16
|
725 #ifdef BOOST_HAS_CHAR16_T
|
Chris@16
|
726
|
Chris@16
|
727 template<>
|
Chris@16
|
728 struct BOOST_LOCALE_DECL base_message_format<char16_t> : public std::locale::facet
|
Chris@16
|
729 {
|
Chris@16
|
730 base_message_format(size_t refs = 0) : std::locale::facet(refs)
|
Chris@16
|
731 {
|
Chris@16
|
732 }
|
Chris@16
|
733 static std::locale::id id;
|
Chris@16
|
734 };
|
Chris@16
|
735
|
Chris@16
|
736 #endif
|
Chris@16
|
737
|
Chris@16
|
738 #ifdef BOOST_HAS_CHAR32_T
|
Chris@16
|
739
|
Chris@16
|
740 template<>
|
Chris@16
|
741 struct BOOST_LOCALE_DECL base_message_format<char32_t> : public std::locale::facet
|
Chris@16
|
742 {
|
Chris@16
|
743 base_message_format(size_t refs = 0) : std::locale::facet(refs)
|
Chris@16
|
744 {
|
Chris@16
|
745 }
|
Chris@16
|
746 static std::locale::id id;
|
Chris@16
|
747 };
|
Chris@16
|
748
|
Chris@16
|
749 #endif
|
Chris@16
|
750
|
Chris@16
|
751 /// \endcond
|
Chris@16
|
752
|
Chris@16
|
753 ///
|
Chris@16
|
754 /// @}
|
Chris@16
|
755 ///
|
Chris@16
|
756
|
Chris@16
|
757 namespace as {
|
Chris@16
|
758 /// \cond INTERNAL
|
Chris@16
|
759 namespace details {
|
Chris@16
|
760 struct set_domain {
|
Chris@16
|
761 std::string domain_id;
|
Chris@16
|
762 };
|
Chris@16
|
763 template<typename CharType>
|
Chris@16
|
764 std::basic_ostream<CharType> &operator<<(std::basic_ostream<CharType> &out, set_domain const &dom)
|
Chris@16
|
765 {
|
Chris@16
|
766 int id = std::use_facet<message_format<CharType> >(out.getloc()).domain(dom.domain_id);
|
Chris@16
|
767 ios_info::get(out).domain_id(id);
|
Chris@16
|
768 return out;
|
Chris@16
|
769 }
|
Chris@16
|
770 } // details
|
Chris@16
|
771 /// \endcond
|
Chris@16
|
772
|
Chris@16
|
773 ///
|
Chris@16
|
774 /// \addtogroup manipulators
|
Chris@16
|
775 ///
|
Chris@16
|
776 /// @{
|
Chris@16
|
777
|
Chris@16
|
778 ///
|
Chris@16
|
779 /// Manipulator for switching message domain in ostream,
|
Chris@16
|
780 ///
|
Chris@16
|
781 /// \note The returned object throws std::bad_cast if the I/O stream does not have \ref message_format facet installed
|
Chris@16
|
782 ///
|
Chris@16
|
783 inline
|
Chris@16
|
784 #ifdef BOOST_LOCALE_DOXYGEN
|
Chris@16
|
785 unspecified_type
|
Chris@16
|
786 #else
|
Chris@16
|
787 details::set_domain
|
Chris@16
|
788 #endif
|
Chris@16
|
789 domain(std::string const &id)
|
Chris@16
|
790 {
|
Chris@16
|
791 details::set_domain tmp = { id };
|
Chris@16
|
792 return tmp;
|
Chris@16
|
793 }
|
Chris@16
|
794 /// @}
|
Chris@16
|
795 } // as
|
Chris@16
|
796 } // locale
|
Chris@16
|
797 } // boost
|
Chris@16
|
798
|
Chris@16
|
799 #ifdef BOOST_MSVC
|
Chris@16
|
800 #pragma warning(pop)
|
Chris@16
|
801 #endif
|
Chris@16
|
802
|
Chris@16
|
803
|
Chris@16
|
804 #endif
|
Chris@16
|
805
|
Chris@16
|
806 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|
Chris@16
|
807
|