+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()); }
+ // position one after the last valid one
+ const_iterator end() const { return const_iterator(this, m_impl.end()); }
+ iterator end() { return iterator(this, m_impl.end()); }
+
+ // first element of the reversed string
+ const_reverse_iterator rbegin() const
+ { return const_reverse_iterator(end()); }
+ reverse_iterator rbegin()
+ { return reverse_iterator(end()); }
+ // one beyond the end of the reversed string
+ const_reverse_iterator rend() const
+ { return const_reverse_iterator(begin()); }
+ reverse_iterator rend()
+ { return reverse_iterator(begin()); }
+
+ // std::string methods:
+#if wxUSE_UNICODE_UTF8
+ size_t length() const
+ {
+#if wxUSE_STRING_POS_CACHE
+ wxCACHE_PROFILE_FIELD_INC(lentot);
+
+ Cache::Element * const cache = GetCacheElement();
+
+ if ( cache->len == npos )
+ {
+ // it's probably not worth trying to be clever and using cache->pos
+ // here as it's probably 0 anyhow -- you usually call length() before
+ // starting to index the string
+ cache->len = end() - begin();
+ }
+ else
+ {
+ wxCACHE_PROFILE_FIELD_INC(lenhits);
+
+ wxSTRING_CACHE_ASSERT( (int)cache->len == end() - begin() );
+ }
+
+ return cache->len;
+#else // !wxUSE_STRING_POS_CACHE
+ return end() - begin();
+#endif // wxUSE_STRING_POS_CACHE/!wxUSE_STRING_POS_CACHE
+ }
+#else
+ size_t length() const { return m_impl.length(); }
+#endif
+
+ size_type size() const { return length(); }
+ size_type max_size() const { return npos; }