Restore ToCDouble compatibility with leading spaces/+ and hex
The previous ToCDouble() function accepted leading spaces, a starting + sign, and hex strings. std::from_chars() does not accept spaces or +, and requires a special flag to convert hex strings, so handle this manually to preserve the old behaviour of this function. This is similar to the changes done for ToCULong() in #24022. Closes #24089.
This commit is contained in:
parent
b5fea3cbf6
commit
97cba7c0ca
2 changed files with 58 additions and 2 deletions
|
|
@ -1678,9 +1678,20 @@ bool wxString::ToCDouble(double *pVal) const
|
|||
wxCHECK_MSG( pVal, false, "null output pointer" );
|
||||
|
||||
const wxScopedCharBuffer& buf = utf8_str();
|
||||
const auto start = buf.data();
|
||||
auto start = buf.data();
|
||||
const auto end = start + buf.length();
|
||||
const auto res = std::from_chars(start, end, *pVal);
|
||||
|
||||
// Retain compatibility with the strtod() function by allowing starting spaces
|
||||
// and a leading + sign, which from_chars() does not accept.
|
||||
int base = 0;
|
||||
SkipOptPrefixAndSetBase(base, start, end);
|
||||
|
||||
std::chars_format flags = std::chars_format::general;
|
||||
|
||||
if ( base == 16 )
|
||||
flags = std::chars_format::hex;
|
||||
|
||||
const auto res = std::from_chars(start, end, *pVal, flags);
|
||||
|
||||
return res.ec == std::errc{} && res.ptr == end;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -804,6 +804,17 @@ TEST_CASE("StringToDouble", "[wxString]")
|
|||
{ wxT("--1"), 0, false },
|
||||
{ wxT("-3E-5"), -3E-5, true },
|
||||
{ wxT("-3E-abcde5"), 0, false },
|
||||
|
||||
{ wxT(" 1"), 1, true },
|
||||
{ wxT(" .1"), .1, true },
|
||||
{ wxT(" -1.2"), -1.2, true },
|
||||
|
||||
// printf can output + in a valid double/float string
|
||||
{ wxT("+1"), 1, true },
|
||||
{ wxT("+.1"), 0.1, true },
|
||||
{ wxT("++1"), 0, false },
|
||||
|
||||
{ wxT("0X1.BC70A3D70A3D7p+6"), 111.11, true },
|
||||
};
|
||||
|
||||
// test ToCDouble() first:
|
||||
|
|
@ -817,6 +828,18 @@ TEST_CASE("StringToDouble", "[wxString]")
|
|||
CHECK( d == ld.value );
|
||||
}
|
||||
|
||||
CHECK( wxString("inf").ToCDouble(&d) );
|
||||
CHECK( std::isinf(d) );
|
||||
|
||||
CHECK( wxString("INFINITY").ToCDouble(&d) );
|
||||
CHECK( std::isinf(d) );
|
||||
|
||||
CHECK( wxString("nan").ToCDouble(&d) );
|
||||
CHECK( std::isnan(d) );
|
||||
|
||||
CHECK( wxString("NAN").ToCDouble(&d) );
|
||||
CHECK( std::isnan(d) );
|
||||
|
||||
|
||||
// test ToDouble() now:
|
||||
// NOTE: for the test to be reliable, we need to set the locale explicitly
|
||||
|
|
@ -844,6 +867,16 @@ TEST_CASE("StringToDouble", "[wxString]")
|
|||
{ wxT("--1"), 0, false },
|
||||
{ wxT("-3E-5"), -3E-5, true },
|
||||
{ wxT("-3E-abcde5"), 0, false },
|
||||
|
||||
{ wxT(" 1"), 1, true },
|
||||
{ wxT(" ,1"), .1, true },
|
||||
|
||||
// printf can output + in a valid double/float string
|
||||
{ wxT("+1"), 1, true },
|
||||
{ wxT("+,1"), 0.1, true },
|
||||
{ wxT("++1"), 0, false },
|
||||
|
||||
{ wxT("0X1,BC70A3D70A3D7P+6"), 111.11, true },
|
||||
};
|
||||
|
||||
for ( n = 0; n < WXSIZEOF(doubleData2); n++ )
|
||||
|
|
@ -853,6 +886,18 @@ TEST_CASE("StringToDouble", "[wxString]")
|
|||
if ( ld.ok )
|
||||
CHECK( d == ld.value );
|
||||
}
|
||||
|
||||
CHECK( wxString("inf").ToDouble(&d) );
|
||||
CHECK( std::isinf(d) );
|
||||
|
||||
CHECK( wxString("INFINITY").ToDouble(&d) );
|
||||
CHECK( std::isinf(d) );
|
||||
|
||||
CHECK( wxString("nan").ToDouble(&d) );
|
||||
CHECK( std::isnan(d) );
|
||||
|
||||
CHECK( wxString("NAN").ToDouble(&d) );
|
||||
CHECK( std::isnan(d) );
|
||||
}
|
||||
|
||||
TEST_CASE("StringFromDouble", "[wxString]")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue