diff options
author | Lukas Matena <lukasmatena@seznam.cz> | 2021-09-13 21:46:19 +0300 |
---|---|---|
committer | Lukas Matena <lukasmatena@seznam.cz> | 2021-09-15 20:52:32 +0300 |
commit | fe94a3c8c5b9769041aa2a311c25efc2b5d9f16c (patch) | |
tree | df22bccf3bed9e8182698ed32e44b9203f65e947 /src/libslic3r | |
parent | aef90bc735bd0df3a9737b2ff86cd22caf56b78b (diff) |
LocalesUtils: fixed BSD and improved performance of decimal point formatting functions
Diffstat (limited to 'src/libslic3r')
-rw-r--r-- | src/libslic3r/LocalesUtils.cpp | 43 |
1 files 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 <charconv> +#endif #include <stdexcept> +#include <fast_float/fast_float.h> + + namespace Slic3r { @@ -11,14 +17,14 @@ 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 = duplocale(m_original_locale); - m_new_locale = newlocale(LC_NUMERIC_MASK, "C", m_new_locale); + m_new_locale = newlocale(LC_NUMERIC_MASK, "C", m_original_locale); uselocale(m_new_locale); -#else // APPLE +#else // linux / BSD m_original_locale = uselocale((locale_t)0); - m_new_locale = newlocale(LC_NUMERIC_MASK, "C", m_original_locale); + m_new_locale = duplocale(m_original_locale); + m_new_locale = newlocale(LC_NUMERIC_MASK, "C", m_new_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 } |