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:
Václav Slavík
2007-04-17 15:32:05 +00:00
parent 1e510b1e2d
commit 59953bf4ba
3 changed files with 112 additions and 18 deletions

View 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

View File

@@ -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()
{

View 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