diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index e067a5a839..fc9cdad6ae 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -269,6 +269,7 @@ target_link_libraries( kicommon kiplatform nlohmann_json nlohmann_json_schema_validator + FastFloat::fast_float fmt::fmt CURL::libcurl picosha2 diff --git a/common/dsnlexer.cpp b/common/dsnlexer.cpp index a9c5dfabe5..d5ddf5f90b 100644 --- a/common/dsnlexer.cpp +++ b/common/dsnlexer.cpp @@ -22,7 +22,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include +#include #include #include #include // bsearch() @@ -861,43 +861,13 @@ wxArrayString* DSNLEXER::ReadCommentLines() double DSNLEXER::parseDouble() { -// We try here to be locale independent to avoid the need to switch to a "C" locale -#if ( defined( __GNUC__ ) && __GNUC__ < 11 ) || ( defined( __clang__ ) && __clang_major__ < 13 ) - // GCC older than 11 "supports" C++17 without supporting the C++17 std::from_chars for doubles - // clang is similar - - // Use wxString::ToCDouble() which is designed to be locale independent - wxString tmp = CurStr(); - double fval; - bool success = tmp.ToCDouble( &fval ); - - if( !success ) - { - wxString error; - error.Printf( _( "Invalid floating point number in\nfile: '%s'\nline: %d\noffset: %d" ), - CurSource(), CurLineNumber(), CurOffset() ); - - THROW_IO_ERROR( error ); - } - - return fval; -#else - // Use std::from_chars which is designed to be locale independent and performance oriented - // for data interchange - + // Use fast_float::from_chars which is designed to be locale independent and significantly + // faster than strtod and std::from_chars const std::string& str = CurStr(); - // Offset any leading whitespace, this is one thing from_chars does not handle - size_t woff = 0; - - while( std::isspace( str[woff] ) && woff < str.length() ) - { - woff++; - } - double dval{}; - std::from_chars_result res = - std::from_chars( str.data() + woff, str.data() + str.size(), dval ); + fast_float::from_chars_result res = fast_float::from_chars( str.data(), str.data() + str.size(), dval, + fast_float::chars_format::skip_white_space ); if( res.ec != std::errc() ) { @@ -906,5 +876,4 @@ double DSNLEXER::parseDouble() } return dval; -#endif } diff --git a/eeschema/sim/sim_value.cpp b/eeschema/sim/sim_value.cpp index 47024a3314..4adba80cf7 100644 --- a/eeschema/sim/sim_value.cpp +++ b/eeschema/sim/sim_value.cpp @@ -22,7 +22,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include +#include #include #include #include @@ -382,22 +382,20 @@ std::string SIM_VALUE::ConvertNotation( const std::string& aString, NOTATION aFr int exponent = parseResult.exponent ? *parseResult.exponent : 0; exponent += parseResult.unitPrefixExponent ? *parseResult.unitPrefixExponent : 0; - try - { - int expReduction = 0; - std::string prefix = SIM_VALUE_PARSER::ExponentToUnitPrefix( exponent, expReduction, - aToNotation ); - double significand{}; - wxString( parseResult.significand ).ToCDouble( &significand ); + int expReduction = 0; + std::string prefix = SIM_VALUE_PARSER::ExponentToUnitPrefix( exponent, expReduction, + aToNotation ); + double significand{}; - exponent -= expReduction; - return fmt::format( "{:g}{}", significand * std::pow( 10, exponent ), - prefix ); - } - catch( const std::invalid_argument& ) - { - // best efforts - } + fast_float::from_chars( + parseResult.significand.data(), + parseResult.significand.data() + parseResult.significand.size(), + significand, + fast_float::chars_format::skip_white_space | fast_float::chars_format::allow_leading_plus ); + + exponent -= expReduction; + return fmt::format( "{:g}{}", significand * std::pow( 10, exponent ), + prefix ); } return aString; @@ -446,19 +444,17 @@ double SIM_VALUE::ToDouble( const std::string& aString, double aDefault ) if( parseResult.isOk && !parseResult.isEmpty && !parseResult.significand.empty() ) { - try - { - LOCALE_IO toggle; - int exponent = parseResult.exponent ? *parseResult.exponent : 0; + int exponent = parseResult.exponent ? *parseResult.exponent : 0; - exponent += parseResult.unitPrefixExponent ? *parseResult.unitPrefixExponent : 0; + exponent += parseResult.unitPrefixExponent ? *parseResult.unitPrefixExponent : 0; + double significand{}; - return std::stod( parseResult.significand ) * std::pow( 10, exponent ); - } - catch( const std::invalid_argument& ) - { - // best efforts - } + fast_float::from_chars( parseResult.significand.data(), + parseResult.significand.data() + parseResult.significand.size(), + significand, + fast_float::chars_format::skip_white_space | fast_float::chars_format::allow_leading_plus ); + + return significand * std::pow( 10, exponent ); } return aDefault; diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt index ca753778f9..5084de6959 100644 --- a/thirdparty/CMakeLists.txt +++ b/thirdparty/CMakeLists.txt @@ -48,6 +48,8 @@ add_subdirectory( delaunator ) add_subdirectory( dxflib_qcad ) add_subdirectory( dynamic_bitset ) add_subdirectory( expected ) +set( FASTFLOAT_INSTALL OFF ) +add_subdirectory( fast_float ) set( FMT_INSTALL OFF ) add_subdirectory( fmt ) add_subdirectory( gzip-hpp )