diff --git a/UnitTests/pch.hpp b/UnitTests/pch.hpp index ce7d17ed7..56c123dcb 100644 --- a/UnitTests/pch.hpp +++ b/UnitTests/pch.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/include/stdex/chrono.hpp b/include/stdex/chrono.hpp index 1e802b0f2..352dd5164 100644 --- a/include/stdex/chrono.hpp +++ b/include/stdex/chrono.hpp @@ -8,7 +8,7 @@ #include "compat.hpp" #include "math.hpp" #include "system.hpp" -#include "string.hpp" +#include "locale.hpp" #include #include #include diff --git a/include/stdex/locale.hpp b/include/stdex/locale.hpp new file mode 100644 index 000000000..2def763ac --- /dev/null +++ b/include/stdex/locale.hpp @@ -0,0 +1,70 @@ +/* + SPDX-License-Identifier: MIT + Copyright © 2016-2023 Amebis +*/ + +#pragma once + +#include "compat.hpp" +#include +#include + +namespace stdex +{ +#ifdef _WIN32 + using locale_t = _locale_t; + + inline locale_t create_locale(_In_ int category, _In_z_ const char* locale) { return _create_locale(category, locale); } + inline locale_t create_locale(_In_ int category, _In_z_ const wchar_t* locale) { return _wcreate_locale(category, locale); } + inline void free_locale(_In_opt_ locale_t locale) { _free_locale(locale); } +#else + using locale_t = ::locale_t; + + inline locale_t create_locale(_In_ int category, _In_z_ const char* locale) + { + int mask = 0; + switch (category) { + case LC_ALL : mask = LC_ALL_MASK ; break; + case LC_COLLATE : mask = LC_COLLATE_MASK ; break; + case LC_CTYPE : mask = LC_CTYPE_MASK ; break; + case LC_MESSAGES: mask = LC_MESSAGES_MASK; break; + case LC_MONETARY: mask = LC_MONETARY_MASK; break; + case LC_NUMERIC : mask = LC_NUMERIC_MASK ; break; + case LC_TIME : mask = LC_TIME_MASK ; break; + } + return newlocale(mask, locale, LC_GLOBAL_LOCALE); + } + + inline void free_locale(_In_opt_ locale_t locale) { freelocale(locale); } +#endif + + /// + /// Deleter for unique_ptr using free_locale + /// + struct free_locale_delete + { + /// + /// Delete a pointer + /// + void operator()(_In_ locale_t locale) const + { + free_locale(locale); + } + }; + + /// + /// locale_t helper class to free_locale when going out of scope + /// +#if defined(_WIN32) + using locale = std::unique_ptr<__crt_locale_pointers, free_locale_delete>; +#elif defined(__APPLE__) + using locale = std::unique_ptr; +#else + using locale = std::unique_ptr; +#endif + + /// + /// Reusable C locale + /// + const locale locale_C(create_locale(LC_ALL, "C")); +} \ No newline at end of file diff --git a/include/stdex/stream.hpp b/include/stdex/stream.hpp index a55eaf8b7..ebdd38359 100644 --- a/include/stdex/stream.hpp +++ b/include/stdex/stream.hpp @@ -8,6 +8,7 @@ #include "compat.hpp" #include "endian.hpp" #include "interval.hpp" +#include "locale.hpp" #include "math.hpp" #include "ring.hpp" #include "string.hpp" diff --git a/include/stdex/string.hpp b/include/stdex/string.hpp index 877dd4dfd..d5b990838 100644 --- a/include/stdex/string.hpp +++ b/include/stdex/string.hpp @@ -6,8 +6,8 @@ #pragma once #include "compat.hpp" +#include "locale.hpp" #include -#include #include #include #include @@ -19,68 +19,10 @@ #include #include #include -#include #include namespace stdex { -#ifdef _WIN32 - using locale_t = _locale_t; - - inline locale_t create_locale(_In_ int category, _In_z_ const char* locale) { return _create_locale(category, locale); } - inline locale_t create_locale(_In_ int category, _In_z_ const wchar_t* locale) { return _wcreate_locale(category, locale); } - inline void free_locale(_In_opt_ locale_t locale) { _free_locale(locale); } -#else - using locale_t = ::locale_t; - - inline locale_t create_locale(_In_ int category, _In_z_ const char* locale) - { - int mask = 0; - switch (category) { - case LC_ALL : mask = LC_ALL_MASK ; break; - case LC_COLLATE : mask = LC_COLLATE_MASK ; break; - case LC_CTYPE : mask = LC_CTYPE_MASK ; break; - case LC_MESSAGES: mask = LC_MESSAGES_MASK; break; - case LC_MONETARY: mask = LC_MONETARY_MASK; break; - case LC_NUMERIC : mask = LC_NUMERIC_MASK ; break; - case LC_TIME : mask = LC_TIME_MASK ; break; - } - return newlocale(mask, locale, LC_GLOBAL_LOCALE); - } - - inline void free_locale(_In_opt_ locale_t locale) { freelocale(locale); } -#endif - - /// - /// Deleter for unique_ptr using free_locale - /// - struct free_locale_delete - { - /// - /// Delete a pointer - /// - void operator()(_In_ locale_t locale) const - { - free_locale(locale); - } - }; - - /// - /// locale_t helper class to free_locale when going out of scope - /// -#if defined(_WIN32) - using locale = std::unique_ptr<__crt_locale_pointers, free_locale_delete>; -#elif defined(__APPLE__) - using locale = std::unique_ptr; -#else - using locale = std::unique_ptr; -#endif - - /// - /// Reusable C locale - /// - const locale locale_C(create_locale(LC_ALL, "C")); - /// /// UTF-16 code unit ///