+private:
+ // used to transform an expression built using c_str() (and hence of type
+ // wxCStrData) to an iterator into the string
+ static const_iterator CreateConstIterator(const wxCStrData& data)
+ {
+ return const_iterator(data.m_str,
+ (data.m_str->begin() + data.m_offset).impl());
+ }
+
+ // 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
+ #if !wxUSE_STL_BASED_WXSTRING
+ wxString(const wxStringImpl& src) : m_impl(src) { }
+ // else: already defined as wxString(wxStdString) below
+ #endif
+ static wxString FromImpl(const wxStringImpl& src) { return wxString(src); }
+#endif
+
+public:
+ // constructors and destructor
+ // ctor for an empty string
+ wxString() {}
+
+ // copy ctor
+ wxString(const wxString& stringSrc) : m_impl(stringSrc.m_impl) { }
+
+ // string containing nRepeat copies of ch
+ wxString(wxUniChar ch, size_t nRepeat = 1 )
+ { assign(nRepeat, ch); }
+ wxString(size_t nRepeat, wxUniChar ch)
+ { assign(nRepeat, ch); }
+ wxString(wxUniCharRef ch, size_t nRepeat = 1)
+ { assign(nRepeat, ch); }
+ wxString(size_t nRepeat, wxUniCharRef ch)
+ { assign(nRepeat, ch); }
+ wxString(char ch, size_t nRepeat = 1)
+ { assign(nRepeat, ch); }
+ wxString(size_t nRepeat, char ch)
+ { assign(nRepeat, ch); }
+ wxString(wchar_t ch, size_t nRepeat = 1)
+ { assign(nRepeat, ch); }
+ wxString(size_t nRepeat, wchar_t ch)
+ { assign(nRepeat, ch); }
+
+ // ctors from char* strings:
+ wxString(const char *psz)
+ : m_impl(ImplStr(psz)) {}
+ wxString(const char *psz, const wxMBConv& conv)
+ : m_impl(ImplStr(psz, conv)) {}
+ wxString(const char *psz, size_t nLength)
+ { assign(psz, nLength); }
+ wxString(const char *psz, const wxMBConv& conv, size_t nLength)
+ {
+ SubstrBufFromMB str(ImplStr(psz, nLength, conv));
+ m_impl.assign(str.data, str.len);
+ }
+
+ // and unsigned char*:
+ wxString(const unsigned char *psz)
+ : m_impl(ImplStr((const char*)psz)) {}
+ wxString(const unsigned char *psz, const wxMBConv& conv)
+ : m_impl(ImplStr((const char*)psz, conv)) {}
+ wxString(const unsigned char *psz, size_t nLength)
+ { assign((const char*)psz, nLength); }
+ wxString(const unsigned char *psz, const wxMBConv& conv, size_t nLength)
+ {
+ SubstrBufFromMB str(ImplStr((const char*)psz, nLength, conv));
+ m_impl.assign(str.data, str.len);
+ }
+
+ // ctors from wchar_t* strings:
+ wxString(const wchar_t *pwz)
+ : m_impl(ImplStr(pwz)) {}
+ wxString(const wchar_t *pwz, const wxMBConv& WXUNUSED(conv))
+ : m_impl(ImplStr(pwz)) {}
+ wxString(const wchar_t *pwz, size_t nLength)
+ { assign(pwz, nLength); }
+ wxString(const wchar_t *pwz, const wxMBConv& WXUNUSED(conv), size_t nLength)
+ { assign(pwz, nLength); }
+
+ wxString(const wxScopedCharBuffer& buf)
+ { assign(buf.data(), buf.length()); }
+ wxString(const wxScopedWCharBuffer& buf)
+ { assign(buf.data(), buf.length()); }
+
+ // NB: this version uses m_impl.c_str() to force making a copy of the
+ // string, so that "wxString(str.c_str())" idiom for passing strings
+ // between threads works
+ wxString(const wxCStrData& cstr)
+ : m_impl(cstr.AsString().m_impl.c_str()) { }
+
+ // as we provide both ctors with this signature for both char and unsigned
+ // char string, we need to provide one for wxCStrData to resolve ambiguity
+ wxString(const wxCStrData& cstr, size_t nLength)
+ : m_impl(cstr.AsString().Mid(0, nLength).m_impl) {}
+
+ // and because wxString is convertible to wxCStrData and const wxChar *
+ // we also need to provide this one
+ wxString(const wxString& str, size_t nLength)
+ { assign(str, nLength); }
+
+
+#if wxUSE_STRING_POS_CACHE
+ ~wxString()
+ {
+ // we need to invalidate our cache entry as another string could be
+ // recreated at the same address (unlikely, but still possible, with the
+ // heap-allocated strings but perfectly common with stack-allocated ones)
+ InvalidateCache();
+ }
+#endif // wxUSE_STRING_POS_CACHE
+
+ // even if we're not built with wxUSE_STD_STRING_CONV_IN_WXSTRING == 1 it is
+ // very convenient to allow 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
+ #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
+#endif // wxUSE_STD_STRING
+
+ // Also always provide explicit conversions to std::[w]string in any case,
+ // see below for the implicit ones.
+#if wxUSE_STD_STRING
+ // We can avoid a copy if we already use this string type internally,
+ // otherwise we create a copy on the fly:
+ #if wxUSE_UNICODE_WCHAR && wxUSE_STL_BASED_WXSTRING
+ #define wxStringToStdWstringRetType const wxStdWideString&
+ const wxStdWideString& ToStdWstring() const { return m_impl; }
+ #else
+ // wxStringImpl is either not std::string or needs conversion
+ #define wxStringToStdWstringRetType wxStdWideString
+ wxStdWideString ToStdWstring() const
+ {
+#if wxUSE_UNICODE_WCHAR
+ wxScopedWCharBuffer buf =
+ wxScopedWCharBuffer::CreateNonOwned(m_impl.c_str(), m_impl.length());
+#else // !wxUSE_UNICODE_WCHAR
+ wxScopedWCharBuffer buf(wc_str());
+#endif
+
+ return wxStdWideString(buf.data(), buf.length());
+ }
+ #endif
+
+ #if (!wxUSE_UNICODE || wxUSE_UTF8_LOCALE_ONLY) && wxUSE_STL_BASED_WXSTRING
+ // wxStringImpl is std::string in the encoding we want
+ #define wxStringToStdStringRetType const std::string&
+ const std::string& ToStdString() const { return m_impl; }
+ #else
+ // wxStringImpl is either not std::string or needs conversion
+ #define wxStringToStdStringRetType std::string
+ std::string ToStdString() const
+ {
+ wxScopedCharBuffer buf(mb_str());
+ return std::string(buf.data(), buf.length());
+ }
+ #endif
+
+#if wxUSE_STD_STRING_CONV_IN_WXSTRING
+ // Implicit conversions to std::[w]string are not provided by default as
+ // they conflict with the implicit conversions to "const char/wchar_t *"
+ // which we use for backwards compatibility but do provide them if
+ // explicitly requested.
+ operator wxStringToStdStringRetType() const { return ToStdString(); }
+ operator wxStringToStdWstringRetType() const { return ToStdWstring(); }
+#endif // wxUSE_STD_STRING_CONV_IN_WXSTRING
+
+#undef wxStringToStdStringRetType
+#undef wxStringToStdWstringRetType
+
+#endif // wxUSE_STD_STRING
+
+ wxString Clone() const
+ {
+ // make a deep copy of the string, i.e. the returned string will have
+ // ref count = 1 with refcounted implementation
+ return wxString::FromImpl(wxStringImpl(m_impl.c_str(), m_impl.length()));
+ }
+
+ // first valid index position
+ const_iterator begin() const { return const_iterator(this, m_impl.begin()); }
+ iterator begin() { return iterator(this, m_impl.begin()); }