From 59953bf4ba167311fb0cd2c2c0f3d5d0475b98c8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Tue, 17 Apr 2007 15:32:05 +0000 Subject: [PATCH] added conversion to and from std::string and std::wstring (if wxUSE_STD_STRING) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45519 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/string.h | 72 ++++++++++++++++++++++++++++++------ include/wx/stringimpl.h | 26 ++++++++++--- tests/strings/stdstrings.cpp | 32 ++++++++++++++++ 3 files changed, 112 insertions(+), 18 deletions(-) diff --git a/include/wx/string.h b/include/wx/string.h index 72873615bc..2c26c1536c 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -833,15 +833,30 @@ private: return const_iterator(data.m_str->begin() + data.m_offset); } + // in UTF-8 STL build, creation from std::string requires conversion under + // non-UTF8 locales, so we can't have and use wxString(wxStringImpl) ctor; + // instead we define dummy type that lets us have wxString ctor for creation + // from wxStringImpl that couldn't be used by user code (in all other builds, + // "standard" ctors can be used): +#if wxUSE_UNICODE_UTF8 && wxUSE_STL_BASED_WXSTRING + struct CtorFromStringImplTag {}; + + wxString(CtorFromStringImplTag* WXUNUSED(dummy), const wxStringImpl& src) + : m_impl(src) {} + + static wxString FromImpl(const wxStringImpl& src) + { return wxString((CtorFromStringImplTag*)NULL, src); } +#else + wxString(const wxStringImpl& src) : m_impl(src) { } + static wxString FromImpl(const wxStringImpl& src) { return wxString(src); } +#endif + public: // constructors and destructor // ctor for an empty string wxString() {} // copy ctor - // FIXME-UTF8: this one needs to do UTF-8 conversion in UTF-8 build! - wxString(const wxStringImpl& stringSrc) : m_impl(stringSrc) { } - wxString(const wxString& stringSrc) : m_impl(stringSrc.m_impl) { } // string containing nRepeat copies of ch @@ -917,17 +932,50 @@ public: : m_impl(str.Mid(0, nLength).m_impl) {} // even if we're not built with wxUSE_STL == 1 it is very convenient to allow - // implicit conversions from std::string to wxString as this allows to use - // the same strings in non-GUI and GUI code, however we don't want to - // unconditionally add this ctor as it would make wx lib dependent on + // implicit conversions from std::string to wxString and vice verse as this + // allows to use the same strings in non-GUI and GUI code, however we don't + // want to unconditionally add this ctor as it would make wx lib dependent on // libstdc++ on some Linux versions which is bad, so instead we ask the // client code to define this wxUSE_STD_STRING symbol if they need it -#if wxUSE_STD_STRING && !wxUSE_STL_BASED_WXSTRING - wxString(const wxStdString& s) - // FIXME-UTF8: this one needs to do UTF-8 conversion in UTF-8 build! - : m_impl(s.c_str()) { } // FIXME-UTF8: this is broken for embedded 0s -#endif // wxUSE_STD_STRING && !wxUSE_STL_BASED_WXSTRING +#if wxUSE_STD_STRING + + #if wxUSE_UNICODE_WCHAR + wxString(const wxStdWideString& str) : m_impl(str) {} + #else // UTF-8 or ANSI + wxString(const wxStdWideString& str) + { assign(str.c_str(), str.length()); } + #endif + + #if !wxUSE_UNICODE // ANSI build + // FIXME-UTF8: do this in UTF8 build #if wxUSE_UTF8_LOCALE_ONLY, too + wxString(const std::string& str) : m_impl(str) {} + #else // Unicode + wxString(const std::string& str) + { assign(str.c_str(), str.length()); } + #endif + + #if wxUSE_UNICODE_WCHAR && wxUSE_STL_BASED_WXSTRING + // wxStringImpl is std::string in the encoding we want + operator const wxStdWideString&() const { return m_impl; } + #else + // wxStringImpl is either not std::string or needs conversion + operator wxStdWideString() const + // FIXME-UTF8: broken for embedded NULs + { return wxStdWideString(wc_str()); } + #endif + + #if !wxUSE_UNICODE && wxUSE_STL_BASED_WXSTRING + // FIXME-UTF8: do this in UTF8 build #if wxUSE_UTF8_LOCALE_ONLY, too + // wxStringImpl is std::string in the encoding we want + operator const std::string&() const { return m_impl; } + #else + // wxStringImpl is either not std::string or needs conversion + operator std::string() const + // FIXME-UTF8: broken for embedded NULs + { return std::string(mb_str()); } + #endif +#endif // wxUSE_STD_STRING // first valid index position const_iterator begin() const { return const_iterator(m_impl.begin()); } @@ -984,7 +1032,7 @@ public: { size_t pos, len; PosLenToImpl(nStart, nLen, &pos, &len); - return m_impl.substr(pos, len); + return FromImpl(m_impl.substr(pos, len)); } // generic attributes & operations diff --git a/include/wx/stringimpl.h b/include/wx/stringimpl.h index 0a3f45bb52..1b3f172c94 100644 --- a/include/wx/stringimpl.h +++ b/include/wx/stringimpl.h @@ -61,17 +61,20 @@ extern WXDLLIMPEXP_DATA_BASE(const wxStringCharType*) wxEmptyStringImpl; #include #include "wx/afterstd.h" +#ifdef HAVE_STD_WSTRING + typedef std::wstring wxStdWideString; +#else + typedef std::basic_string wxStdWideString; +#endif + #if wxUSE_UNICODE_WCHAR - #ifdef HAVE_STD_WSTRING - typedef std::wstring wxStdString; - #else - typedef std::basic_string wxStdString; - #endif + typedef wxStdWideString wxStdString; #else typedef std::string wxStdString; #endif -#endif // need +#endif // wxUSE_STL_BASED_WXSTRING || wxUSE_STD_STRING + #if wxUSE_STL_BASED_WXSTRING @@ -321,6 +324,17 @@ public: // take everything between start and end wxStringImpl(const_iterator start, const_iterator end); + + // ctor from and conversion to std::string +#if wxUSE_STD_STRING + wxStringImpl(const wxStdString& impl) + { InitWith(impl.c_str(), 0, impl.length()); } + + operator wxStdString() const + { return wxStdString(c_str(), length()); } +#endif + + // dtor is not virtual, this class must not be inherited from! ~wxStringImpl() { diff --git a/tests/strings/stdstrings.cpp b/tests/strings/stdstrings.cpp index 6f5506f47a..9cb81dffe6 100644 --- a/tests/strings/stdstrings.cpp +++ b/tests/strings/stdstrings.cpp @@ -46,6 +46,9 @@ private: CPPUNIT_TEST( StdResize ); CPPUNIT_TEST( StdRiter ); CPPUNIT_TEST( StdSubstr ); +#if wxUSE_STD_STRING + CPPUNIT_TEST( StdConversion ); +#endif CPPUNIT_TEST_SUITE_END(); void StdConstructors(); @@ -62,6 +65,9 @@ private: void StdResize(); void StdRiter(); void StdSubstr(); +#if wxUSE_STD_STRING + void StdConversion(); +#endif DECLARE_NO_COPY_CLASS(StdStringTestCase) }; @@ -514,3 +520,29 @@ void StdStringTestCase::StdSubstr() CPPUNIT_ASSERT( s1.substr( 17, 30 ) == _T("") ); } +#if wxUSE_STD_STRING +void StdStringTestCase::StdConversion() +{ + std::string strStd("std::string value"); + wxStdWideString strStdWide(L"std::wstring value"); + + wxString s1(strStd); + CPPUNIT_ASSERT( s1 == "std::string value" ); + + wxString s2(strStdWide); + CPPUNIT_ASSERT( s2 == "std::wstring value" ); + + wxString s3; + s3 = strStd; + CPPUNIT_ASSERT( s3 == "std::string value" ); + s3 = strStdWide; + CPPUNIT_ASSERT( s3 == "std::wstring value" ); + + wxString s4("hello"); + std::string s5 = s4; + CPPUNIT_ASSERT( s5 == "hello" ); + + wxStdWideString s6 = s4; + CPPUNIT_ASSERT( s6 == "hello" ); +} +#endif // wxUSE_STD_STRING -- 2.47.2