Add wxString::FromDouble() and FromCDouble().

wxString::FromCDouble() is needed inside wxWidgets itself to format numbers
independently of the current locale. FromDouble() was added for symmetry with
ToDouble/ToCDouble() functions.

Use std::locale for the implementation if available and manual wxLocale-based
fallback otherwise.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64449 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2010-05-31 11:55:48 +00:00
parent 105993f7b6
commit 951201d81c
4 changed files with 109 additions and 0 deletions

View File

@ -2288,6 +2288,13 @@ public:
// convert to a double
bool ToCDouble(double *val) const;
// create a string representing the given floating point number
// in the current locale
static wxString FromDouble(double val)
{ return wxString::Format(wxS("%g"), val); }
// in C locale
static wxString FromCDouble(double val);
#ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN
// formatted input/output
// as sprintf(), returns the number of characters written or < 0 on error

View File

@ -1507,6 +1507,36 @@ public:
static wxString FromAscii(char c);
//@}
/**
Returns a string with the textual representation of the number in C
locale.
Unlike FromDouble() the string returned by this function always uses
the period character as decimal separator, independently of the current
locale.
@since 2.9.1
@see ToCDouble()
*/
static wxString FromCDouble(double val);
/**
Returns a string with the textual representation of the number.
This is a simple wrapper for @code wxString::Format("%g", val)
@endcode.
Notice that the string returned by this function uses the decimal
separator appropriate for the current locale, e.g. @c "," and not a
period in French locale. Use FromCDouble() if this is unwanted.
@since 2.9.1
@see ToDouble()
*/
static wxString FromDouble(double val);
//@{
/**
Converts C string encoded in UTF-8 to wxString.

View File

@ -45,6 +45,10 @@
#include "wx/msw/wrapwin.h"
#endif // __WXMSW__
#if wxUSE_STD_IOSTREAM
#include <sstream>
#endif
// string handling functions used by wxString:
#if wxUSE_UNICODE_UTF8
#define wxStringMemcpy memcpy
@ -1785,6 +1789,37 @@ bool wxString::ToCDouble(double *pVal) const
#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
// ---------------------------------------------------------------------------

View File

@ -53,6 +53,7 @@ private:
CPPUNIT_TEST( ToULongLong );
#endif // wxLongLong_t
CPPUNIT_TEST( ToDouble );
CPPUNIT_TEST( FromDouble );
CPPUNIT_TEST( StringBuf );
CPPUNIT_TEST( UTF8Buf );
CPPUNIT_TEST( CStrDataTernaryOperator );
@ -85,6 +86,7 @@ private:
void ToULongLong();
#endif // wxLongLong_t
void ToDouble();
void FromDouble();
void StringBuf();
void UTF8Buf();
void CStrDataTernaryOperator();
@ -747,6 +749,41 @@ void StringTestCase::ToDouble()
}
}
void StringTestCase::FromDouble()
{
static const struct FromDoubleTestData
{
double value;
const char *str;
} testData[] =
{
{ 1.23, "1.23" },
{ -3e-10, "-3e-10" },
{ -0.45678, "-0.45678" },
};
for ( unsigned n = 0; n < WXSIZEOF(testData); n++ )
{
const FromDoubleTestData& td = testData[n];
CPPUNIT_ASSERT_EQUAL( td.str, wxString::FromCDouble(td.value) );
}
if ( !wxLocale::IsAvailable(wxLANGUAGE_FRENCH) )
return;
wxLocale locale;
CPPUNIT_ASSERT( locale.Init(wxLANGUAGE_FRENCH, wxLOCALE_DONT_LOAD_DEFAULT) );
for ( unsigned m = 0; m < WXSIZEOF(testData); m++ )
{
const FromDoubleTestData& td = testData[m];
wxString str(td.str);
str.Replace(".", ",");
CPPUNIT_ASSERT_EQUAL( str, wxString::FromDouble(td.value) );
}
}
void StringTestCase::StringBuf()
{
// check that buffer can be used to write into the string