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
This commit is contained in:
		| @@ -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 | ||||
|   | ||||
| @@ -61,17 +61,20 @@ extern WXDLLIMPEXP_DATA_BASE(const wxStringCharType*) wxEmptyStringImpl; | ||||
| #include <string> | ||||
| #include "wx/afterstd.h" | ||||
|  | ||||
| #ifdef HAVE_STD_WSTRING | ||||
|     typedef std::wstring wxStdWideString; | ||||
| #else | ||||
|     typedef std::basic_string<wchar_t> wxStdWideString; | ||||
| #endif | ||||
|  | ||||
| #if wxUSE_UNICODE_WCHAR | ||||
|     #ifdef HAVE_STD_WSTRING | ||||
|         typedef std::wstring wxStdString; | ||||
|     #else | ||||
|         typedef std::basic_string<wxStringCharType> wxStdString; | ||||
|     #endif | ||||
|     typedef wxStdWideString wxStdString; | ||||
| #else | ||||
|     typedef std::string wxStdString; | ||||
| #endif | ||||
|  | ||||
| #endif // need <string> | ||||
| #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() | ||||
|   { | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user