From e3ab69523b78d79752943ab6d044c334045a1e57 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 11 Apr 2010 11:08:49 +0000 Subject: [PATCH] Add wxString::ToStdString() and ToStdWstring(). These trivial helper functions are available in all builds (provided that wxUSE_STD_STRING is not explicitly set to non-default 0 value) unlike implicit conversions to std::[w]string which are only available when wxUSE_STL==1. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63938 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + include/wx/string.h | 32 +++++++++++++++++++++++++------- interface/wx/string.h | 34 ++++++++++++++++++++++++++++++++++ tests/strings/stdstrings.cpp | 13 ++++++++++--- 4 files changed, 70 insertions(+), 10 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index db31c5502c..233ce6f6e5 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -440,6 +440,7 @@ All: - Don't crash when input is empty in wxFileConfig ctor (Lukasz Michalski). - Correct wxSocket::Peek() to not block (Anders Larsen). - Added IEC and SI units support to GetHumanReadableSize() (Julien Weinzorn). +- Add convenient wxString::ToStd{String,Wstring}() helpers. Unix: diff --git a/include/wx/string.h b/include/wx/string.h index baf1de6bf9..5d207a6b7f 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -1341,14 +1341,18 @@ public: // Unlike ctor from std::string, we provide conversion to std::string only // if wxUSE_STL and not merely wxUSE_STD_STRING (which is on by default), - // because it conflicts with operator const char/wchar_t*: -#if wxUSE_STL + // because it conflicts with operator const char/wchar_t* but we still + // provide explicit conversions to std::[w]string for convenience in any case +#if wxUSE_STD_STRING + // We can avoid a copy if we already use this string type internally, + // otherwise we create a copy on the fly: #if wxUSE_UNICODE_WCHAR && wxUSE_STL_BASED_WXSTRING - // wxStringImpl is std::string in the encoding we want - operator const wxStdWideString&() const { return m_impl; } + #define wxStringToStdWstringRetType const wxStdWideString& + const wxStdWideString& ToStdWstring() const { return m_impl; } #else // wxStringImpl is either not std::string or needs conversion - operator wxStdWideString() const + #define wxStringToStdWstringRetType wxStdWideString + wxStdWideString ToStdWstring() const { wxScopedWCharBuffer buf(wc_str()); return wxStdWideString(buf.data(), buf.length()); @@ -1357,17 +1361,31 @@ public: #if (!wxUSE_UNICODE || wxUSE_UTF8_LOCALE_ONLY) && wxUSE_STL_BASED_WXSTRING // wxStringImpl is std::string in the encoding we want - operator const std::string&() const { return m_impl; } + #define wxStringToStdStringRetType const std::string& + const std::string& ToStdString() const { return m_impl; } #else // wxStringImpl is either not std::string or needs conversion - operator std::string() const + #define wxStringToStdStringRetType std::string + std::string ToStdString() const { wxScopedCharBuffer buf(mb_str()); return std::string(buf.data(), buf.length()); } #endif + +#if wxUSE_STL + // In wxUSE_STL case we also provide implicit conversions as there is no + // ambiguity with the const char/wchar_t* ones as they are disabled in this + // build (for consistency with std::basic_string<>) + operator wxStringToStdStringRetType() const { return ToStdString(); } + operator wxStringToStdWstringRetType() const { return ToStdWstring(); } #endif // wxUSE_STL +#undef wxStringToStdStringRetType +#undef wxStringToStdWstringRetType + +#endif // wxUSE_STD_STRING + wxString Clone() const { // make a deep copy of the string, i.e. the returned string will have diff --git a/interface/wx/string.h b/interface/wx/string.h index 65437943bd..dc82130d2a 100644 --- a/interface/wx/string.h +++ b/interface/wx/string.h @@ -181,11 +181,15 @@ public: /** Constructs a string from @a str using the using the current locale encoding to convert it to Unicode (wxConvLibc). + + @see ToStdString() */ wxString(const std::string& str); /** Constructs a string from @a str. + + @see ToStdWstring() */ wxString(const std::wstring& str); @@ -509,6 +513,36 @@ public: */ const wxCharBuffer ToAscii() const; + /** + Return the string as an std::string in current locale encoding. + + Note that if the conversion of (Unicode) string contents to the current + locale fails, the return string will be empty. Be sure to check for + this to avoid silent data loss. + + Instead of using this function it's also possible to write + @code + std::string s; + wxString wxs; + ... + s = std::string(wxs); + @endcode + but using ToStdString() may make the code more clear. + + @since 2.9.1 + */ + std::string ToStdString() const; + + /** + Return the string as an std::wstring. + + Unlike ToStdString(), there is no danger of data loss when using this + function. + + @since 2.9.1 + */ + std::wstring ToStdWstring() const; + /** Same as utf8_str(). */ diff --git a/tests/strings/stdstrings.cpp b/tests/strings/stdstrings.cpp index 294eb923d6..13f5e2728e 100644 --- a/tests/strings/stdstrings.cpp +++ b/tests/strings/stdstrings.cpp @@ -559,15 +559,22 @@ void StdStringTestCase::StdConversion() wxString s4("hello"); - // wxString -> std::string conversion is only available in wxUSE_STL case, - // because it conflicts with conversion to const char*/wchar_t*: + // notice that implicit wxString -> std::string conversion is only + // available in wxUSE_STL case, because it conflicts with conversion to + // const char*/wchar_t* #if wxUSE_STL std::string s5 = s4; +#else + std::string s5 = s4.ToStdString(); +#endif CPPUNIT_ASSERT_EQUAL( "hello", s5 ); +#if wxUSE_STL wxStdWideString s6 = s4; - CPPUNIT_ASSERT_EQUAL( "hello", s6 ); +#else + wxStdWideString s6 = s4.ToStdWstring(); #endif + CPPUNIT_ASSERT_EQUAL( "hello", s6 ); std::string s7(s4); CPPUNIT_ASSERT( s7 == "hello" ); -- 2.47.2