diff options
author | Lukas Matena <lukasmatena@seznam.cz> | 2021-05-03 17:00:46 +0300 |
---|---|---|
committer | Lukas Matena <lukasmatena@seznam.cz> | 2021-05-24 13:20:29 +0300 |
commit | 5a1441f9b7b9bb6d35b97ad9cbc25a94c2700d7b (patch) | |
tree | 7a25ac93c73ee806e3b00c1827f9ba4b276959f5 /src | |
parent | 9da87d8e0f0730fac93f6f3bd956ace8b1f3c7b5 (diff) |
Created a RAII class to switch LC_NUMERIC to "C" and back
Diffstat (limited to 'src')
-rw-r--r-- | src/libslic3r/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/libslic3r/LocalesUtils.cpp | 59 | ||||
-rw-r--r-- | src/libslic3r/LocalesUtils.hpp | 47 |
3 files changed, 108 insertions, 0 deletions
diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index d98d0e10f..b7b90a8f5 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -126,6 +126,8 @@ add_library(libslic3r STATIC Line.hpp LibraryCheck.cpp LibraryCheck.hpp + LocalesUtils.cpp + LocalesUtils.hpp Model.cpp Model.hpp ModelArrange.hpp diff --git a/src/libslic3r/LocalesUtils.cpp b/src/libslic3r/LocalesUtils.cpp new file mode 100644 index 000000000..d98145e4b --- /dev/null +++ b/src/libslic3r/LocalesUtils.cpp @@ -0,0 +1,59 @@ +#include "LocalesUtils.hpp" + + +namespace Slic3r { + + +CNumericLocalesSetter::CNumericLocalesSetter() +{ +#ifdef _WIN32 + _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); + m_orig_numeric_locale = std::setlocale(LC_NUMERIC, nullptr); + std::setlocale(LC_NUMERIC, "C"); +#else + 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); +#endif +} + + + +CNumericLocalesSetter::~CNumericLocalesSetter() +{ +#ifdef _WIN32 + std::setlocale(LC_NUMERIC, m_orig_numeric_locale) +#else + uselocale(m_original_locale); + freelocale(m_new_locale); +#endif +} + + + +bool is_decimal_separator_point() +{ + char str[5] = ""; + sprintf(str, "%.1f", 0.5f); + return str[1] == '.'; +} + +std::string float_to_string_decimal_point(double value, int precision/* = -1*/) +{ + assert(is_decimal_separator_point()); + std::stringstream buf; + if (precision >= 0) + buf << std::fixed << std::setprecision(precision); + buf << value; + return buf.str(); +} + +std::string float_to_string_decimal_point(float value, int precision/* = -1*/) +{ + return float_to_string_decimal_point(double(value), precision); +} + + +} // namespace Slic3r + diff --git a/src/libslic3r/LocalesUtils.hpp b/src/libslic3r/LocalesUtils.hpp new file mode 100644 index 000000000..74281a157 --- /dev/null +++ b/src/libslic3r/LocalesUtils.hpp @@ -0,0 +1,47 @@ +#ifndef slic3r_LocalesUtils_hpp_ +#define slic3r_LocalesUtils_hpp_ + +#include <string> +#include <clocale> +#include <iomanip> +#include <cassert> + +#ifdef __APPLE__ +#include <xlocale.h> +#endif + +namespace Slic3r { + +// RAII wrapper that sets LC_NUMERIC to "C" on construction +// and restores the old value on destruction. +class CNumericLocalesSetter { +public: + CNumericLocalesSetter(); + ~CNumericLocalesSetter(); + +private: +#ifdef _WIN32 + std::string m_orig_numeric_locale; +#else + locale_t m_original_locale; + locale_t m_new_locale; +#endif + +}; + +// A function to check that current C locale uses decimal point as a separator. +// Intended mostly for asserts. +bool is_decimal_separator_point(); + + +// A substitute for std::to_string that works according to +// C++ locales, not C locale. Meant to be used when we need +// to be sure that decimal point is used as a separator. +// (We use user C locales and "C" C++ locales in most of the code.) +std::string float_to_string_decimal_point(double value, int precision = -1); +std::string float_to_string_decimal_point(float value, int precision = -1); + + +} // namespace Slic3r + +#endif // slic3r_LocalesUtils_hpp_ |