X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b96a56e60e65e17704fc66ae9cdbb2444ac987d8..beea183b40566b55020c9a6c4c976c3fbe77e55a:/src/common/string.cpp?ds=sidebyside diff --git a/src/common/string.cpp b/src/common/string.cpp index dcac014916..a0d42cb42f 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -24,6 +24,7 @@ #ifndef WX_PRECOMP #include "wx/string.h" #include "wx/wxcrtvararg.h" + #include "wx/intl.h" #include "wx/log.h" #endif @@ -44,6 +45,10 @@ #include "wx/msw/wrapwin.h" #endif // __WXMSW__ +#if wxUSE_STD_IOSTREAM + #include +#endif + // string handling functions used by wxString: #if wxUSE_UNICODE_UTF8 #define wxStringMemcpy memcpy @@ -1079,9 +1084,15 @@ size_t wxString::find_last_not_of(const wxOtherCharType* sz, size_t nStart, int wxString::CmpNoCase(const wxString& s) const { #if defined(__WXMSW__) && !wxUSE_UNICODE_UTF8 - // prefer to use CompareString() if available as it's more efficient than - // doing it manual or even using wxStricmp() (see #10375) - switch ( ::CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE, + // Prefer to use CompareString() if available as it's more efficient than + // doing it manually or even using wxStricmp() (see #10375) + // + // Also note that not using NORM_STRINGSORT may result in not having a + // strict weak ordering (e.g. s1 < s2 and s2 < s3 but s3 < s1) and so break + // algorithms such as std::sort that rely on it. It's also more consistent + // with the fall back version below. + switch ( ::CompareString(LOCALE_USER_DEFAULT, + NORM_IGNORECASE | SORT_STRINGSORT, m_impl.c_str(), m_impl.length(), s.m_impl.c_str(), s.m_impl.length()) ) { @@ -1727,7 +1738,87 @@ bool wxString::ToCDouble(double *pVal) const WX_STRING_TO_X_TYPE_END } -#endif // wxUSE_XLOCALE +#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 +} // --------------------------------------------------------------------------- // formatted output