summaryrefslogtreecommitdiff
path: root/glib/glibmm
diff options
context:
space:
mode:
authorDaniel Elstner <daniel@src.gnome.org>2007-09-03 00:30:54 +0000
committerDaniel Elstner <daniel@src.gnome.org>2007-09-03 00:30:54 +0000
commitf73390bfac30242a4d11306f5ca65637e1293a1f (patch)
tree269b26fd7a77dba169895562110db88799292741 /glib/glibmm
parente51acb7f6d22b79c1237d17cb0f22740fa65e9af (diff)
downloadglibmm-f73390bfac30242a4d11306f5ca65637e1293a1f.tar.gz
:FormatStream::FormatStream): Use the global C++ locale instead of forcing
* glib/glibmm/ustring.cc (ustring::FormatStream::FormatStream): Use the global C++ locale instead of forcing the environment's locale onto the formatting stream. This lifts an unnecessary restriction at the cost of requiring users to call std::locale::global(). * glib/glibmm/ustring.h (ustring): Advertise the new compose and format API in the class documentation. (ustring::format): Correct a couple of cut'n'paste mistakes -- ouch. Also add two more overloads so that format() now takes up to eight arguments. Extent the method documentation, too. (ustring::Stringify): Explicitly declare the class as noncopyable. (ustring::compose): Qualify calls to method ustring::compose_argv() in order to avoid surprising name lookup results in the context of the template instantiation. * docs/reference/Doxyfile.in (PREDEFINED): Add GLIBMM_HAVE_WIDESTREAM so that the wide stream I/O operators show up in the documentation. svn path=/trunk/; revision=441
Diffstat (limited to 'glib/glibmm')
-rw-r--r--glib/glibmm/ustring.cc17
-rw-r--r--glib/glibmm/ustring.h130
2 files changed, 106 insertions, 41 deletions
diff --git a/glib/glibmm/ustring.cc b/glib/glibmm/ustring.cc
index 46c6f354..e936e4b4 100644
--- a/glib/glibmm/ustring.cc
+++ b/glib/glibmm/ustring.cc
@@ -1253,22 +1253,7 @@ ustring::SequenceToString<Glib::ustring::const_iterator,gunichar>
ustring::FormatStream::FormatStream()
:
stream_ ()
-{
- // Try to use the default locale of the environment,
- // but don't abort if it cannot be initialized.
-#ifdef GLIBMM_EXCEPTIONS_ENABLED
- try
- {
- stream_.imbue(std::locale(""));
- }
- catch (const std::runtime_error& error)
- {
- g_warning("%s: %s", G_STRFUNC, error.what());
- }
-#else
- stream_.imbue(std::locale(""));
-#endif /* !GLIBMM_EXCEPTIONS_ENABLED */
-}
+{}
ustring::FormatStream::~FormatStream()
{}
diff --git a/glib/glibmm/ustring.h b/glib/glibmm/ustring.h
index 88c8bce0..04a4a14b 100644
--- a/glib/glibmm/ustring.h
+++ b/glib/glibmm/ustring.h
@@ -189,6 +189,18 @@ gunichar get_unichar_from_std_iterator(std::string::const_iterator pos) G_GNUC_P
* label->set_text(Glib::locale_to_utf8(output.str()));
* @endcode
*
+ * @par Formatted output and internationalization
+ * @par
+ * The methods ustring::compose() and ustring::format() provide a convenient
+ * and powerful alternative to string streams, as shown in the example below.
+ * Refer to the method documentation of compose() and format() for details.
+ * @code
+ * using Glib::ustring;
+ *
+ * ustring message = ustring::compose("%1 is lower than 0x%2.",
+ * 12, ustring::format(std::hex, 16));
+ * @endcode
+ *
* @par Implementation notes
* @par
* Glib::ustring does not inherit from std::string, because std::string was
@@ -670,14 +682,27 @@ public:
/*! Format the argument to its string representation.
* Applies the arguments in order to an std::wostringstream and returns the
* resulting string. I/O manipulators may also be used as arguments. This
- * greatly simplifies the common task of converting a number to a string:
+ * greatly simplifies the common task of converting a number to a string, as
+ * demonstrated by the example below. The format() methods can also be used
+ * in conjunction with compose() to facilitate localization of user-visible
+ * messages.
+ * @code
+ * using Glib::ustring;
+ * double value = 22.0 / 7.0;
+ * ustring text = ustring::format(std::fixed, std::setprecision(2), value);
+ * @endcode
+ * @note The use of a wide character stream in the implementation of format()
+ * is almost completely transparent. However, one of the instances where the
+ * use of wide streams becomes visible is when the std::setfill() stream
+ * manipulator is used. In order for std::setfill() to work the argument
+ * must be of type <tt>wchar_t</tt>. This can be achieved by using the
+ * <tt>L</tt> prefix with a character literal, as shown in the example.
* @code
* using Glib::ustring;
- * const double value = 1.23;
- * const ustring text = ustring::format(std::setprecision(2), value);
+ * // Insert leading zeroes to fill in at least six digits
+ * ustring text = ustring::format(std::setfill(L'0'), std::setw(6), 123);
* @endcode
- * ustring::format() can be used in conjunction with ustring::compose()
- * to produce internationalized messages for display to the user.
+ *
* @param a1 A streamable value or an I/O manipulator.
* @return The string representation of the argument stream.
* @throw Glib::ConvertError
@@ -696,17 +721,29 @@ public:
template <class T1, class T2, class T3, class T4>
static inline
- ustring format(const T1& a1, const T2& a2, const T3& a3, const T1& a4);
+ ustring format(const T1& a1, const T2& a2, const T3& a3, const T4& a4);
template <class T1, class T2, class T3, class T4, class T5>
static inline
ustring format(const T1& a1, const T2& a2, const T3& a3,
- const T1& a4, const T2& a5);
+ const T4& a4, const T5& a5);
template <class T1, class T2, class T3, class T4, class T5, class T6>
static inline
ustring format(const T1& a1, const T2& a2, const T3& a3,
- const T1& a4, const T2& a5, const T3& a6);
+ const T4& a4, const T5& a5, const T6& a6);
+
+ template <class T1, class T2, class T3, class T4,
+ class T5, class T6, class T7>
+ static inline
+ ustring format(const T1& a1, const T2& a2, const T3& a3, const T4& a4,
+ const T5& a5, const T6& a6, const T7& a7);
+
+ template <class T1, class T2, class T3, class T4,
+ class T5, class T6, class T7, class T8>
+ static inline
+ ustring format(const T1& a1, const T2& a2, const T3& a3, const T4& a4,
+ const T5& a5, const T6& a6, const T7& a7, const T8& a8);
//! @}
private:
@@ -1061,7 +1098,7 @@ ustring ustring::format(const T1& a1, const T2& a2, const T3& a3)
template <class T1, class T2, class T3, class T4>
inline // static
-ustring ustring::format(const T1& a1, const T2& a2, const T3& a3, const T1& a4)
+ustring ustring::format(const T1& a1, const T2& a2, const T3& a3, const T4& a4)
{
ustring::FormatStream buf;
buf.stream(a1);
@@ -1074,7 +1111,7 @@ ustring ustring::format(const T1& a1, const T2& a2, const T3& a3, const T1& a4)
template <class T1, class T2, class T3, class T4, class T5>
inline // static
ustring ustring::format(const T1& a1, const T2& a2, const T3& a3,
- const T1& a4, const T2& a5)
+ const T4& a4, const T5& a5)
{
ustring::FormatStream buf;
buf.stream(a1);
@@ -1088,7 +1125,7 @@ ustring ustring::format(const T1& a1, const T2& a2, const T3& a3,
template <class T1, class T2, class T3, class T4, class T5, class T6>
inline // static
ustring ustring::format(const T1& a1, const T2& a2, const T3& a3,
- const T1& a4, const T2& a5, const T3& a6)
+ const T4& a4, const T5& a5, const T6& a6)
{
ustring::FormatStream buf;
buf.stream(a1);
@@ -1100,16 +1137,55 @@ ustring ustring::format(const T1& a1, const T2& a2, const T3& a3,
return buf.to_string();
}
+template <class T1, class T2, class T3, class T4,
+ class T5, class T6, class T7>
+inline // static
+ustring ustring::format(const T1& a1, const T2& a2, const T3& a3, const T4& a4,
+ const T5& a5, const T6& a6, const T7& a7)
+{
+ ustring::FormatStream buf;
+ buf.stream(a1);
+ buf.stream(a2);
+ buf.stream(a3);
+ buf.stream(a4);
+ buf.stream(a5);
+ buf.stream(a6);
+ buf.stream(a7);
+ return buf.to_string();
+}
+
+template <class T1, class T2, class T3, class T4,
+ class T5, class T6, class T7, class T8>
+inline // static
+ustring ustring::format(const T1& a1, const T2& a2, const T3& a3, const T4& a4,
+ const T5& a5, const T6& a6, const T7& a7, const T8& a8)
+{
+ ustring::FormatStream buf;
+ buf.stream(a1);
+ buf.stream(a2);
+ buf.stream(a3);
+ buf.stream(a4);
+ buf.stream(a5);
+ buf.stream(a6);
+ buf.stream(a7);
+ buf.stream(a8);
+ return buf.to_string();
+}
+
template <class T>
class ustring::Stringify
{
private:
ustring string_;
+ // noncopyable
+ Stringify(const ustring::Stringify<T>&);
+ Stringify<T>& operator=(const ustring::Stringify<T>&);
+
public:
- explicit Stringify(const T& arg) : string_ (ustring::format(arg)) {}
- explicit Stringify(const char* arg) : string_ (arg) {}
- const ustring* ptr() const { return &string_; }
+ explicit inline Stringify(const T& arg) : string_ (ustring::format(arg)) {}
+ explicit inline Stringify(const char* arg) : string_ (arg) {}
+ inline const ustring* ptr() const { return &string_; }
};
template <>
@@ -1118,9 +1194,13 @@ class ustring::Stringify<ustring>
private:
const ustring& string_;
+ // noncopyable
+ Stringify(const ustring::Stringify<ustring>&);
+ Stringify<ustring>& operator=(const ustring::Stringify<ustring>&);
+
public:
- explicit Stringify(const ustring& arg) : string_ (arg) {}
- const ustring* ptr() const { return &string_; }
+ explicit inline Stringify(const ustring& arg) : string_ (arg) {}
+ inline const ustring* ptr() const { return &string_; }
};
template <class T1>
@@ -1130,7 +1210,7 @@ ustring ustring::compose(const ustring& fmt, const T1& a1)
const ustring::Stringify<T1> s1 (a1);
const ustring *const argv[] = { s1.ptr() };
- return compose_argv(fmt, G_N_ELEMENTS(argv), argv);
+ return ustring::compose_argv(fmt, G_N_ELEMENTS(argv), argv);
}
template <class T1, class T2>
@@ -1141,7 +1221,7 @@ ustring ustring::compose(const ustring& fmt, const T1& a1, const T2& a2)
const ustring::Stringify<T2> s2 (a2);
const ustring *const argv[] = { s1.ptr(), s2.ptr() };
- return compose_argv(fmt, G_N_ELEMENTS(argv), argv);
+ return ustring::compose_argv(fmt, G_N_ELEMENTS(argv), argv);
}
template <class T1, class T2, class T3>
@@ -1154,7 +1234,7 @@ ustring ustring::compose(const ustring& fmt,
const ustring::Stringify<T3> s3 (a3);
const ustring *const argv[] = { s1.ptr(), s2.ptr(), s3.ptr() };
- return compose_argv(fmt, G_N_ELEMENTS(argv), argv);
+ return ustring::compose_argv(fmt, G_N_ELEMENTS(argv), argv);
}
template <class T1, class T2, class T3, class T4>
@@ -1168,7 +1248,7 @@ ustring ustring::compose(const ustring& fmt,
const ustring::Stringify<T4> s4 (a4);
const ustring *const argv[] = { s1.ptr(), s2.ptr(), s3.ptr(), s4.ptr() };
- return compose_argv(fmt, G_N_ELEMENTS(argv), argv);
+ return ustring::compose_argv(fmt, G_N_ELEMENTS(argv), argv);
}
template <class T1, class T2, class T3, class T4, class T5>
@@ -1184,7 +1264,7 @@ ustring ustring::compose(const ustring& fmt,
const ustring::Stringify<T5> s5 (a5);
const ustring *const argv[] = { s1.ptr(), s2.ptr(), s3.ptr(), s4.ptr(), s5.ptr() };
- return compose_argv(fmt, G_N_ELEMENTS(argv), argv);
+ return ustring::compose_argv(fmt, G_N_ELEMENTS(argv), argv);
}
template <class T1, class T2, class T3, class T4, class T5, class T6>
@@ -1202,7 +1282,7 @@ ustring ustring::compose(const ustring& fmt,
const ustring *const argv[] = { s1.ptr(), s2.ptr(), s3.ptr(), s4.ptr(),
s5.ptr(), s6.ptr() };
- return compose_argv(fmt, G_N_ELEMENTS(argv), argv);
+ return ustring::compose_argv(fmt, G_N_ELEMENTS(argv), argv);
}
template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
@@ -1221,7 +1301,7 @@ ustring ustring::compose(const ustring& fmt,
const ustring *const argv[] = { s1.ptr(), s2.ptr(), s3.ptr(), s4.ptr(),
s5.ptr(), s6.ptr(), s7.ptr() };
- return compose_argv(fmt, G_N_ELEMENTS(argv), argv);
+ return ustring::compose_argv(fmt, G_N_ELEMENTS(argv), argv);
}
template <class T1, class T2, class T3, class T4,
@@ -1243,7 +1323,7 @@ ustring ustring::compose(const ustring& fmt,
const ustring *const argv[] = { s1.ptr(), s2.ptr(), s3.ptr(), s4.ptr(),
s5.ptr(), s6.ptr(), s7.ptr(), s8.ptr() };
- return compose_argv(fmt, G_N_ELEMENTS(argv), argv);
+ return ustring::compose_argv(fmt, G_N_ELEMENTS(argv), argv);
}
template <class T1, class T2, class T3, class T4, class T5,
@@ -1266,7 +1346,7 @@ ustring ustring::compose(const ustring& fmt,
const ustring *const argv[] = { s1.ptr(), s2.ptr(), s3.ptr(), s4.ptr(),
s5.ptr(), s6.ptr(), s7.ptr(), s8.ptr(), s9.ptr() };
- return compose_argv(fmt, G_N_ELEMENTS(argv), argv);
+ return ustring::compose_argv(fmt, G_N_ELEMENTS(argv), argv);
}
#endif /* DOXYGEN_SHOULD_SKIP_THIS */