Add support for unsigned long long to wxNumberFormatter
This is necessary in order to deal with the numbers greater than wxINT64_MAX that can't be represented in just long long. It also allows to implement the intuitive handling of minus sign for the unsigned numbers, i.e. not to accept it in FromString(), unlike the standard functions which do (and parse -1 as 0xffff...fff). Also extend the tests to check for more boundary cases.
This commit is contained in:
@@ -34,6 +34,8 @@ public:
|
|||||||
static wxString ToString(wxLongLong_t val,
|
static wxString ToString(wxLongLong_t val,
|
||||||
int style = Style_WithThousandsSep);
|
int style = Style_WithThousandsSep);
|
||||||
#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
||||||
|
static wxString ToString(wxULongLong_t val,
|
||||||
|
int style = Style_WithThousandsSep);
|
||||||
static wxString ToString(double val,
|
static wxString ToString(double val,
|
||||||
int precision,
|
int precision,
|
||||||
int style = Style_WithThousandsSep);
|
int style = Style_WithThousandsSep);
|
||||||
@@ -46,6 +48,7 @@ public:
|
|||||||
#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
||||||
static bool FromString(wxString s, wxLongLong_t *val);
|
static bool FromString(wxString s, wxLongLong_t *val);
|
||||||
#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
||||||
|
static bool FromString(wxString s, wxULongLong_t *val);
|
||||||
static bool FromString(wxString s, double *val);
|
static bool FromString(wxString s, double *val);
|
||||||
|
|
||||||
|
|
||||||
|
@@ -73,6 +73,7 @@ public:
|
|||||||
//@{
|
//@{
|
||||||
static wxString ToString(long val, int flags = Style_WithThousandsSep);
|
static wxString ToString(long val, int flags = Style_WithThousandsSep);
|
||||||
static wxString ToString(long long val, int flags = Style_WithThousandsSep);
|
static wxString ToString(long long val, int flags = Style_WithThousandsSep);
|
||||||
|
static wxString ToString(unsigned long long val, int flags = Style_WithThousandsSep);
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -97,11 +98,18 @@ public:
|
|||||||
success they return @true and store the result at the location pointed
|
success they return @true and store the result at the location pointed
|
||||||
to by @a val (which can't be @NULL), otherwise @false is returned.
|
to by @a val (which can't be @NULL), otherwise @false is returned.
|
||||||
|
|
||||||
|
Note that the overload taking unsigned long long value is only
|
||||||
|
available since wxWidgets 3.1.5. Also, unlike wxString::ToULongLong()
|
||||||
|
and the standard functions such as @c strtoul(), this overload does
|
||||||
|
@em not accept, i.e. returns @false, for the strings starting with the
|
||||||
|
minus sign.
|
||||||
|
|
||||||
@see wxString::ToLong(), wxString::ToDouble()
|
@see wxString::ToLong(), wxString::ToDouble()
|
||||||
*/
|
*/
|
||||||
//@{
|
//@{
|
||||||
static bool FromString(wxString s, long *val);
|
static bool FromString(wxString s, long *val);
|
||||||
static bool FromString(wxString s, long long *val);
|
static bool FromString(wxString s, long long *val);
|
||||||
|
static bool FromString(wxString s, unsigned long long *val);
|
||||||
static bool FromString(wxString s, double *val);
|
static bool FromString(wxString s, double *val);
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
@@ -198,6 +198,12 @@ wxString wxNumberFormatter::ToString(wxLongLong_t val, int style)
|
|||||||
|
|
||||||
#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
||||||
|
|
||||||
|
wxString wxNumberFormatter::ToString(wxULongLong_t val, int style)
|
||||||
|
{
|
||||||
|
return PostProcessIntString(wxString::Format("%" wxLongLongFmtSpec "u", val),
|
||||||
|
style);
|
||||||
|
}
|
||||||
|
|
||||||
wxString wxNumberFormatter::ToString(double val, int precision, int style)
|
wxString wxNumberFormatter::ToString(double val, int precision, int style)
|
||||||
{
|
{
|
||||||
wxString s = wxString::FromDouble(val,precision);
|
wxString s = wxString::FromDouble(val,precision);
|
||||||
@@ -300,6 +306,27 @@ bool wxNumberFormatter::FromString(wxString s, wxLongLong_t *val)
|
|||||||
|
|
||||||
#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
||||||
|
|
||||||
|
bool wxNumberFormatter::FromString(wxString s, wxULongLong_t *val)
|
||||||
|
{
|
||||||
|
RemoveThousandsSeparators(s);
|
||||||
|
|
||||||
|
// wxString::ToULongLong() does accept minus sign for unsigned integers,
|
||||||
|
// consistently with the standard functions behaviour, e.g. strtoul() does
|
||||||
|
// the same thing, but here we really want to accept the "true" unsigned
|
||||||
|
// numbers only, so check for leading minus, possibly preceded by some
|
||||||
|
// whitespace.
|
||||||
|
for ( wxString::const_iterator it = s.begin(); it != s.end(); ++it )
|
||||||
|
{
|
||||||
|
if ( *it == '-' )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( *it != ' ' && *it != '\t' )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.ToULongLong(val);
|
||||||
|
}
|
||||||
|
|
||||||
bool wxNumberFormatter::FromString(wxString s, double *val)
|
bool wxNumberFormatter::FromString(wxString s, double *val)
|
||||||
{
|
{
|
||||||
RemoveThousandsSeparators(s);
|
RemoveThousandsSeparators(s);
|
||||||
|
@@ -206,6 +206,10 @@ TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::LongLongFromString", "[num
|
|||||||
CHECK( !wxNumberFormatter::FromString("", &l) );
|
CHECK( !wxNumberFormatter::FromString("", &l) );
|
||||||
CHECK( !wxNumberFormatter::FromString("foo", &l) );
|
CHECK( !wxNumberFormatter::FromString("foo", &l) );
|
||||||
CHECK( !wxNumberFormatter::FromString("1.234", &l) );
|
CHECK( !wxNumberFormatter::FromString("1.234", &l) );
|
||||||
|
CHECK( !wxNumberFormatter::FromString("-", &l) );
|
||||||
|
|
||||||
|
CHECK( wxNumberFormatter::FromString("0", &l) );
|
||||||
|
CHECK( l == 0 );
|
||||||
|
|
||||||
CHECK( wxNumberFormatter::FromString("123", &l) );
|
CHECK( wxNumberFormatter::FromString("123", &l) );
|
||||||
CHECK( l == 123 );
|
CHECK( l == 123 );
|
||||||
@@ -224,10 +228,63 @@ TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::LongLongFromString", "[num
|
|||||||
|
|
||||||
CHECK( wxNumberFormatter::FromString("1,234,567", &l) );
|
CHECK( wxNumberFormatter::FromString("1,234,567", &l) );
|
||||||
CHECK( l == 1234567 );
|
CHECK( l == 1234567 );
|
||||||
|
|
||||||
|
CHECK( wxNumberFormatter::FromString("-123", &l) );
|
||||||
|
CHECK( l == -123 );
|
||||||
|
|
||||||
|
CHECK( wxNumberFormatter::FromString("9223372036854775807", &l) );
|
||||||
|
CHECK( l == wxINT64_MAX );
|
||||||
|
|
||||||
|
CHECK( !wxNumberFormatter::FromString("9223372036854775808", &l) );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
|
||||||
|
|
||||||
|
TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::ULongLongFromString", "[numformatter]")
|
||||||
|
{
|
||||||
|
if ( !CanRunTest() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxULongLong_t u;
|
||||||
|
CHECK( !wxNumberFormatter::FromString("", &u) );
|
||||||
|
CHECK( !wxNumberFormatter::FromString("bar", &u) );
|
||||||
|
CHECK( !wxNumberFormatter::FromString("1.234", &u) );
|
||||||
|
CHECK( !wxNumberFormatter::FromString("-2", &u) );
|
||||||
|
CHECK( !wxNumberFormatter::FromString("-", &u) );
|
||||||
|
|
||||||
|
CHECK( wxNumberFormatter::FromString("0", &u) );
|
||||||
|
CHECK( u == 0 );
|
||||||
|
|
||||||
|
CHECK( wxNumberFormatter::FromString("123", &u) );
|
||||||
|
CHECK( u == 123 );
|
||||||
|
|
||||||
|
CHECK( wxNumberFormatter::FromString("1234", &u) );
|
||||||
|
CHECK( u == 1234 );
|
||||||
|
|
||||||
|
CHECK( wxNumberFormatter::FromString("1,234", &u) );
|
||||||
|
CHECK( u == 1234 );
|
||||||
|
|
||||||
|
CHECK( wxNumberFormatter::FromString("12,345", &u) );
|
||||||
|
CHECK( u == 12345 );
|
||||||
|
|
||||||
|
CHECK( wxNumberFormatter::FromString("123,456", &u) );
|
||||||
|
CHECK( u == 123456 );
|
||||||
|
|
||||||
|
CHECK( wxNumberFormatter::FromString("1,234,567", &u) );
|
||||||
|
CHECK( u == 1234567 );
|
||||||
|
|
||||||
|
CHECK( wxNumberFormatter::FromString("9223372036854775807", &u) );
|
||||||
|
CHECK( u == static_cast<wxULongLong_t>(wxINT64_MAX) );
|
||||||
|
|
||||||
|
CHECK( wxNumberFormatter::FromString("9223372036854775808", &u) );
|
||||||
|
CHECK( u == static_cast<wxULongLong_t>(wxINT64_MAX) + 1 );
|
||||||
|
|
||||||
|
CHECK( wxNumberFormatter::FromString("18446744073709551615", &u) );
|
||||||
|
CHECK( u == wxUINT64_MAX );
|
||||||
|
|
||||||
|
CHECK( !wxNumberFormatter::FromString("18446744073709551616", &u) );
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::DoubleFromString", "[numformatter]")
|
TEST_CASE_METHOD(NumFormatterTestCase, "NumFormatter::DoubleFromString", "[numformatter]")
|
||||||
{
|
{
|
||||||
if ( !CanRunTest() )
|
if ( !CanRunTest() )
|
||||||
|
Reference in New Issue
Block a user