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