]> git.saurik.com Git - wxWidgets.git/commitdiff
added conversion to and from std::string and std::wstring (if wxUSE_STD_STRING)
authorVáclav Slavík <vslavik@fastmail.fm>
Tue, 17 Apr 2007 15:32:05 +0000 (15:32 +0000)
committerVáclav Slavík <vslavik@fastmail.fm>
Tue, 17 Apr 2007 15:32:05 +0000 (15:32 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45519 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/string.h
include/wx/stringimpl.h
tests/strings/stdstrings.cpp

index 72873615bcf5f46fb87c9c6f7fddc44eec1035f7..2c26c1536c8fe966916bbb0f198b237d6a0f1c83 100644 (file)
@@ -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
index 0a3f45bb528450322c47b4cfb418c89a307e40ed..1b3f172c948bda220fa3bd0398a3f1196818a661 100644 (file)
@@ -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()
   {
index 6f5506f47afa2a720a18fb0f7de7dabbd0e0f9d8..9cb81dffe6e40e9641b46ff8f89644bc07b21c2a 100644 (file)
@@ -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