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"
|
||||
|
||||
#if wxUSE_UNICODE_WCHAR
|
||||
#ifdef HAVE_STD_WSTRING
|
||||
typedef std::wstring wxStdString;
|
||||
typedef std::wstring wxStdWideString;
|
||||
#else
|
||||
typedef std::basic_string<wxStringCharType> wxStdString;
|
||||
typedef std::basic_string<wchar_t> wxStdWideString;
|
||||
#endif
|
||||
|
||||
#if wxUSE_UNICODE_WCHAR
|
||||
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