+ // this is an optimization: even though using mb_str(wxConvLibc) does the
+ // same thing (i.e. returns pointer to internal representation as locale is
+ // always an UTF-8 one) in wxUSE_UTF8_LOCALE_ONLY case, we can avoid the
+ // extra checks and the temporary buffer construction by providing a
+ // separate mb_str() overload
+#if wxUSE_UTF8_LOCALE_ONLY
+ const char* mb_str() const { return wx_str(); }
+ const wxScopedCharBuffer mb_str(const wxMBConv& conv) const
+ {
+ return AsCharBuf(conv);
+ }
+#else // !wxUSE_UTF8_LOCALE_ONLY
+ const wxScopedCharBuffer mb_str(const wxMBConv& conv = wxConvLibc) const
+ {
+ return AsCharBuf(conv);
+ }
+#endif // wxUSE_UTF8_LOCALE_ONLY/!wxUSE_UTF8_LOCALE_ONLY
+
+ const wxWX2MBbuf mbc_str() const { return mb_str(*wxConvCurrent); }
+
+#if wxUSE_UNICODE_WCHAR
+ const wchar_t* wc_str() const { return wx_str(); }
+#elif wxUSE_UNICODE_UTF8
+ const wxScopedWCharBuffer wc_str() const
+ { return AsWCharBuf(wxMBConvStrictUTF8()); }
+#endif
+ // for compatibility with !wxUSE_UNICODE version
+ const wxWX2WCbuf wc_str(const wxMBConv& WXUNUSED(conv)) const
+ { return wc_str(); }
+
+#if wxMBFILES
+ const wxScopedCharBuffer fn_str() const { return mb_str(wxConvFile); }
+#else // !wxMBFILES
+ const wxWX2WCbuf fn_str() const { return wc_str(); }
+#endif // wxMBFILES/!wxMBFILES
+
+#else // ANSI
+ const char* mb_str() const { return wx_str(); }
+
+ // for compatibility with wxUSE_UNICODE version
+ const char* mb_str(const wxMBConv& WXUNUSED(conv)) const { return wx_str(); }
+
+ const wxWX2MBbuf mbc_str() const { return mb_str(); }
+
+ const wxScopedWCharBuffer wc_str(const wxMBConv& conv = wxConvLibc) const
+ { return AsWCharBuf(conv); }
+
+ const wxScopedCharBuffer fn_str() const
+ { return wxConvFile.cWC2WX( wc_str( wxConvLibc ) ); }
+#endif // Unicode/ANSI
+
+#if wxUSE_UNICODE_UTF8
+ const wxScopedWCharBuffer t_str() const { return wc_str(); }
+#elif wxUSE_UNICODE_WCHAR
+ const wchar_t* t_str() const { return wx_str(); }
+#else
+ const char* t_str() const { return wx_str(); }
+#endif
+
+
+ // overloaded assignment
+ // from another wxString
+ wxString& operator=(const wxString& stringSrc)
+ {
+ if ( this != &stringSrc )
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ m_impl = stringSrc.m_impl;
+ }
+
+ return *this;
+ }
+
+ wxString& operator=(const wxCStrData& cstr)
+ { return *this = cstr.AsString(); }
+ // from a character
+ wxString& operator=(wxUniChar ch)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+#if wxUSE_UNICODE_UTF8
+ if ( !ch.IsAscii() )
+ m_impl = wxStringOperations::EncodeChar(ch);
+ else
+#endif // wxUSE_UNICODE_UTF8
+ m_impl = (wxStringCharType)ch;
+ return *this;
+ }
+
+ wxString& operator=(wxUniCharRef ch)
+ { return operator=((wxUniChar)ch); }
+ wxString& operator=(char ch)
+ { return operator=(wxUniChar(ch)); }
+ wxString& operator=(unsigned char ch)
+ { return operator=(wxUniChar(ch)); }
+ wxString& operator=(wchar_t ch)
+ { return operator=(wxUniChar(ch)); }
+ // from a C string - STL probably will crash on NULL,
+ // so we need to compensate in that case
+#if wxUSE_STL_BASED_WXSTRING
+ wxString& operator=(const char *psz)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ if ( psz )
+ m_impl = ImplStr(psz);
+ else
+ clear();
+
+ return *this;
+ }
+
+ wxString& operator=(const wchar_t *pwz)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ if ( pwz )
+ m_impl = ImplStr(pwz);
+ else
+ clear();
+
+ return *this;
+ }
+#else // !wxUSE_STL_BASED_WXSTRING
+ wxString& operator=(const char *psz)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ m_impl = ImplStr(psz);
+
+ return *this;
+ }
+
+ wxString& operator=(const wchar_t *pwz)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ m_impl = ImplStr(pwz);
+
+ return *this;
+ }
+#endif // wxUSE_STL_BASED_WXSTRING/!wxUSE_STL_BASED_WXSTRING
+
+ wxString& operator=(const unsigned char *psz)
+ { return operator=((const char*)psz); }
+
+ // from wxScopedWCharBuffer
+ wxString& operator=(const wxScopedWCharBuffer& s)
+ { return assign(s); }
+ // from wxScopedCharBuffer
+ wxString& operator=(const wxScopedCharBuffer& s)
+ { return assign(s); }
+
+ // string concatenation
+ // in place concatenation
+ /*
+ Concatenate and return the result. Note that the left to right
+ associativity of << allows to write things like "str << str1 << str2
+ << ..." (unlike with +=)
+ */
+ // string += string
+ wxString& operator<<(const wxString& s)
+ {
+#if WXWIN_COMPATIBILITY_2_8 && !wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8
+ wxASSERT_MSG( s.IsValid(),
+ wxT("did you forget to call UngetWriteBuf()?") );
+#endif
+
+ append(s);
+ return *this;
+ }
+ // string += C string
+ wxString& operator<<(const char *psz)
+ { append(psz); return *this; }
+ wxString& operator<<(const wchar_t *pwz)
+ { append(pwz); return *this; }
+ wxString& operator<<(const wxCStrData& psz)
+ { append(psz.AsString()); return *this; }
+ // string += char
+ wxString& operator<<(wxUniChar ch) { append(1, ch); return *this; }
+ wxString& operator<<(wxUniCharRef ch) { append(1, ch); return *this; }
+ wxString& operator<<(char ch) { append(1, ch); return *this; }
+ wxString& operator<<(unsigned char ch) { append(1, ch); return *this; }
+ wxString& operator<<(wchar_t ch) { append(1, ch); return *this; }
+
+ // string += buffer (i.e. from wxGetString)
+ wxString& operator<<(const wxScopedWCharBuffer& s)
+ { return append(s); }
+ wxString& operator<<(const wxScopedCharBuffer& s)
+ { return append(s); }
+
+ // string += C string
+ wxString& Append(const wxString& s)
+ {
+ // test for empty() to share the string if possible
+ if ( empty() )
+ *this = s;
+ else
+ append(s);
+ return *this;
+ }
+ wxString& Append(const char* psz)
+ { append(psz); return *this; }
+ wxString& Append(const wchar_t* pwz)
+ { append(pwz); return *this; }
+ wxString& Append(const wxCStrData& psz)
+ { append(psz); return *this; }
+ wxString& Append(const wxScopedCharBuffer& psz)
+ { append(psz); return *this; }
+ wxString& Append(const wxScopedWCharBuffer& psz)
+ { append(psz); return *this; }
+ wxString& Append(const char* psz, size_t nLen)
+ { append(psz, nLen); return *this; }
+ wxString& Append(const wchar_t* pwz, size_t nLen)
+ { append(pwz, nLen); return *this; }
+ wxString& Append(const wxCStrData& psz, size_t nLen)
+ { append(psz, nLen); return *this; }
+ wxString& Append(const wxScopedCharBuffer& psz, size_t nLen)
+ { append(psz, nLen); return *this; }
+ wxString& Append(const wxScopedWCharBuffer& psz, size_t nLen)
+ { append(psz, nLen); return *this; }
+ // append count copies of given character
+ wxString& Append(wxUniChar ch, size_t count = 1u)
+ { append(count, ch); return *this; }
+ wxString& Append(wxUniCharRef ch, size_t count = 1u)
+ { append(count, ch); return *this; }
+ wxString& Append(char ch, size_t count = 1u)
+ { append(count, ch); return *this; }
+ wxString& Append(unsigned char ch, size_t count = 1u)
+ { append(count, ch); return *this; }
+ wxString& Append(wchar_t ch, size_t count = 1u)
+ { append(count, ch); return *this; }
+
+ // prepend a string, return the string itself
+ wxString& Prepend(const wxString& str)
+ { *this = str + *this; return *this; }
+
+ // non-destructive concatenation
+ // two strings
+ friend wxString WXDLLIMPEXP_BASE operator+(const wxString& string1,
+ const wxString& string2);
+ // string with a single char
+ friend wxString WXDLLIMPEXP_BASE operator+(const wxString& string, wxUniChar ch);
+ // char with a string
+ friend wxString WXDLLIMPEXP_BASE operator+(wxUniChar ch, const wxString& string);
+ // string with C string
+ friend wxString WXDLLIMPEXP_BASE operator+(const wxString& string,
+ const char *psz);
+ friend wxString WXDLLIMPEXP_BASE operator+(const wxString& string,
+ const wchar_t *pwz);
+ // C string with string
+ friend wxString WXDLLIMPEXP_BASE operator+(const char *psz,
+ const wxString& string);
+ friend wxString WXDLLIMPEXP_BASE operator+(const wchar_t *pwz,
+ const wxString& string);
+
+ // stream-like functions
+ // insert an int into string
+ wxString& operator<<(int i)
+ { return (*this) << Format(wxT("%d"), i); }
+ // insert an unsigned int into string
+ wxString& operator<<(unsigned int ui)
+ { return (*this) << Format(wxT("%u"), ui); }
+ // insert a long into string
+ wxString& operator<<(long l)
+ { return (*this) << Format(wxT("%ld"), l); }
+ // insert an unsigned long into string
+ wxString& operator<<(unsigned long ul)
+ { return (*this) << Format(wxT("%lu"), ul); }
+#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
+ // insert a long long if they exist and aren't longs
+ wxString& operator<<(wxLongLong_t ll)
+ {
+ return (*this) << Format("%" wxLongLongFmtSpec "d", ll);
+ }
+ // insert an unsigned long long
+ wxString& operator<<(wxULongLong_t ull)
+ {
+ return (*this) << Format("%" wxLongLongFmtSpec "u" , ull);
+ }
+#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
+ // insert a float into string
+ wxString& operator<<(float f)
+ { return (*this) << Format(wxT("%f"), f); }
+ // insert a double into string
+ wxString& operator<<(double d)
+ { return (*this) << Format(wxT("%g"), d); }
+
+ // string comparison
+ // case-sensitive comparison (returns a value < 0, = 0 or > 0)
+ int Cmp(const char *psz) const
+ { return compare(psz); }
+ int Cmp(const wchar_t *pwz) const
+ { return compare(pwz); }
+ int Cmp(const wxString& s) const
+ { return compare(s); }
+ int Cmp(const wxCStrData& s) const
+ { return compare(s); }
+ int Cmp(const wxScopedCharBuffer& s) const
+ { return compare(s); }
+ int Cmp(const wxScopedWCharBuffer& s) const
+ { return compare(s); }
+ // same as Cmp() but not case-sensitive
+ int CmpNoCase(const wxString& s) const;
+
+ // test for the string equality, either considering case or not
+ // (if compareWithCase then the case matters)
+ bool IsSameAs(const wxString& str, bool compareWithCase = true) const
+ {
+#if !wxUSE_UNICODE_UTF8
+ // in UTF-8 build, length() is O(n) and doing this would be _slower_
+ if ( length() != str.length() )
+ return false;
+#endif
+ return (compareWithCase ? Cmp(str) : CmpNoCase(str)) == 0;
+ }
+ bool IsSameAs(const char *str, bool compareWithCase = true) const
+ { return (compareWithCase ? Cmp(str) : CmpNoCase(str)) == 0; }
+ bool IsSameAs(const wchar_t *str, bool compareWithCase = true) const
+ { return (compareWithCase ? Cmp(str) : CmpNoCase(str)) == 0; }
+
+ bool IsSameAs(const wxCStrData& str, bool compareWithCase = true) const
+ { return IsSameAs(str.AsString(), compareWithCase); }
+ bool IsSameAs(const wxScopedCharBuffer& str, bool compareWithCase = true) const
+ { return IsSameAs(str.data(), compareWithCase); }
+ bool IsSameAs(const wxScopedWCharBuffer& str, bool compareWithCase = true) const
+ { return IsSameAs(str.data(), compareWithCase); }
+ // comparison with a single character: returns true if equal
+ bool IsSameAs(wxUniChar c, bool compareWithCase = true) const;
+ // FIXME-UTF8: remove these overloads
+ bool IsSameAs(wxUniCharRef c, bool compareWithCase = true) const
+ { return IsSameAs(wxUniChar(c), compareWithCase); }
+ bool IsSameAs(char c, bool compareWithCase = true) const
+ { return IsSameAs(wxUniChar(c), compareWithCase); }
+ bool IsSameAs(unsigned char c, bool compareWithCase = true) const
+ { return IsSameAs(wxUniChar(c), compareWithCase); }
+ bool IsSameAs(wchar_t c, bool compareWithCase = true) const
+ { return IsSameAs(wxUniChar(c), compareWithCase); }
+ bool IsSameAs(int c, bool compareWithCase = true) const
+ { return IsSameAs(wxUniChar(c), compareWithCase); }
+
+ // simple sub-string extraction
+ // return substring starting at nFirst of length nCount (or till the end
+ // if nCount = default value)
+ wxString Mid(size_t nFirst, size_t nCount = npos) const;
+
+ // operator version of Mid()
+ wxString operator()(size_t start, size_t len) const
+ { return Mid(start, len); }
+
+ // check if the string starts with the given prefix and return the rest
+ // of the string in the provided pointer if it is not NULL; otherwise
+ // return false
+ bool StartsWith(const wxString& prefix, wxString *rest = NULL) const;
+ // check if the string ends with the given suffix and return the
+ // beginning of the string before the suffix in the provided pointer if
+ // it is not NULL; otherwise return false
+ bool EndsWith(const wxString& suffix, wxString *rest = NULL) const;
+
+ // get first nCount characters
+ wxString Left(size_t nCount) const;
+ // get last nCount characters
+ wxString Right(size_t nCount) const;
+ // get all characters before the first occurrence of ch
+ // (returns the whole string if ch not found) and also put everything
+ // following the first occurrence of ch into rest if it's non-NULL
+ wxString BeforeFirst(wxUniChar ch, wxString *rest = NULL) const;
+ // get all characters before the last occurrence of ch
+ // (returns empty string if ch not found) and also put everything
+ // following the last occurrence of ch into rest if it's non-NULL
+ wxString BeforeLast(wxUniChar ch, wxString *rest = NULL) const;
+ // get all characters after the first occurrence of ch
+ // (returns empty string if ch not found)
+ wxString AfterFirst(wxUniChar ch) const;
+ // get all characters after the last occurrence of ch
+ // (returns the whole string if ch not found)
+ wxString AfterLast(wxUniChar ch) const;
+
+ // for compatibility only, use more explicitly named functions above
+ wxString Before(wxUniChar ch) const { return BeforeLast(ch); }
+ wxString After(wxUniChar ch) const { return AfterFirst(ch); }
+
+ // case conversion
+ // convert to upper case in place, return the string itself
+ wxString& MakeUpper();
+ // convert to upper case, return the copy of the string
+ wxString Upper() const { return wxString(*this).MakeUpper(); }
+ // convert to lower case in place, return the string itself
+ wxString& MakeLower();
+ // convert to lower case, return the copy of the string
+ wxString Lower() const { return wxString(*this).MakeLower(); }
+ // convert the first character to the upper case and the rest to the
+ // lower one, return the modified string itself
+ wxString& MakeCapitalized();
+ // convert the first character to the upper case and the rest to the
+ // lower one, return the copy of the string
+ wxString Capitalize() const { return wxString(*this).MakeCapitalized(); }
+
+ // trimming/padding whitespace (either side) and truncating
+ // remove spaces from left or from right (default) side
+ wxString& Trim(bool bFromRight = true);
+ // add nCount copies chPad in the beginning or at the end (default)
+ wxString& Pad(size_t nCount, wxUniChar chPad = wxT(' '), bool bFromRight = true);
+
+ // searching and replacing
+ // searching (return starting index, or -1 if not found)
+ int Find(wxUniChar ch, bool bFromEnd = false) const; // like strchr/strrchr
+ int Find(wxUniCharRef ch, bool bFromEnd = false) const
+ { return Find(wxUniChar(ch), bFromEnd); }
+ int Find(char ch, bool bFromEnd = false) const
+ { return Find(wxUniChar(ch), bFromEnd); }
+ int Find(unsigned char ch, bool bFromEnd = false) const
+ { return Find(wxUniChar(ch), bFromEnd); }
+ int Find(wchar_t ch, bool bFromEnd = false) const
+ { return Find(wxUniChar(ch), bFromEnd); }
+ // searching (return starting index, or -1 if not found)
+ int Find(const wxString& sub) const // like strstr
+ {
+ size_type idx = find(sub);
+ return (idx == npos) ? wxNOT_FOUND : (int)idx;
+ }
+ int Find(const char *sub) const // like strstr
+ {
+ size_type idx = find(sub);
+ return (idx == npos) ? wxNOT_FOUND : (int)idx;
+ }
+ int Find(const wchar_t *sub) const // like strstr
+ {
+ size_type idx = find(sub);
+ return (idx == npos) ? wxNOT_FOUND : (int)idx;
+ }
+
+ int Find(const wxCStrData& sub) const
+ { return Find(sub.AsString()); }
+ int Find(const wxScopedCharBuffer& sub) const
+ { return Find(sub.data()); }
+ int Find(const wxScopedWCharBuffer& sub) const
+ { return Find(sub.data()); }
+
+ // replace first (or all of bReplaceAll) occurrences of substring with
+ // another string, returns the number of replacements made
+ size_t Replace(const wxString& strOld,
+ const wxString& strNew,
+ bool bReplaceAll = true);
+
+ // check if the string contents matches a mask containing '*' and '?'
+ bool Matches(const wxString& mask) const;
+
+ // conversion to numbers: all functions return true only if the whole
+ // string is a number and put the value of this number into the pointer
+ // provided, the base is the numeric base in which the conversion should be
+ // done and must be comprised between 2 and 36 or be 0 in which case the
+ // standard C rules apply (leading '0' => octal, "0x" => hex)
+ // convert to a signed integer
+ bool ToLong(long *val, int base = 10) const;
+ // convert to an unsigned integer
+ bool ToULong(unsigned long *val, int base = 10) const;
+ // convert to wxLongLong
+#if defined(wxLongLong_t)
+ bool ToLongLong(wxLongLong_t *val, int base = 10) const;
+ // convert to wxULongLong
+ bool ToULongLong(wxULongLong_t *val, int base = 10) const;
+#endif // wxLongLong_t
+ // convert to a double
+ bool ToDouble(double *val) const;
+
+ // conversions to numbers using C locale
+ // convert to a signed integer
+ bool ToCLong(long *val, int base = 10) const;
+ // convert to an unsigned integer
+ bool ToCULong(unsigned long *val, int base = 10) const;
+ // convert to a double
+ bool ToCDouble(double *val) const;
+
+ // create a string representing the given floating point number with the
+ // default (like %g) or fixed (if precision >=0) precision
+ // in the current locale
+ static wxString FromDouble(double val, int precision = -1);
+ // in C locale
+ static wxString FromCDouble(double val, int precision = -1);
+
+#ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN
+ // formatted input/output
+ // as sprintf(), returns the number of characters written or < 0 on error
+ // (take 'this' into account in attribute parameter count)
+ // int Printf(const wxString& format, ...);
+ WX_DEFINE_VARARG_FUNC(int, Printf, 1, (const wxFormatString&),
+ DoPrintfWchar, DoPrintfUtf8)
+#ifdef __WATCOMC__
+ // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
+ WX_VARARG_WATCOM_WORKAROUND(int, Printf, 1, (const wxString&),
+ (wxFormatString(f1)));
+ WX_VARARG_WATCOM_WORKAROUND(int, Printf, 1, (const wxCStrData&),
+ (wxFormatString(f1)));
+ WX_VARARG_WATCOM_WORKAROUND(int, Printf, 1, (const char*),
+ (wxFormatString(f1)));
+ WX_VARARG_WATCOM_WORKAROUND(int, Printf, 1, (const wchar_t*),
+ (wxFormatString(f1)));
+#endif
+#endif // !wxNEEDS_WXSTRING_PRINTF_MIXIN
+ // as vprintf(), returns the number of characters written or < 0 on error
+ int PrintfV(const wxString& format, va_list argptr);
+
+#ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN
+ // returns the string containing the result of Printf() to it
+ // static wxString Format(const wxString& format, ...) WX_ATTRIBUTE_PRINTF_1;
+ WX_DEFINE_VARARG_FUNC(static wxString, Format, 1, (const wxFormatString&),
+ DoFormatWchar, DoFormatUtf8)
+#ifdef __WATCOMC__
+ // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
+ WX_VARARG_WATCOM_WORKAROUND(static wxString, Format, 1, (const wxString&),
+ (wxFormatString(f1)));
+ WX_VARARG_WATCOM_WORKAROUND(static wxString, Format, 1, (const wxCStrData&),
+ (wxFormatString(f1)));
+ WX_VARARG_WATCOM_WORKAROUND(static wxString, Format, 1, (const char*),
+ (wxFormatString(f1)));
+ WX_VARARG_WATCOM_WORKAROUND(static wxString, Format, 1, (const wchar_t*),
+ (wxFormatString(f1)));
+#endif
+#endif
+ // the same as above, but takes a va_list
+ static wxString FormatV(const wxString& format, va_list argptr);
+
+ // raw access to string memory
+ // ensure that string has space for at least nLen characters
+ // only works if the data of this string is not shared
+ bool Alloc(size_t nLen) { reserve(nLen); return capacity() >= nLen; }
+ // minimize the string's memory
+ // only works if the data of this string is not shared
+ bool Shrink();
+#if WXWIN_COMPATIBILITY_2_8 && !wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8
+ // These are deprecated, use wxStringBuffer or wxStringBufferLength instead
+ //
+ // get writable buffer of at least nLen bytes. Unget() *must* be called
+ // a.s.a.p. to put string back in a reasonable state!
+ wxDEPRECATED( wxStringCharType *GetWriteBuf(size_t nLen) );
+ // call this immediately after GetWriteBuf() has been used
+ wxDEPRECATED( void UngetWriteBuf() );
+ wxDEPRECATED( void UngetWriteBuf(size_t nLen) );
+#endif // WXWIN_COMPATIBILITY_2_8 && !wxUSE_STL_BASED_WXSTRING && wxUSE_UNICODE_UTF8
+
+ // wxWidgets version 1 compatibility functions
+
+ // use Mid()
+ wxString SubString(size_t from, size_t to) const
+ { return Mid(from, (to - from + 1)); }
+ // values for second parameter of CompareTo function
+ enum caseCompare {exact, ignoreCase};
+ // values for first parameter of Strip function
+ enum stripType {leading = 0x1, trailing = 0x2, both = 0x3};
+
+#ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN
+ // use Printf()
+ // (take 'this' into account in attribute parameter count)
+ // int sprintf(const wxString& format, ...) WX_ATTRIBUTE_PRINTF_2;
+ WX_DEFINE_VARARG_FUNC(int, sprintf, 1, (const wxFormatString&),
+ DoPrintfWchar, DoPrintfUtf8)
+#ifdef __WATCOMC__
+ // workaround for http://bugzilla.openwatcom.org/show_bug.cgi?id=351
+ WX_VARARG_WATCOM_WORKAROUND(int, sprintf, 1, (const wxString&),
+ (wxFormatString(f1)));
+ WX_VARARG_WATCOM_WORKAROUND(int, sprintf, 1, (const wxCStrData&),
+ (wxFormatString(f1)));
+ WX_VARARG_WATCOM_WORKAROUND(int, sprintf, 1, (const char*),
+ (wxFormatString(f1)));
+ WX_VARARG_WATCOM_WORKAROUND(int, sprintf, 1, (const wchar_t*),
+ (wxFormatString(f1)));
+#endif
+#endif // wxNEEDS_WXSTRING_PRINTF_MIXIN
+
+ // use Cmp()
+ int CompareTo(const wxChar* psz, caseCompare cmp = exact) const
+ { return cmp == exact ? Cmp(psz) : CmpNoCase(psz); }
+
+ // use length()
+ size_t Length() const { return length(); }
+ // Count the number of characters
+ int Freq(wxUniChar ch) const;
+ // use MakeLower
+ void LowerCase() { MakeLower(); }
+ // use MakeUpper
+ void UpperCase() { MakeUpper(); }
+ // use Trim except that it doesn't change this string
+ wxString Strip(stripType w = trailing) const;
+
+ // use Find (more general variants not yet supported)
+ size_t Index(const wxChar* psz) const { return Find(psz); }
+ size_t Index(wxUniChar ch) const { return Find(ch); }
+ // use Truncate
+ wxString& Remove(size_t pos) { return Truncate(pos); }
+ wxString& RemoveLast(size_t n = 1) { return Truncate(length() - n); }
+
+ wxString& Remove(size_t nStart, size_t nLen)
+ { return (wxString&)erase( nStart, nLen ); }
+
+ // use Find()
+ int First( wxUniChar ch ) const { return Find(ch); }
+ int First( wxUniCharRef ch ) const { return Find(ch); }
+ int First( char ch ) const { return Find(ch); }
+ int First( unsigned char ch ) const { return Find(ch); }
+ int First( wchar_t ch ) const { return Find(ch); }
+ int First( const wxString& str ) const { return Find(str); }
+ int Last( wxUniChar ch ) const { return Find(ch, true); }
+ bool Contains(const wxString& str) const { return Find(str) != wxNOT_FOUND; }
+
+ // use empty()
+ bool IsNull() const { return empty(); }
+
+ // std::string compatibility functions
+
+ // take nLen chars starting at nPos
+ wxString(const wxString& str, size_t nPos, size_t nLen)
+ { assign(str, nPos, nLen); }
+ // take all characters from first to last
+ wxString(const_iterator first, const_iterator last)
+ : m_impl(first.impl(), last.impl()) { }
+#if WXWIN_COMPATIBILITY_STRING_PTR_AS_ITER
+ // the 2 overloads below are for compatibility with the existing code using
+ // pointers instead of iterators
+ wxString(const char *first, const char *last)
+ {
+ SubstrBufFromMB str(ImplStr(first, last - first));
+ m_impl.assign(str.data, str.len);
+ }
+ wxString(const wchar_t *first, const wchar_t *last)
+ {
+ SubstrBufFromWC str(ImplStr(first, last - first));
+ m_impl.assign(str.data, str.len);
+ }
+ // and this one is needed to compile code adding offsets to c_str() result
+ wxString(const wxCStrData& first, const wxCStrData& last)
+ : m_impl(CreateConstIterator(first).impl(),
+ CreateConstIterator(last).impl())
+ {
+ wxASSERT_MSG( first.m_str == last.m_str,
+ wxT("pointers must be into the same string") );
+ }
+#endif // WXWIN_COMPATIBILITY_STRING_PTR_AS_ITER
+
+ // lib.string.modifiers
+ // append elements str[pos], ..., str[pos+n]
+ wxString& append(const wxString& str, size_t pos, size_t n)
+ {
+ wxSTRING_UPDATE_CACHED_LENGTH(n);
+
+ size_t from, len;
+ str.PosLenToImpl(pos, n, &from, &len);
+ m_impl.append(str.m_impl, from, len);
+ return *this;
+ }
+ // append a string
+ wxString& append(const wxString& str)
+ {
+ wxSTRING_UPDATE_CACHED_LENGTH(str.length());
+
+ m_impl.append(str.m_impl);
+ return *this;
+ }
+
+ // append first n (or all if n == npos) characters of sz
+ wxString& append(const char *sz)
+ {
+ wxSTRING_INVALIDATE_CACHED_LENGTH();
+
+ m_impl.append(ImplStr(sz));
+ return *this;
+ }
+
+ wxString& append(const wchar_t *sz)
+ {
+ wxSTRING_INVALIDATE_CACHED_LENGTH();
+
+ m_impl.append(ImplStr(sz));
+ return *this;
+ }
+
+ wxString& append(const char *sz, size_t n)
+ {
+ wxSTRING_INVALIDATE_CACHED_LENGTH();
+
+ SubstrBufFromMB str(ImplStr(sz, n));
+ m_impl.append(str.data, str.len);
+ return *this;
+ }
+ wxString& append(const wchar_t *sz, size_t n)
+ {
+ wxSTRING_UPDATE_CACHED_LENGTH(n);
+
+ SubstrBufFromWC str(ImplStr(sz, n));
+ m_impl.append(str.data, str.len);
+ return *this;
+ }
+
+ wxString& append(const wxCStrData& str)
+ { return append(str.AsString()); }
+ wxString& append(const wxScopedCharBuffer& str)
+ { return append(str.data(), str.length()); }
+ wxString& append(const wxScopedWCharBuffer& str)
+ { return append(str.data(), str.length()); }
+ wxString& append(const wxCStrData& str, size_t n)
+ { return append(str.AsString(), 0, n); }
+ wxString& append(const wxScopedCharBuffer& str, size_t n)
+ { return append(str.data(), n); }
+ wxString& append(const wxScopedWCharBuffer& str, size_t n)
+ { return append(str.data(), n); }
+
+ // append n copies of ch
+ wxString& append(size_t n, wxUniChar ch)
+ {
+#if wxUSE_UNICODE_UTF8
+ if ( !ch.IsAscii() )
+ {
+ wxSTRING_INVALIDATE_CACHED_LENGTH();
+
+ m_impl.append(wxStringOperations::EncodeNChars(n, ch));
+ }
+ else // ASCII
+#endif
+ {
+ wxSTRING_UPDATE_CACHED_LENGTH(n);
+
+ m_impl.append(n, (wxStringCharType)ch);
+ }
+
+ return *this;
+ }
+
+ wxString& append(size_t n, wxUniCharRef ch)
+ { return append(n, wxUniChar(ch)); }
+ wxString& append(size_t n, char ch)
+ { return append(n, wxUniChar(ch)); }
+ wxString& append(size_t n, unsigned char ch)
+ { return append(n, wxUniChar(ch)); }
+ wxString& append(size_t n, wchar_t ch)
+ { return append(n, wxUniChar(ch)); }
+
+ // append from first to last
+ wxString& append(const_iterator first, const_iterator last)
+ {
+ wxSTRING_INVALIDATE_CACHED_LENGTH();
+
+ m_impl.append(first.impl(), last.impl());
+ return *this;
+ }
+#if WXWIN_COMPATIBILITY_STRING_PTR_AS_ITER
+ wxString& append(const char *first, const char *last)
+ { return append(first, last - first); }
+ wxString& append(const wchar_t *first, const wchar_t *last)
+ { return append(first, last - first); }
+ wxString& append(const wxCStrData& first, const wxCStrData& last)
+ { return append(CreateConstIterator(first), CreateConstIterator(last)); }
+#endif // WXWIN_COMPATIBILITY_STRING_PTR_AS_ITER
+
+ // same as `this_string = str'
+ wxString& assign(const wxString& str)
+ {
+ wxSTRING_SET_CACHED_LENGTH(str.length());
+
+ m_impl = str.m_impl;
+
+ return *this;
+ }
+
+ // This is a non-standard-compliant overload taking the first "len"
+ // characters of the source string.
+ wxString& assign(const wxString& str, size_t len)
+ {
+#if wxUSE_STRING_POS_CACHE
+ // It is legal to pass len > str.length() to wxStringImpl::assign() but
+ // by restricting it here we save some work for that function so it's not
+ // really less efficient and, at the same time, ensure that we don't
+ // cache invalid length.
+ const size_t lenSrc = str.length();
+ if ( len > lenSrc )
+ len = lenSrc;
+
+ wxSTRING_SET_CACHED_LENGTH(len);
+#endif // wxUSE_STRING_POS_CACHE
+
+ m_impl.assign(str.m_impl, 0, str.LenToImpl(len));
+
+ return *this;
+ }
+
+ // same as ` = str[pos..pos + n]
+ wxString& assign(const wxString& str, size_t pos, size_t n)
+ {
+ size_t from, len;
+ str.PosLenToImpl(pos, n, &from, &len);
+ m_impl.assign(str.m_impl, from, len);
+
+ // it's important to call this after PosLenToImpl() above in case str is
+ // the same string as this one
+ wxSTRING_SET_CACHED_LENGTH(n);
+
+ return *this;
+ }
+
+ // same as `= first n (or all if n == npos) characters of sz'
+ wxString& assign(const char *sz)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ m_impl.assign(ImplStr(sz));
+
+ return *this;
+ }
+
+ wxString& assign(const wchar_t *sz)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ m_impl.assign(ImplStr(sz));
+
+ return *this;
+ }
+
+ wxString& assign(const char *sz, size_t n)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ SubstrBufFromMB str(ImplStr(sz, n));
+ m_impl.assign(str.data, str.len);
+
+ return *this;
+ }
+
+ wxString& assign(const wchar_t *sz, size_t n)
+ {
+ wxSTRING_SET_CACHED_LENGTH(n);
+
+ SubstrBufFromWC str(ImplStr(sz, n));
+ m_impl.assign(str.data, str.len);
+
+ return *this;
+ }
+
+ wxString& assign(const wxCStrData& str)
+ { return assign(str.AsString()); }
+ wxString& assign(const wxScopedCharBuffer& str)
+ { return assign(str.data(), str.length()); }
+ wxString& assign(const wxScopedWCharBuffer& str)
+ { return assign(str.data(), str.length()); }
+ wxString& assign(const wxCStrData& str, size_t len)
+ { return assign(str.AsString(), len); }
+ wxString& assign(const wxScopedCharBuffer& str, size_t len)
+ { return assign(str.data(), len); }
+ wxString& assign(const wxScopedWCharBuffer& str, size_t len)
+ { return assign(str.data(), len); }
+
+ // same as `= n copies of ch'
+ wxString& assign(size_t n, wxUniChar ch)
+ {
+ wxSTRING_SET_CACHED_LENGTH(n);
+
+#if wxUSE_UNICODE_UTF8
+ if ( !ch.IsAscii() )
+ m_impl.assign(wxStringOperations::EncodeNChars(n, ch));
+ else
+#endif
+ m_impl.assign(n, (wxStringCharType)ch);
+
+ return *this;
+ }
+
+ wxString& assign(size_t n, wxUniCharRef ch)
+ { return assign(n, wxUniChar(ch)); }
+ wxString& assign(size_t n, char ch)
+ { return assign(n, wxUniChar(ch)); }
+ wxString& assign(size_t n, unsigned char ch)
+ { return assign(n, wxUniChar(ch)); }
+ wxString& assign(size_t n, wchar_t ch)
+ { return assign(n, wxUniChar(ch)); }
+
+ // assign from first to last
+ wxString& assign(const_iterator first, const_iterator last)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ m_impl.assign(first.impl(), last.impl());
+
+ return *this;
+ }
+#if WXWIN_COMPATIBILITY_STRING_PTR_AS_ITER
+ wxString& assign(const char *first, const char *last)
+ { return assign(first, last - first); }
+ wxString& assign(const wchar_t *first, const wchar_t *last)
+ { return assign(first, last - first); }
+ wxString& assign(const wxCStrData& first, const wxCStrData& last)
+ { return assign(CreateConstIterator(first), CreateConstIterator(last)); }
+#endif // WXWIN_COMPATIBILITY_STRING_PTR_AS_ITER
+
+ // string comparison
+ int compare(const wxString& str) const;
+ int compare(const char* sz) const;
+ int compare(const wchar_t* sz) const;
+ int compare(const wxCStrData& str) const
+ { return compare(str.AsString()); }
+ int compare(const wxScopedCharBuffer& str) const
+ { return compare(str.data()); }
+ int compare(const wxScopedWCharBuffer& str) const
+ { return compare(str.data()); }
+ // comparison with a substring
+ int compare(size_t nStart, size_t nLen, const wxString& str) const;
+ // comparison of 2 substrings
+ int compare(size_t nStart, size_t nLen,
+ const wxString& str, size_t nStart2, size_t nLen2) const;
+ // substring comparison with first nCount characters of sz
+ int compare(size_t nStart, size_t nLen,
+ const char* sz, size_t nCount = npos) const;
+ int compare(size_t nStart, size_t nLen,
+ const wchar_t* sz, size_t nCount = npos) const;
+
+ // insert another string
+ wxString& insert(size_t nPos, const wxString& str)
+ { insert(GetIterForNthChar(nPos), str.begin(), str.end()); return *this; }
+ // insert n chars of str starting at nStart (in str)
+ wxString& insert(size_t nPos, const wxString& str, size_t nStart, size_t n)
+ {
+ wxSTRING_UPDATE_CACHED_LENGTH(n);
+
+ size_t from, len;
+ str.PosLenToImpl(nStart, n, &from, &len);
+ m_impl.insert(PosToImpl(nPos), str.m_impl, from, len);
+
+ return *this;
+ }
+
+ // insert first n (or all if n == npos) characters of sz
+ wxString& insert(size_t nPos, const char *sz)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ m_impl.insert(PosToImpl(nPos), ImplStr(sz));
+
+ return *this;
+ }
+
+ wxString& insert(size_t nPos, const wchar_t *sz)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ m_impl.insert(PosToImpl(nPos), ImplStr(sz)); return *this;
+ }
+
+ wxString& insert(size_t nPos, const char *sz, size_t n)
+ {
+ wxSTRING_UPDATE_CACHED_LENGTH(n);
+
+ SubstrBufFromMB str(ImplStr(sz, n));
+ m_impl.insert(PosToImpl(nPos), str.data, str.len);
+
+ return *this;
+ }
+
+ wxString& insert(size_t nPos, const wchar_t *sz, size_t n)
+ {
+ wxSTRING_UPDATE_CACHED_LENGTH(n);
+
+ SubstrBufFromWC str(ImplStr(sz, n));
+ m_impl.insert(PosToImpl(nPos), str.data, str.len);
+
+ return *this;
+ }
+
+ // insert n copies of ch
+ wxString& insert(size_t nPos, size_t n, wxUniChar ch)
+ {
+ wxSTRING_UPDATE_CACHED_LENGTH(n);
+
+#if wxUSE_UNICODE_UTF8
+ if ( !ch.IsAscii() )
+ m_impl.insert(PosToImpl(nPos), wxStringOperations::EncodeNChars(n, ch));
+ else
+#endif
+ m_impl.insert(PosToImpl(nPos), n, (wxStringCharType)ch);
+ return *this;
+ }
+
+ iterator insert(iterator it, wxUniChar ch)
+ {
+ wxSTRING_UPDATE_CACHED_LENGTH(1);
+
+#if wxUSE_UNICODE_UTF8
+ if ( !ch.IsAscii() )
+ {
+ size_t pos = IterToImplPos(it);
+ m_impl.insert(pos, wxStringOperations::EncodeChar(ch));
+ return iterator(this, m_impl.begin() + pos);
+ }
+ else
+#endif
+ return iterator(this, m_impl.insert(it.impl(), (wxStringCharType)ch));
+ }
+
+ void insert(iterator it, const_iterator first, const_iterator last)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ m_impl.insert(it.impl(), first.impl(), last.impl());
+ }
+
+#if WXWIN_COMPATIBILITY_STRING_PTR_AS_ITER
+ void insert(iterator it, const char *first, const char *last)
+ { insert(it - begin(), first, last - first); }
+ void insert(iterator it, const wchar_t *first, const wchar_t *last)
+ { insert(it - begin(), first, last - first); }
+ void insert(iterator it, const wxCStrData& first, const wxCStrData& last)
+ { insert(it, CreateConstIterator(first), CreateConstIterator(last)); }
+#endif // WXWIN_COMPATIBILITY_STRING_PTR_AS_ITER
+
+ void insert(iterator it, size_type n, wxUniChar ch)
+ {
+ wxSTRING_UPDATE_CACHED_LENGTH(n);
+
+#if wxUSE_UNICODE_UTF8
+ if ( !ch.IsAscii() )
+ m_impl.insert(IterToImplPos(it), wxStringOperations::EncodeNChars(n, ch));
+ else
+#endif
+ m_impl.insert(it.impl(), n, (wxStringCharType)ch);
+ }
+
+ // delete characters from nStart to nStart + nLen
+ wxString& erase(size_type pos = 0, size_type n = npos)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ size_t from, len;
+ PosLenToImpl(pos, n, &from, &len);
+ m_impl.erase(from, len);
+
+ return *this;
+ }
+
+ // delete characters from first up to last
+ iterator erase(iterator first, iterator last)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ return iterator(this, m_impl.erase(first.impl(), last.impl()));
+ }
+
+ iterator erase(iterator first)
+ {
+ wxSTRING_UPDATE_CACHED_LENGTH(-1);
+
+ return iterator(this, m_impl.erase(first.impl()));
+ }
+
+#ifdef wxSTRING_BASE_HASNT_CLEAR
+ void clear() { erase(); }
+#else
+ void clear()
+ {
+ wxSTRING_SET_CACHED_LENGTH(0);
+
+ m_impl.clear();
+ }
+#endif
+
+ // replaces the substring of length nLen starting at nStart
+ wxString& replace(size_t nStart, size_t nLen, const char* sz)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ size_t from, len;
+ PosLenToImpl(nStart, nLen, &from, &len);
+ m_impl.replace(from, len, ImplStr(sz));
+
+ return *this;
+ }
+
+ wxString& replace(size_t nStart, size_t nLen, const wchar_t* sz)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ size_t from, len;
+ PosLenToImpl(nStart, nLen, &from, &len);
+ m_impl.replace(from, len, ImplStr(sz));
+
+ return *this;
+ }
+
+ // replaces the substring of length nLen starting at nStart
+ wxString& replace(size_t nStart, size_t nLen, const wxString& str)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ size_t from, len;
+ PosLenToImpl(nStart, nLen, &from, &len);
+ m_impl.replace(from, len, str.m_impl);
+
+ return *this;
+ }
+
+ // replaces the substring with nCount copies of ch
+ wxString& replace(size_t nStart, size_t nLen, size_t nCount, wxUniChar ch)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ size_t from, len;
+ PosLenToImpl(nStart, nLen, &from, &len);
+#if wxUSE_UNICODE_UTF8
+ if ( !ch.IsAscii() )
+ m_impl.replace(from, len, wxStringOperations::EncodeNChars(nCount, ch));
+ else
+#endif
+ m_impl.replace(from, len, nCount, (wxStringCharType)ch);
+
+ return *this;
+ }
+
+ // replaces a substring with another substring
+ wxString& replace(size_t nStart, size_t nLen,
+ const wxString& str, size_t nStart2, size_t nLen2)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ size_t from, len;
+ PosLenToImpl(nStart, nLen, &from, &len);
+
+ size_t from2, len2;
+ str.PosLenToImpl(nStart2, nLen2, &from2, &len2);
+
+ m_impl.replace(from, len, str.m_impl, from2, len2);
+
+ return *this;
+ }
+
+ // replaces the substring with first nCount chars of sz
+ wxString& replace(size_t nStart, size_t nLen,
+ const char* sz, size_t nCount)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ size_t from, len;
+ PosLenToImpl(nStart, nLen, &from, &len);
+
+ SubstrBufFromMB str(ImplStr(sz, nCount));
+
+ m_impl.replace(from, len, str.data, str.len);
+
+ return *this;
+ }
+
+ wxString& replace(size_t nStart, size_t nLen,
+ const wchar_t* sz, size_t nCount)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ size_t from, len;
+ PosLenToImpl(nStart, nLen, &from, &len);
+
+ SubstrBufFromWC str(ImplStr(sz, nCount));
+
+ m_impl.replace(from, len, str.data, str.len);
+
+ return *this;
+ }
+
+ wxString& replace(size_t nStart, size_t nLen,
+ const wxString& s, size_t nCount)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ size_t from, len;
+ PosLenToImpl(nStart, nLen, &from, &len);
+ m_impl.replace(from, len, s.m_impl.c_str(), s.LenToImpl(nCount));
+
+ return *this;
+ }
+
+ wxString& replace(iterator first, iterator last, const char* s)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ m_impl.replace(first.impl(), last.impl(), ImplStr(s));
+
+ return *this;
+ }
+
+ wxString& replace(iterator first, iterator last, const wchar_t* s)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ m_impl.replace(first.impl(), last.impl(), ImplStr(s));
+
+ return *this;
+ }
+
+ wxString& replace(iterator first, iterator last, const char* s, size_type n)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ SubstrBufFromMB str(ImplStr(s, n));
+ m_impl.replace(first.impl(), last.impl(), str.data, str.len);
+
+ return *this;
+ }
+
+ wxString& replace(iterator first, iterator last, const wchar_t* s, size_type n)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ SubstrBufFromWC str(ImplStr(s, n));
+ m_impl.replace(first.impl(), last.impl(), str.data, str.len);
+
+ return *this;
+ }
+
+ wxString& replace(iterator first, iterator last, const wxString& s)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ m_impl.replace(first.impl(), last.impl(), s.m_impl);
+
+ return *this;
+ }
+
+ wxString& replace(iterator first, iterator last, size_type n, wxUniChar ch)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+#if wxUSE_UNICODE_UTF8
+ if ( !ch.IsAscii() )
+ m_impl.replace(first.impl(), last.impl(),
+ wxStringOperations::EncodeNChars(n, ch));
+ else
+#endif
+ m_impl.replace(first.impl(), last.impl(), n, (wxStringCharType)ch);
+
+ return *this;
+ }
+
+ wxString& replace(iterator first, iterator last,
+ const_iterator first1, const_iterator last1)
+ {
+ wxSTRING_INVALIDATE_CACHE();
+
+ m_impl.replace(first.impl(), last.impl(), first1.impl(), last1.impl());
+
+ return *this;
+ }
+
+ wxString& replace(iterator first, iterator last,
+ const char *first1, const char *last1)
+ { replace(first, last, first1, last1 - first1); return *this; }
+ wxString& replace(iterator first, iterator last,
+ const wchar_t *first1, const wchar_t *last1)
+ { replace(first, last, first1, last1 - first1); return *this; }