From fe94a3c8c5b9769041aa2a311c25efc2b5d9f16c Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 13 Sep 2021 20:46:19 +0200 Subject: [PATCH] LocalesUtils: fixed BSD and improved performance of decimal point formatting functions --- src/libslic3r/LocalesUtils.cpp | 43 +++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/src/libslic3r/LocalesUtils.cpp b/src/libslic3r/LocalesUtils.cpp index 64ab700ed..8c42a36ba 100644 --- a/src/libslic3r/LocalesUtils.cpp +++ b/src/libslic3r/LocalesUtils.cpp @@ -1,7 +1,13 @@ #include "LocalesUtils.hpp" +#ifdef _WIN32 + #include +#endif #include +#include + + namespace Slic3r { @@ -11,15 +17,15 @@ CNumericLocalesSetter::CNumericLocalesSetter() _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); m_orig_numeric_locale = std::setlocale(LC_NUMERIC, nullptr); std::setlocale(LC_NUMERIC, "C"); -#elif __linux__ +#elif __APPLE__ + m_original_locale = uselocale((locale_t)0); + m_new_locale = newlocale(LC_NUMERIC_MASK, "C", m_original_locale); + uselocale(m_new_locale); +#else // linux / BSD m_original_locale = uselocale((locale_t)0); m_new_locale = duplocale(m_original_locale); m_new_locale = newlocale(LC_NUMERIC_MASK, "C", m_new_locale); uselocale(m_new_locale); -#else // APPLE - m_original_locale = uselocale((locale_t)0); - m_new_locale = newlocale(LC_NUMERIC_MASK, "C", m_original_locale); - uselocale(m_new_locale); #endif } @@ -48,25 +54,34 @@ bool is_decimal_separator_point() double string_to_double_decimal_point(const std::string& str, size_t* pos /* = nullptr*/) { double out; - std::istringstream stream(str); - if (! (stream >> out)) - throw std::invalid_argument("string_to_double_decimal_point conversion failed."); - if (pos) { - if (stream.eof()) - *pos = str.size(); - else - *pos = stream.tellg(); - } + size_t p = fast_float::from_chars(str.data(), str.data() + str.size(), out).ptr - str.data(); + if (pos) + *pos = p; return out; } std::string float_to_string_decimal_point(double value, int precision/* = -1*/) { + // Our Windows build server fully supports C++17 std::to_chars. Let's use it. + // Other platforms are behind, fall back to slow stringstreams for now. +#ifdef _WIN32 + constexpr size_t SIZE = 20; + char out[SIZE] = ""; + std::to_chars_result res; + if (precision >=0) + res = std::to_chars(out, out+SIZE, value, std::chars_format::fixed, precision); + else + res = std::to_chars(out, out+SIZE, value, std::chars_format::general, 6); + if (res.ec == std::errc::value_too_large) + throw std::invalid_argument("float_to_string_decimal_point conversion failed."); + return std::string(out, res.ptr - out); +#else std::stringstream buf; if (precision >= 0) buf << std::fixed << std::setprecision(precision); buf << value; return buf.str(); +#endif }