1 // This may look like C code, but it's really -*- C++ -*-
2 /*
3  * Copyright (C) 2008 Emweb bv, Herent, Belgium.
4  *
5  * See the LICENSE file for terms of use.
6  */
7 #ifndef WSTRING_H_
8 #define WSTRING_H_
9 
10 #include <Wt/WDllDefs.h>
11 #include <Wt/WGlobal.h>
12 
13 #include <string>
14 #include <vector>
15 #include <iosfwd>
16 #include <locale>
17 
18 namespace Wt {
19 
20 /*! \class WString Wt/WString.h Wt/WString.h
21  *  \brief A value class which describes a locale-aware unicode string.
22  *
23  * %Wt offers this string to facilitate handling of unicode text
24  * through the user interface, and to offer support for localized text
25  * using message resource bundles.
26  *
27  * A %WString may be constructed from a std::string, std::wstring or
28  * c-style strings (const char * and const wchar_t *), and converted
29  * to each of these strings taking into account the locale in which
30  * the %Wt application runs on the web server. Independent of the
31  * locale on the web server, you may convert from and to UTF8 unicode
32  * encoded std::strings.
33  *
34  * By using the static functions WString::tr() (or WWidget::tr()), one
35  * may construct a localized string. The key is used to retrieve its
36  * current value from the application's message-resource
37  * bundles.
38  *
39  * Argument place holder in a string, denoted using {<i>n</i>} for the
40  * <i>n</i>'th argument, may be substituted by values set using
41  * arg(int) and arg(std::string).
42  *
43  * %WString is used by all built-in widgets for displayed text. By
44  * calling WApplication::setLocale() or WApplication::refresh(), the
45  * contents of every %WString is reevaluated in the new locale, by
46  * calling refresh(). In this way, the contents of the whole user
47  * interface is adapted to a possibly changed locale.
48  *
49  * To benefit from the localization properties of %WString, you should
50  * design your own widget classes to use %WString in their interface
51  * for any text that is displayed. In this way, your own widgets will
52  * automatically, and without any extra effort, participate in a
53  * relocalization triggered by WApplication::setLocale().
54  *
55  * This string class does not provide anything more than basic
56  * manipulations. Instead, you should convert to a standard library
57  * string class to manipulate the string contents and perform string
58  * algorithms on them. In particular, we recommend to use the
59  * conversion methods toUTF8(), fromUTF8() to convert from and to UTF8
60  * encoded std::strings. In this way, you can support the whole
61  * unicode character set, with backward compatible support for the
62  * standard 7-bit ASCII set. Since %WString internally uses
63  * UTF8-encoding, and UTF8-encoding is used by the library for
64  * communication with the browser, there is no actual conversion
65  * overhead. Only when you need to run string algorithms that require
66  * the actual length of the string in number of characters, you would
67  * need to convert to a wide string representation such as
68  * std::wstring.
69  *
70  * \sa WApplication::messageResourceBundle()
71  * \sa WApplication::locale()
72  */
73 class WT_API WString
74 {
75 public:
76   /*! \brief Sets the encoding for
77    *         \link Wt::CharEncoding::Default CharEncoding::Default\endlink
78    *
79    * WString::setDefaultEncoding() controls the behaviour of \link
80    * Wt::CharEncoding::Default CharEncoding::Default\endlink. If not modified, the
81    * default encoding will be the CharEncoding::UTF8.
82    *
83    * Since this is a system-wide setting, and not a per-session setting,
84    * you should call this function before any session is created, e.g. in
85    * main() before calling WRun().
86   */
87   static void setDefaultEncoding(Wt::CharEncoding encoding);
88 
89   /*! \brief Creates an empty string
90    *
91    * Create a literal string with empty contents ("").
92    */
93   WString();
94 
95   /*! \brief Creates a %WString from a wide C string.
96    *
97    * The wide string is implicitly converted to proper unicode. Note
98    * that there are known issues with the portability of wchar_t since
99    * its width and encoding are platform dependent.
100    */
101   WString(const wchar_t *value);
102 
103   /*! \brief Copy constructor
104    */
105   WString(const WString& other);
106 
107   /*! \brief Move constructor
108    */
109   WString(WString&& other);
110 
111   /*! \brief Creates a %WString from a wide C++ string
112    *
113    * The wide string is implicitly converted to proper unicode. Note
114    * that there are known issues with the portability of wchar_t since
115    * its width and encoding are platform dependent.
116    */
117   WString(const std::wstring& value);
118 
119 #ifndef WT_TARGET_JAVA
120   /*! \brief Creates a %WString from a UTF-16 C string.
121    *
122    * The UTF-16 string is implicitly converted to UTF-8.
123    */
124   WString(const char16_t *value);
125 
126   /*! \brief Creates a %WString from a UTF-16 C++ string
127    *
128    * The UTF-16 string is implicitly converted to UTF-8.
129    */
130   WString(const std::u16string &value);
131 
132   /*! \brief Creates a %WString from a UTF-32 C string.
133    *
134    * The UTF-32 string is implicitly converted to UTF-8.
135    */
136   WString(const char32_t *value);
137 
138   /*! \brief Creates a %WString from a UTF-32 C++ string
139    *
140    * The UTF-32 string is implicitly converted to UTF-8.
141    */
142   WString(const std::u32string &value);
143 #endif // WT_TARGET_JAVA
144 
145   /*! \brief Creates a %WString from a C string.
146    *
147    * The C string is implicitly converted to unicode. When
148    * \p encoding is \link Wt::CharEncoding::Local CharEncoding::Local\endlink,
149    * the current locale is used to interpret the C string. When
150    * encoding is \link Wt::CharEncoding::UTF8 CharEncoding::UTF8\endlink, the C string is
151    * interpreted as a CharEncoding::UTF8 encoded unicode string.
152    *
153    * WString::setDefaultEncoding() controls the behaviour of
154    * \link Wt::CharEncoding::Default CharEncoding::Default\endlink. Use it to set a
155    * system-wide default format for C style strings (e.g. to UTF-8).
156    */
157   WString(const char *value,
158 	  CharEncoding encoding = CharEncoding::Default);
159 
160   /*! \brief Creates a %WString from a C string.
161    *
162    * The C string is implicitly converted to unicode. The
163    * string is interpreted within the character set of the given locale.
164    */
165   WString(const char *value, const std::locale &loc);
166 
167   /*! \brief Creates a %WString from a C++ string.
168    *
169    * The C++ string is implicitly converted to unicode. When
170    * \p encoding is \link Wt::CharEncoding::Local CharEncoding::Local\endlink,
171    * the current locale is used to interpret the C++ string. When
172    * encoding is \link Wt::CharEncoding::UTF8 CharEncoding::UTF8\endlink, the C++ string is
173    * interpreted as a CharEncoding::UTF8 encoded unicode string.
174    *
175    * WString::setDefaultEncoding() controls the behaviour of
176    * \link Wt::CharEncoding::Default CharEncoding::Default\endlink. Use it to set a
177    * system-wide default format for C style strings (e.g. to UTF-8).
178 
179    */
180   WString(const std::string& value,
181 	  CharEncoding encoding = CharEncoding::Default);
182 
183   /*! \brief Creates a %WString from a C++ string.
184    *
185    * The C++ string is implicitly converted to unicode. When
186    * \p encoding is \link Wt::CharEncoding::Local CharEncoding::Local\endlink,
187    * the current locale is used to interpret the C++ string. When
188    * encoding is \link Wt::CharEncoding::UTF8 CharEncoding::UTF8\endlink, the C++ string is
189    * interpreted as a CharEncoding::UTF8 encoded unicode string.
190    *
191    * WString::setDefaultEncoding() controls the behaviour of
192    * \link Wt::CharEncoding::Default CharEncoding::Default\endlink. Use it to set a
193    * system-wide default format for C style strings (e.g. to UTF-8).
194 
195    */
196   WString(std::string&& value,
197 	  CharEncoding encoding = CharEncoding::Default);
198 
199   /*! \brief Creates a %WString from a C++ string.
200    *
201    * The C++ string is implicitly converted to unicode. The
202    * string is interpreted within the character set of the given locale.
203    */
204   WString(const std::string& value, const std::locale &loc);
205 
206   /*! \brief Destructor
207    */
208   ~WString();
209 
210   WString trim() const;
211 
212   /*! \brief Copy assignment operator
213    *
214    * Copy another string into this string.
215    */
216   WString& operator= (const WString& rhs);
217 
218   /*! \brief Move assignment operator
219    *
220    * Move another string into this string.
221    */
222   WString& operator= (WString&& rhs);
223 
224   /*! \brief Comparison operator
225    *
226    * Compares two strings and returns \c true if the strings are exactly
227    * the same. This may require evaluating a localized string in the
228    * current locale.
229    */
230   bool operator== (const WString& rhs) const;
231 
232   /*! \brief Comparison operator
233    *
234    * Compares to strings lexicographically. This may require
235    * evaluating a localized string in the current locale. The unicode
236    * representation of the strings are compared.
237    */
238   bool operator< (const WString& rhs) const;
239 
240   /*! \brief Comparison operator
241    *
242    * Compares to strings lexicographically. This may require
243    * evaluating a localized string in the current locale. The unicode
244    * representation of the strings are compared.
245    */
246   bool operator> (const WString& rhs) const;
247 
248 #ifdef WT_TARGET_JAVA
249   int compareTo(const WString& rhs) const;
250 #endif
251 
252   /*! \brief Self-concatenation operator
253    *
254    * Appends a string to the current value. If the string was localized,
255    * this automatically converts it to a literal string, by evaluating the
256    * string using the current WLocale.
257    */
258   WString& operator+= (const WString& rhs);
259 
260   /*! \brief Self-concatenation operator
261    *
262    * Appends a string to the current value. If the string was localized,
263    * this automatically converts it to a literal string, by evaluating the
264    * string using the current WLocale.
265    */
266   WString& operator+= (const std::wstring& rhs);
267 
268 #ifndef WT_TARGET_JAVA
269   /*! \brief Self-concatenation operator
270    *
271    * Appends a string to the current value. If the string was localized,
272    * this automatically converts it to a literal string, by evaluating the
273    * string using the current WLocale.
274    */
275   WString& operator+= (const std::u16string& rhs);
276 
277   /*! \brief Self-concatenation operator
278    *
279    * Appends a string to the current value. If the string was localized,
280    * this automatically converts it to a literal string, by evaluating the
281    * string using the current WLocale.
282    */
283   WString& operator+= (const std::u32string& rhs);
284 #endif // WT_TARGET_JAVA
285 
286   /*! \brief Self-concatenation operator
287    *
288    * Appends a string to the current value. If the string was localized,
289    * this automatically converts it to a literal string, by evaluating the
290    * string using the current WLocale.
291    */
292   WString& operator+= (const wchar_t *rhs);
293 
294 #ifndef WT_TARGET_JAVA
295   /*! \brief Self-concatenation operator
296    *
297    * Appends a string to the current value. If the string was localized,
298    * this automatically converts it to a literal string, by evaluating the
299    * string using the current WLocale.
300    */
301   WString& operator+= (const char16_t *rhs);
302 
303   /*! \brief Self-concatenation operator
304    *
305    * Appends a string to the current value. If the string was localized,
306    * this automatically converts it to a literal string, by evaluating the
307    * string using the current WLocale.
308    */
309   WString& operator+= (const char32_t *rhs);
310 #endif // WT_TARGET_JAVA
311 
312   /*! \brief Self-concatenation operator
313    *
314    * Appends a string to the current value. The right hand side is
315    * interpreted in the server locale and converted to unicode. If the
316    * string was localized, this automatically converts it to a literal
317    * string, by evaluating the string using the current WLocale.
318    */
319   WString& operator+= (const std::string& rhs);
320 
321   /*! \brief Self-concatenation operator
322    *
323    * Appends a string to the current value. The right hand side is
324    * interpreted in the server locale and converted to unicode. If the
325    * string was localized, this automatically converts it to a literal
326    * string, by evaluating the string using the current WLocale.
327    */
328   WString& operator+= (const char *rhs);
329 
330   /*! \brief Returns whether the string is empty.
331    */
332   bool empty() const;
333 
334   /*! \brief Creates a %WString from a UTF-8 encoded string.
335    *
336    * This is equivalent to using the constructor WString(\p value,
337    * CharEncoding::UTF8).
338    *
339    * When \p checkValid is \c true, the UTF-8 encoding is validated. You
340    * should enable this only if you cannot trust the origin of the string.
341    * The library uses this internally whenever it receives data from the
342    * browser (in UTF-8 format).
343    */
344   static WString fromUTF8(const std::string& value, bool checkValid = false);
345 
346   /*! \brief Creates a %WString from a UTF-8 encoded string.
347    *
348    * This is equivalent to using the constructor WString(\p value,
349    * CharEncoding::UTF8).
350    *
351    * When \p checkValid is \c true, the UTF-8 encoding is validated. You
352    * should enable this only if you cannot trust the origin of the string.
353    * The library uses this internally whenever it receives data from the
354    * browser (in UTF-8 format).
355    */
356   static WString fromUTF8(std::string&& value, bool checkValid = false);
357 
358   /*! \brief Creates a %WString from a UTF-8 unicode encoded string.
359    *
360    * This is equivalent to using the constructor WString(\p value,
361    * CharEncoding::UTF8).
362    *
363    * When \p checkValid is \c true, the UTF-8 encoding is validated. You
364    * should enable this only if you cannot trust the origin of the string.
365    * The library uses this internally whenever it receives data from the
366    * browser (in UTF-8 format).
367    */
368   static WString fromUTF8(const char *value, bool checkValid = false);
369 
370   /*! \brief Returns the value as a UTF-8 encoded string.
371    *
372    * For a localized string, returns the current localized value. If
373    * the localized string is formatted as XML, this will unescape all
374    * XML escapes. Literal strings will remain unchanged.
375    *
376    * \sa fromUTF8(), toXhtmlUTF8()
377    */
378   std::string toUTF8() const;
379 
380   /*! \brief Returns the value as a UTF-8 encoded XHTML string.
381    *
382    * For a localized string, returns the current localized value. If
383    * the localized string is formatted as plaintext, the localized string
384    * will be escaped. Literal strings will remain unchanged.
385    *
386    * \sa toUTF8()
387    */
388   std::string toXhtmlUTF8() const;
389 
390   /*! \brief Creates a localized string from a key.
391    *
392    * Whenever the value of the string is needed, the key is used for a
393    * lookup in the application message resource bundles taking into
394    * account the current application locale. If the key cannot be
395    * resolved, its value is set to '??key??'.
396    *
397    * \sa WApplication::locale(), WApplication::localizedStrings()
398    */
399   static WString tr(const char *key);
400 
401   /*! \brief Creates a localized string with the specified key.
402    *
403    * \sa tr(const char *)
404    */
405   static WString tr(const std::string& key);
406 
407   /*! \brief Creates a localized string from a key for a number \p n.
408    *
409    * Whenever the value of the string is needed, the \p key is used
410    * for a lookup in the application message resource bundles taking
411    * into account the current application locale. This function
412    * fetches the appropriate plural case for the translation
413    * corresponding to the quantity \p n. Note that usually, your
414    * string will have a place-holder for the value of \p n, and thus
415    * you will also need to bind \p as an argument.
416    *
417    * For example, consider a string "quantity.cars" with two plural cases:
418    * - n == 1: "{1} car"
419    * - n != 1: "{1} cars"
420    *
421    * You would use the following to use the string:
422    * \if cpp
423    * \code
424    * Wt::WString::trn("quantity.cars", cars).arg(cars);
425    * \endcode
426    * \else
427    * \code
428    * WString.trn("quantity.cars", cars).arg(cars);
429    * \endcode
430    * \endif
431    *
432    * If the \p key cannot be resolved, its value is set to '??key??'.
433    *
434    * \sa tr()
435    */
436   static WString trn(const char *key, ::uint64_t n);
437 
438   /*! \brief Creates a localized string with the specified key for a
439       number \c n.
440    *
441    * \sa trn(const char *)
442    */
443   static WString trn(const std::string& key, ::uint64_t n);
444 
445   /*! \brief Returns the value as a wide C++ string.
446    *
447    * A localized string is resolved using the WApplication::localizedStrings().
448    *
449    * Argument place holders are substitued with actual arguments.
450    */
451   std::wstring value() const;
452 
453 #ifndef WT_TARGET_JAVA
454   /*! \brief Returns the value as a UTF-16 C++ string.
455    *
456    * A localized string is resolved using the WApplication::localizedStrings().
457    *
458    * Argument place holders are substitued with actual arguments.
459    */
460   std::u16string toUTF16() const;
461 
462   /*! \brief Returns the value as a UTF-32 C++ string.
463    *
464    * A localized string is resolved using the WApplication::localizedStrings().
465    *
466    * Argument place holders are substitued with actual arguments.
467    */
468   std::u32string toUTF32() const;
469 #endif // WT_TARGET_JAVA
470 
471   /*! \brief Returns the value as a narrow C++ string.
472    *
473    * A localized string is resolved using the WApplication::localizedStrings().
474    *
475    * Argument place holders are substitued with actual arguments.
476    *
477    * Any wide character is narrowed using the provided locale, possibly
478    * losing information. If you wish to keep all information, use toUTF8()
479    * instead, which encodes wide characters in the string.
480    *
481    * \sa toUTF8()
482    */
483   std::string narrow(const std::locale &loc = std::locale()) const;
484 
485   /*! \brief Returns the value as a wide C++ string.
486    *
487    * A localized string is resolved using the WApplication::localizedStrings().
488    *
489    * Argument place holders are substitued with actual arguments.
490    */
491   operator std::wstring() const;
492 
493 #ifndef WT_TARGET_JAVA
494   /*! \brief Returns the value as a UTF-16 C++ string.
495    *
496    * A localized string is resolved using the WApplication::localizedStrings().
497    *
498    * Argument place holders are substitued with actual arguments.
499    */
500   operator std::u16string() const;
501 
502   /*! \brief Returns the value as a UTF-32 C++ string.
503    *
504    * A localized string is resolved using the WApplication::localizedStrings().
505    *
506    * Argument place holders are substitued with actual arguments.
507    */
508   operator std::u32string() const;
509 #endif // WT_TARGET_JAVA
510 
511   /*! \brief Returns whether the string is literal or localized.
512    *
513    * \sa tr()
514    */
literal()515   bool literal() const { return !impl_ || impl_->key_.empty(); }
516 
517   /*! \brief Returns the key for a localized string.
518    *
519    * When the string is literal, the result is undefined.
520    */
521   const std::string key() const;
522 
523   /*! \brief Substitutes the next positional argument with a string value.
524    *
525    * In the string, the \p n-th argument is referred to as using
526    * {\p n}.
527    *
528    * For example: the string "<tt>{1} bought {2} apples in the
529    * shop.</tt>" with first argument value "<tt>Bart</tt>" and second
530    * argument value <tt>5</tt> becomes: "<tt>Bart bought 5 apples in
531    * the shop.</tt>"
532    */
533   WString& arg(const std::wstring& value);
534 
535   /*! \brief Substitutes the next positional argument with a string value.
536    *
537    * In the string, the \p n-th argument is referred to as using
538    * {\p n}.
539    *
540    * For example: the string "<tt>{1} bought {2} apples in the
541    * shop.</tt>" with first argument value "<tt>Bart</tt>" and second
542    * argument value <tt>5</tt> becomes: "<tt>Bart bought 5 apples in
543    * the shop.</tt>"
544    */
545   WString& arg(const wchar_t *value);
546 
547 #ifndef WT_TARGET_JAVA
548   /*! \brief Substitutes the next positional argument with a string value.
549    *
550    * In the string, the \p n-th argument is referred to as using
551    * {\p n}.
552    *
553    * For example: the string "<tt>{1} bought {2} apples in the
554    * shop.</tt>" with first argument value "<tt>Bart</tt>" and second
555    * argument value <tt>5</tt> becomes: "<tt>Bart bought 5 apples in
556    * the shop.</tt>"
557    */
558   WString& arg(const std::u16string& value);
559 
560   /*! \brief Substitutes the next positional argument with a string value.
561    *
562    * In the string, the \p n-th argument is referred to as using
563    * {\p n}.
564    *
565    * For example: the string "<tt>{1} bought {2} apples in the
566    * shop.</tt>" with first argument value "<tt>Bart</tt>" and second
567    * argument value <tt>5</tt> becomes: "<tt>Bart bought 5 apples in
568    * the shop.</tt>"
569    */
570   WString& arg(const char16_t *value);
571 
572   /*! \brief Substitutes the next positional argument with a string value.
573    *
574    * In the string, the \p n-th argument is referred to as using
575    * {\p n}.
576    *
577    * For example: the string "<tt>{1} bought {2} apples in the
578    * shop.</tt>" with first argument value "<tt>Bart</tt>" and second
579    * argument value <tt>5</tt> becomes: "<tt>Bart bought 5 apples in
580    * the shop.</tt>"
581    */
582   WString& arg(const std::u32string& value);
583 
584   /*! \brief Substitutes the next positional argument with a string value.
585    *
586    * In the string, the \p n-th argument is referred to as using
587    * {\p n}.
588    *
589    * For example: the string "<tt>{1} bought {2} apples in the
590    * shop.</tt>" with first argument value "<tt>Bart</tt>" and second
591    * argument value <tt>5</tt> becomes: "<tt>Bart bought 5 apples in
592    * the shop.</tt>"
593    */
594   WString& arg(const char32_t *value);
595 #endif // WT_TARGET_JAVA
596 
597   /*! \brief Substitutes the next positional argument with a string value.
598    *
599    * In the string, the \p n-th argument is referred to as using
600    * {\p n}.
601    *
602    * For example: the string "<tt>{1} bought {2} apples in the
603    * shop.</tt>" with first argument value "<tt>Bart</tt>" and second
604    * argument value <tt>5</tt> becomes: "<tt>Bart bought 5 apples in
605    * the shop.</tt>"
606    */
607   WString& arg(const std::string& value,
608 	       CharEncoding encoding = CharEncoding::Default);
609 
610   /*! \brief Substitutes the next positional argument with a string value.
611    *
612    * In the string, the \p n-th argument is referred to as using
613    * {\p n}.
614    *
615    * For example: the string "<tt>{1} bought {2} apples in the
616    * shop.</tt>" with first argument value "<tt>Bart</tt>" and second
617    * argument value <tt>5</tt> becomes: "<tt>Bart bought 5 apples in
618    * the shop.</tt>"
619    */
620   WString& arg(const char *value,
621 	       CharEncoding encoding = CharEncoding::Default);
622 
623   /*! \brief Substitutes the next positional argument with a string value.
624    *
625    * In the string, the \p n-th argument is referred to as using
626    * {\p n}.
627    *
628    * For example: the string "<tt>{1} bought {2} apples in the
629    * shop.</tt>" with first argument value "<tt>Bart</tt>" and second
630    * argument value <tt>5</tt> becomes: "<tt>Bart bought 5 apples in
631    * the shop.</tt>"
632    */
633   WString& arg(const WString& value);
634 
635   /*! \brief Substitutes the next positional argument with an integer value.
636    *
637    * In the string, the \p n-th argument is reffered to as using
638    * {\p n}.
639    *
640    * For example: the string "<tt>{1} bought {2} apples in the
641    * shop.</tt>" with first argument value "<tt>Bart</tt>" and second
642    * argument value <tt>5</tt> becomes: "<tt>Bart bought 5 apples in
643    * the shop.</tt>"
644    */
645   WString& arg(int value);
646 
647   /*! \brief Substitutes the next positional argument with an unsigned value.
648    *
649    * \sa arg()
650    */
651   WString& arg(unsigned value);
652 
653   /*! \brief Substitutes the next positional argument with an integer value.
654    *
655    * In the string, the \p n-th argument is reffered to as using
656    * {\p n}.
657    *
658    * For example: the string "<tt>{1} bought {2} apples in the
659    * shop.</tt>" with first argument value "<tt>Bart</tt>" and second
660    * argument value <tt>5</tt> becomes: "<tt>Bart bought 5 apples in
661    * the shop.</tt>"
662    */
663   WString& arg(long value);
664 
665   /*! \brief Substitutes the next positional argument with an unsigned value.
666    *
667    * \sa arg()
668    */
669   WString& arg(unsigned long value);
670 
671   /*! \brief Substitutes the next positional argument with an integer value.
672    *
673    * In the string, the \p n-th argument is reffered to as using
674    * {\p n}.
675    *
676    * For example: the string "<tt>{1} bought {2} apples in the
677    * shop.</tt>" with first argument value "<tt>Bart</tt>" and second
678    * argument value <tt>5</tt> becomes: "<tt>Bart bought 5 apples in
679    * the shop.</tt>"
680    */
681   WString& arg(long long value);
682 
683   /*! \brief Substitutes the next positional argument with an unsigned value.
684    *
685    * \sa arg()
686    */
687   WString& arg(unsigned long long value);
688 
689   /*! \brief Substitutes the next positional argument with a double value.
690    *
691    * In the string, the \p n-th argument is reffered to as using
692    * {\p n}.
693    *
694    * For example: the string "<tt>{1} bought {2} apples in the
695    * shop.</tt>" with first argument value "<tt>Bart</tt>" and second
696    * argument value <tt>5</tt> becomes: "<tt>Bart bought 5 apples in
697    * the shop.</tt>"
698    */
699   WString& arg(double value);
700 
701   /*! \brief Returns the list of arguments
702    */
703   const std::vector<WString>& args() const;
704 
705   /*! \brief Refreshes the string.
706    *
707    * For a localized string, its value is resolved again.
708    *
709    * Returns whether the value has (potentially) changed.
710    */
711   bool refresh();
712 
713   /*! \brief Returns the string as a JavaScript literal
714    *
715    * The \p delimiter may be a single or double quote.
716    *
717    * \sa WWebWidget::jsStringLiteral()
718    */
719   std::string jsStringLiteral(char delimiter = '\'') const;
720 
721 #ifdef WT_CNOR
722   WString& operator+(const char *);
723   WString& operator+(const WString &);
724 #endif
725 
726   /*! \brief Comparison operator
727    *
728    * Compares two strings and returns \c true if the strings are not exactly
729    * the same. This may require evaluating a localized string in the
730    * current locale.
731    */
732   bool operator!= (const WString& rhs) const { return !(*this == rhs); }
733 
734   /*! \brief An empty string.
735    */
736   static const WString Empty;
737 
738   static void checkUTF8Encoding(std::string& value);
739 
740 private:
741   WString(const char *key, bool, ::uint64_t n = -1);
742 
743   std::string utf8_;
744 
745   std::string resolveKey(TextFormat format) const;
746 
747   void makeLiteral();
748 
749   struct Impl {
750     std::string key_;
751     std::vector<WString> arguments_;
752     ::int64_t n_;
753 
754     Impl();
755   };
756 
757   static std::vector<WString> stArguments_;
758 
759   void createImpl();
760 
761   Impl *impl_;
762   static CharEncoding defaultEncoding_;
763   static CharEncoding realEncoding(CharEncoding encoding);
764 };
765 
766 #ifndef WT_CNOR
767 
768 /*! \brief Short hand for WString(const char * value, CharEncoding::UTF8)
769  *
770  * \relates WString
771  */
772 extern WT_API WString utf8(const char *value);
773 
774 /*! \brief Short hand for WString(const std::string& value, CharEncoding::UTF8)
775  *
776  * \relates WString
777  */
778 extern WT_API WString utf8(const std::string& value);
779 
780 /*! \brief Concatenate two WStrings
781  *
782  * \relates WString
783  */
784 extern WT_API WString operator+ (const WString& lhs, const WString& rhs);
785 
786 /*! \brief Conatenate a WString with a C++ wide string
787  *
788  * \relates WString
789  */
790 extern WT_API WString operator+ (const WString& lhs, const std::wstring& rhs);
791 
792 /*! \brief Conatenate a WString with a C++ UTF-16 string
793  *
794  * \relates WString
795  */
796 extern WT_API WString operator+ (const WString& lhs, const std::u16string& rhs);
797 
798 /*! \brief Conatenate a WString with a C++ UTF-32 string
799  *
800  * \relates WString
801  */
802 extern WT_API WString operator+ (const WString& lhs, const std::u32string& rhs);
803 
804 /*! \brief Conatenate a WString with a C wide string
805  *
806  * \relates WString
807  */
808 extern WT_API WString operator+ (const WString& lhs, const wchar_t *rhs);
809 
810 /*! \brief Conatenate a WString with a C UTF-16 string
811  *
812  * \relates WString
813  */
814 extern WT_API WString operator+ (const WString& lhs, const char16_t *rhs);
815 
816 /*! \brief Conatenate a WString with a C UTF-32 string
817  *
818  * \relates WString
819  */
820 extern WT_API WString operator+ (const WString& lhs, const char32_t *rhs);
821 
822 /*! \brief Conatenate a WString with a C++ string
823  *
824  * \relates WString
825  */
826 extern WT_API WString operator+ (const WString& lhs, const std::string& rhs);
827 
828 /*! \brief Conatenate a WString with a C string
829  *
830  * \relates WString
831  */
832 extern WT_API WString operator+ (const WString& lhs, const char *rhs);
833 
834 /*! \brief Conatenate a C++ wide string with a WString
835  *
836  * \relates WString
837  */
838 extern WT_API WString operator+ (const std::wstring& lhs, const WString& rhs);
839 
840 /*! \brief Conatenate a C++ UTF-16 string with a WString
841  *
842  * \relates WString
843  */
844 extern WT_API WString operator+ (const std::u16string& lhs, const WString& rhs);
845 
846 /*! \brief Conatenate a C++ UTF-32 string with a WString
847  *
848  * \relates WString
849  */
850 extern WT_API WString operator+ (const std::u32string& lhs, const WString& rhs);
851 
852 /*! \brief Conatenate a C wide string with a WString
853  *
854  * \relates WString
855  */
856 extern WT_API WString operator+ (const wchar_t *lhs, const WString& rhs);
857 
858 /*! \brief Conatenate a C UTF-16 string with a WString
859  *
860  * \relates WString
861  */
862 extern WT_API WString operator+ (const char16_t *lhs, const WString& rhs);
863 
864 /*! \brief Conatenate a C UTF-32 string with a WString
865  *
866  * \relates WString
867  */
868 extern WT_API WString operator+ (const char32_t *lhs, const WString& rhs);
869 
870 /*! \brief Conatenate a C++ string with a WString
871  *
872  * \relates WString
873  */
874 extern WT_API WString operator+ (const std::string& lhs, const WString& rhs);
875 
876 /*! \brief Conatenate a C string with a WString
877  *
878  * \relates WString
879  */
880 extern WT_API WString operator+ (const char *lhs, const WString& rhs);
881 
882 /*! \brief Compare a C string with a WString
883  *
884  * \relates WString
885  */
886 extern WT_API bool operator== (const char *lhs, const WString& rhs);
887 
888 /*! \brief Compare a C wide string with a WString
889  *
890  * \relates WString
891  */
892 extern WT_API bool operator== (const wchar_t *lhs, const WString& rhs);
893 
894 /*! \brief Compare a C UTF-16 string with a WString
895  *
896  * \relates WString
897  */
898 extern WT_API bool operator== (const char16_t *lhs, const WString& rhs);
899 
900 /*! \brief Compare a C UTF-32 string with a WString
901  *
902  * \relates WString
903  */
904 extern WT_API bool operator== (const char32_t *lhs, const WString& rhs);
905 
906 /*! \brief Compare a C++ string with a WString
907  *
908  * \relates WString
909  */
910 extern WT_API bool operator== (const std::string& lhs, const WString& rhs);
911 
912 /*! \brief Compare a C++ wide string with a WString
913  *
914  * \relates WString
915  */
916 extern WT_API bool operator== (const std::wstring& lhs, const WString& rhs);
917 
918 /*! \brief Compare a C++ UTF-16 string with a WString
919  *
920  * \relates WString
921  */
922 extern WT_API bool operator== (const std::u16string& lhs, const WString& rhs);
923 
924 /*! \brief Compare a C++ UTF-32 string with a WString
925  *
926  * \relates WString
927  */
928 extern WT_API bool operator== (const std::u32string& lhs, const WString& rhs);
929 
930 /*! \brief Compare a C string with a WString
931  *
932  * \relates WString
933  */
934 extern WT_API bool operator!= (const char *lhs, const WString& rhs);
935 
936 /*! \brief Compare a C wide string with a WString
937  *
938  * \relates WString
939  */
940 extern WT_API bool operator!= (const wchar_t *lhs, const WString& rhs);
941 
942 /*! \brief Compare a C UTF-16 string with a WString
943  *
944  * \relates WString
945  */
946 extern WT_API bool operator!= (const char16_t *lhs, const WString& rhs);
947 
948 /*! \brief Compare a C UTF-32 string with a WString
949  *
950  * \relates WString
951  */
952 extern WT_API bool operator!= (const char32_t *lhs, const WString& rhs);
953 
954 /*! \brief Compare a C++ string with a WString
955  *
956  * \relates WString
957  */
958 extern WT_API bool operator!= (const std::string& lhs, const WString& rhs);
959 
960 /*! \brief Compare a C++ wide string with a WString
961  *
962  * \relates WString
963  */
964 extern WT_API bool operator!= (const std::wstring& lhs, const WString& rhs);
965 
966 /*! \brief Compare a C++ UTF-16 string with a WString
967  *
968  * \relates WString
969  */
970 extern WT_API bool operator!= (const std::u16string& lhs, const WString& rhs);
971 
972 /*! \brief Compare a C++ UTF-32 string with a WString
973  *
974  * \relates WString
975  */
976 extern WT_API bool operator!= (const std::u32string& lhs, const WString& rhs);
977 
978 /*! \brief Output a WString to a C++ wide stream
979  *
980  * \relates WString
981  */
982 extern WT_API std::wostream& operator<< (std::wostream& lhs, const WString& rhs);
983 
984 /*! \brief Output a WString to a C++ stream
985  *
986  * The string is narrowed using the currently global C++ locale, possibly
987  * losing information.
988  * \relates WString
989  */
990 extern WT_API std::ostream& operator<< (std::ostream& lhs, const WString& rhs);
991 
992 #endif // WT_CNOR
993 
994 #ifdef WT_TARGET_JAVA
995 /* To emit javadoc links */
996 const WString WString::Empty;
tr(const char * key)997 WString WString::tr(const char *key) { }
998 #endif
999 
1000 }
1001 
1002 #endif // WSTRING_H_
1003