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); |       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: | public: | ||||||
|   // constructors and destructor |   // constructors and destructor | ||||||
|     // ctor for an empty string |     // ctor for an empty string | ||||||
|   wxString() {} |   wxString() {} | ||||||
|  |  | ||||||
|     // copy ctor |     // 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) { } |   wxString(const wxString& stringSrc) : m_impl(stringSrc.m_impl) { } | ||||||
|  |  | ||||||
|     // string containing nRepeat copies of ch |     // string containing nRepeat copies of ch | ||||||
| @@ -917,17 +932,50 @@ public: | |||||||
|       : m_impl(str.Mid(0, nLength).m_impl) {} |       : m_impl(str.Mid(0, nLength).m_impl) {} | ||||||
|  |  | ||||||
|   // even if we're not built with wxUSE_STL == 1 it is very convenient to allow |   // 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 |   // implicit conversions from std::string to wxString and vice verse as this | ||||||
|   // the same strings in non-GUI and GUI code, however we don't want to |   // allows to use the same strings in non-GUI and GUI code, however we don't | ||||||
|   // unconditionally add this ctor as it would make wx lib dependent on |   // 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 |   // 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 |   // client code to define this wxUSE_STD_STRING symbol if they need it | ||||||
| #if wxUSE_STD_STRING && !wxUSE_STL_BASED_WXSTRING | #if wxUSE_STD_STRING | ||||||
|   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_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 |   // first valid index position | ||||||
|   const_iterator begin() const { return const_iterator(m_impl.begin()); } |   const_iterator begin() const { return const_iterator(m_impl.begin()); } | ||||||
| @@ -984,7 +1032,7 @@ public: | |||||||
|   { |   { | ||||||
|     size_t pos, len; |     size_t pos, len; | ||||||
|     PosLenToImpl(nStart, nLen, &pos, &len); |     PosLenToImpl(nStart, nLen, &pos, &len); | ||||||
|     return m_impl.substr(pos, len); |     return FromImpl(m_impl.substr(pos, len)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // generic attributes & operations |   // generic attributes & operations | ||||||
|   | |||||||
| @@ -61,17 +61,20 @@ extern WXDLLIMPEXP_DATA_BASE(const wxStringCharType*) wxEmptyStringImpl; | |||||||
| #include <string> | #include <string> | ||||||
| #include "wx/afterstd.h" | #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 | #if wxUSE_UNICODE_WCHAR | ||||||
|     #ifdef HAVE_STD_WSTRING |     typedef wxStdWideString wxStdString; | ||||||
|         typedef std::wstring wxStdString; |  | ||||||
|     #else |  | ||||||
|         typedef std::basic_string<wxStringCharType> wxStdString; |  | ||||||
|     #endif |  | ||||||
| #else | #else | ||||||
|     typedef std::string wxStdString; |     typedef std::string wxStdString; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #endif // need <string> | #endif // wxUSE_STL_BASED_WXSTRING || wxUSE_STD_STRING | ||||||
|  |  | ||||||
|  |  | ||||||
| #if wxUSE_STL_BASED_WXSTRING | #if wxUSE_STL_BASED_WXSTRING | ||||||
|  |  | ||||||
| @@ -321,6 +324,17 @@ public: | |||||||
|     // take everything between start and end |     // take everything between start and end | ||||||
|   wxStringImpl(const_iterator start, const_iterator 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! |     // dtor is not virtual, this class must not be inherited from! | ||||||
|   ~wxStringImpl() |   ~wxStringImpl() | ||||||
|   { |   { | ||||||
|   | |||||||
| @@ -46,6 +46,9 @@ private: | |||||||
|         CPPUNIT_TEST( StdResize ); |         CPPUNIT_TEST( StdResize ); | ||||||
|         CPPUNIT_TEST( StdRiter ); |         CPPUNIT_TEST( StdRiter ); | ||||||
|         CPPUNIT_TEST( StdSubstr ); |         CPPUNIT_TEST( StdSubstr ); | ||||||
|  | #if wxUSE_STD_STRING | ||||||
|  |         CPPUNIT_TEST( StdConversion ); | ||||||
|  | #endif | ||||||
|     CPPUNIT_TEST_SUITE_END(); |     CPPUNIT_TEST_SUITE_END(); | ||||||
|  |  | ||||||
|     void StdConstructors(); |     void StdConstructors(); | ||||||
| @@ -62,6 +65,9 @@ private: | |||||||
|     void StdResize(); |     void StdResize(); | ||||||
|     void StdRiter(); |     void StdRiter(); | ||||||
|     void StdSubstr(); |     void StdSubstr(); | ||||||
|  | #if wxUSE_STD_STRING | ||||||
|  |     void StdConversion(); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|     DECLARE_NO_COPY_CLASS(StdStringTestCase) |     DECLARE_NO_COPY_CLASS(StdStringTestCase) | ||||||
| }; | }; | ||||||
| @@ -514,3 +520,29 @@ void StdStringTestCase::StdSubstr() | |||||||
|     CPPUNIT_ASSERT( s1.substr( 17, 30 ) == _T("") ); |     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