diff --git a/src/common/string.cpp b/src/common/string.cpp index f2949268e3..4dd1dc7e91 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -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; } diff --git a/tests/strings/strings.cpp b/tests/strings/strings.cpp index e8f0550a3f..3d8798699f 100644 --- a/tests/strings/strings.cpp +++ b/tests/strings/strings.cpp @@ -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]")