+ return *this;
+}
+
+// adds nCount characters chPad to the string from either side
+wxString& wxString::Pad(size_t nCount, wxUniChar chPad, bool bFromRight)
+{
+ wxString s(chPad, nCount);
+
+ if ( bFromRight )
+ *this += s;
+ else
+ {
+ s += *this;
+ swap(s);
+ }
+
+ return *this;
+}
+
+// truncate the string
+wxString& wxString::Truncate(size_t uiLen)
+{
+ if ( uiLen < length() )
+ {
+ erase(begin() + uiLen, end());
+ }
+ //else: nothing to do, string is already short enough
+
+ return *this;
+}
+
+// ---------------------------------------------------------------------------
+// finding (return wxNOT_FOUND if not found and index otherwise)
+// ---------------------------------------------------------------------------
+
+// find a character
+int wxString::Find(wxUniChar ch, bool bFromEnd) const
+{
+ size_type idx = bFromEnd ? find_last_of(ch) : find_first_of(ch);
+
+ return (idx == npos) ? wxNOT_FOUND : (int)idx;
+}
+
+// ----------------------------------------------------------------------------
+// conversion to numbers
+// ----------------------------------------------------------------------------
+
+// The implementation of all the functions below is exactly the same so factor
+// it out. Note that number extraction works correctly on UTF-8 strings, so
+// we can use wxStringCharType and wx_str() for maximum efficiency.
+
+#ifndef __WXWINCE__
+ #define DO_IF_NOT_WINCE(x) x
+#else
+ #define DO_IF_NOT_WINCE(x)
+#endif
+
+#define WX_STRING_TO_X_TYPE_START \
+ wxCHECK_MSG( pVal, false, wxT("NULL output pointer") ); \
+ DO_IF_NOT_WINCE( errno = 0; ) \
+ const wxStringCharType *start = wx_str(); \
+ wxStringCharType *end;
+
+// notice that we return false without modifying the output parameter at all if
+// nothing could be parsed but we do modify it and return false then if we did
+// parse something successfully but not the entire string
+#define WX_STRING_TO_X_TYPE_END \
+ if ( end == start DO_IF_NOT_WINCE(|| errno == ERANGE) ) \
+ return false; \
+ *pVal = val; \
+ return !*end;
+
+bool wxString::ToLong(long *pVal, int base) const
+{
+ wxASSERT_MSG( !base || (base > 1 && base <= 36), wxT("invalid base") );
+
+ WX_STRING_TO_X_TYPE_START
+ long val = wxStrtol(start, &end, base);
+ WX_STRING_TO_X_TYPE_END
+}
+
+bool wxString::ToULong(unsigned long *pVal, int base) const
+{
+ wxASSERT_MSG( !base || (base > 1 && base <= 36), wxT("invalid base") );
+
+ WX_STRING_TO_X_TYPE_START
+ unsigned long val = wxStrtoul(start, &end, base);
+ WX_STRING_TO_X_TYPE_END
+}
+
+bool wxString::ToLongLong(wxLongLong_t *pVal, int base) const
+{
+ wxASSERT_MSG( !base || (base > 1 && base <= 36), wxT("invalid base") );
+
+ WX_STRING_TO_X_TYPE_START
+ wxLongLong_t val = wxStrtoll(start, &end, base);
+ WX_STRING_TO_X_TYPE_END
+}
+
+bool wxString::ToULongLong(wxULongLong_t *pVal, int base) const
+{
+ wxASSERT_MSG( !base || (base > 1 && base <= 36), wxT("invalid base") );
+
+ WX_STRING_TO_X_TYPE_START
+ wxULongLong_t val = wxStrtoull(start, &end, base);
+ WX_STRING_TO_X_TYPE_END
+}
+
+bool wxString::ToDouble(double *pVal) const
+{
+ WX_STRING_TO_X_TYPE_START
+ double val = wxStrtod(start, &end);
+ WX_STRING_TO_X_TYPE_END
+}
+
+#if wxUSE_XLOCALE
+
+bool wxString::ToCLong(long *pVal, int base) const
+{
+ wxASSERT_MSG( !base || (base > 1 && base <= 36), wxT("invalid base") );
+
+ WX_STRING_TO_X_TYPE_START
+#if (wxUSE_UNICODE_UTF8 || !wxUSE_UNICODE) && defined(wxHAS_XLOCALE_SUPPORT)
+ long val = wxStrtol_lA(start, &end, base, wxCLocale);
+#else
+ long val = wxStrtol_l(start, &end, base, wxCLocale);
+#endif
+ WX_STRING_TO_X_TYPE_END
+}
+
+bool wxString::ToCULong(unsigned long *pVal, int base) const
+{
+ wxASSERT_MSG( !base || (base > 1 && base <= 36), wxT("invalid base") );
+
+ WX_STRING_TO_X_TYPE_START
+#if (wxUSE_UNICODE_UTF8 || !wxUSE_UNICODE) && defined(wxHAS_XLOCALE_SUPPORT)
+ unsigned long val = wxStrtoul_lA(start, &end, base, wxCLocale);
+#else
+ unsigned long val = wxStrtoul_l(start, &end, base, wxCLocale);
+#endif
+ WX_STRING_TO_X_TYPE_END
+}
+
+bool wxString::ToCDouble(double *pVal) const
+{
+ WX_STRING_TO_X_TYPE_START
+#if (wxUSE_UNICODE_UTF8 || !wxUSE_UNICODE) && defined(wxHAS_XLOCALE_SUPPORT)
+ double val = wxStrtod_lA(start, &end, wxCLocale);
+#else
+ double val = wxStrtod_l(start, &end, wxCLocale);
+#endif
+ WX_STRING_TO_X_TYPE_END
+}
+
+#else // wxUSE_XLOCALE
+
+// Provide implementation of these functions even when wxUSE_XLOCALE is
+// disabled, we still need them in wxWidgets internal code.
+
+// For integers we just assume the current locale uses the same number
+// representation as the C one as there is nothing else we can do.
+bool wxString::ToCLong(long *pVal, int base) const
+{
+ return ToLong(pVal, base);
+}
+
+bool wxString::ToCULong(unsigned long *pVal, int base) const
+{
+ return ToULong(pVal, base);
+}
+
+// For floating point numbers we have to handle the problem of the decimal
+// point which is different in different locales.
+bool wxString::ToCDouble(double *pVal) const
+{
+ // Create a copy of this string using the decimal point instead of whatever
+ // separator the current locale uses.
+#if wxUSE_INTL
+ wxString sep = wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT,
+ wxLOCALE_CAT_NUMBER);
+ if ( sep == "." )
+ {
+ // We can avoid an unnecessary string copy in this case.
+ return ToDouble(pVal);
+ }
+#else // !wxUSE_INTL
+ // We don't know what the current separator is so it might even be a point
+ // already, try to parse the string as a double:
+ if ( ToDouble(pVal) )
+ {
+ // It must have been the point, nothing else to do.
+ return true;
+ }
+
+ // Try to guess the separator, using the most common alternative value.
+ wxString sep(",");
+#endif // wxUSE_INTL/!wxUSE_INTL
+ wxString cstr(*this);
+ cstr.Replace(".", sep);
+
+ return cstr.ToDouble(pVal);
+}
+
+#endif // wxUSE_XLOCALE/!wxUSE_XLOCALE
+
+// ----------------------------------------------------------------------------
+// number to string conversion
+// ----------------------------------------------------------------------------
+
+/* static */
+wxString wxString::FromCDouble(double val)
+{
+#if wxUSE_STD_IOSTREAM && wxUSE_STD_STRING
+ // We assume that we can use the ostream and not wstream for numbers.
+ wxSTD ostringstream os;
+ os << val;
+ return os.str();
+#else // wxUSE_STD_IOSTREAM
+ // Can't use iostream locale support, fall back to the manual method
+ // instead.
+ wxString s = FromDouble(val);
+#if wxUSE_INTL
+ wxString sep = wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT,
+ wxLOCALE_CAT_NUMBER);
+#else // !wxUSE_INTL
+ // As above, this is the most common alternative value. Notice that here it
+ // doesn't matter if we guess wrongly and the current separator is already
+ // ".": we'll just waste a call to Replace() in this case.
+ wxString sep(",");
+#endif // wxUSE_INTL/!wxUSE_INTL
+
+ s.Replace(sep, ".");
+ return s;
+#endif // wxUSE_STD_IOSTREAM/!wxUSE_STD_IOSTREAM