From f4c95f6dd9a500103f9b6a3fb552aad63048bfe6 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Thu, 3 Jun 2021 17:40:00 -0700 Subject: [PATCH] Improve handling of thousands separator --- include/fmt/format-inl.h | 15 +++++---------- include/fmt/format.h | 40 +++++++++++++++++++--------------------- src/format.cc | 8 ++++---- 3 files changed, 28 insertions(+), 35 deletions(-) diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index 5e796bd5..c90d9773 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -103,23 +103,18 @@ template Locale locale_ref::get() const { return locale_ ? *static_cast(locale_) : std::locale(); } -template FMT_FUNC std::string grouping_impl(locale_ref loc) { - return std::use_facet>(loc.get()).grouping(); -} -template FMT_FUNC Char thousands_sep_impl(locale_ref loc) { - return std::use_facet>(loc.get()) - .thousands_sep(); +template +FMT_FUNC auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result { + auto& facet = std::use_facet>(loc.get()); + return {facet.grouping(), facet.thousands_sep()}; } template FMT_FUNC Char decimal_point_impl(locale_ref loc) { return std::use_facet>(loc.get()) .decimal_point(); } #else -template FMT_FUNC std::string grouping_impl(locale_ref) { - return "\03"; -} template FMT_FUNC Char thousands_sep_impl(locale_ref) { - return FMT_STATIC_THOUSANDS_SEPARATOR; + return {"\03", FMT_STATIC_THOUSANDS_SEPARATOR}; } template FMT_FUNC Char decimal_point_impl(locale_ref) { return '.'; diff --git a/include/fmt/format.h b/include/fmt/format.h index e14658da..2468f2f1 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -1015,22 +1015,20 @@ template <> constexpr auto digits10() FMT_NOEXCEPT -> int { return 38; } -// DEPRECATED! grouping will be merged into thousands_sep. -template -FMT_API auto grouping_impl(locale_ref loc) -> std::string; -template inline auto grouping(locale_ref loc) -> std::string { - return grouping_impl(loc); -} -template <> inline auto grouping(locale_ref loc) -> std::string { - return grouping_impl(loc); -} +template struct thousands_sep_result { + std::string grouping; + Char thousands_sep; +}; template -FMT_API auto thousands_sep_impl(locale_ref loc) -> Char; -template inline auto thousands_sep(locale_ref loc) -> Char { - return Char(thousands_sep_impl(loc)); +FMT_API auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result; +template +inline auto thousands_sep(locale_ref loc) -> thousands_sep_result { + auto result = thousands_sep_impl(loc); + return {result.grouping, Char(result.thousands_sep)}; } -template <> inline auto thousands_sep(locale_ref loc) -> wchar_t { +template <> +inline auto thousands_sep(locale_ref loc) -> thousands_sep_result { return thousands_sep_impl(loc); } @@ -1419,10 +1417,10 @@ auto write_int_localized(OutputIt& out, UInt value, unsigned prefix, -> bool { static_assert(std::is_same, UInt>::value, ""); const auto sep_size = 1; - std::string groups = grouping(loc); - if (groups.empty()) return false; - auto sep = thousands_sep(loc); - if (!sep) return false; + auto ts = thousands_sep(loc); + const std::string& groups = ts.grouping; + Char sep = ts.thousands_sep; + if (!sep || groups.empty()) return false; int num_digits = count_digits(value); int size = num_digits, n = num_digits; std::string::const_iterator group = groups.cbegin(); @@ -2736,10 +2734,10 @@ extern template void vformat_to(detail::buffer&, string_view, basic_format_args, detail::locale_ref); -extern template FMT_API auto grouping_impl(locale_ref) -> std::string; -extern template FMT_API auto grouping_impl(locale_ref) -> std::string; -extern template FMT_API auto thousands_sep_impl(locale_ref) -> char; -extern template FMT_API auto thousands_sep_impl(locale_ref) -> wchar_t; +extern template FMT_API auto thousands_sep_impl(locale_ref) + -> thousands_sep_result; +extern template FMT_API auto thousands_sep_impl(locale_ref) + -> thousands_sep_result; extern template FMT_API auto decimal_point_impl(locale_ref) -> char; extern template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t; extern template auto format_float(double value, int precision, diff --git a/src/format.cc b/src/format.cc index c56cd31d..187dcb73 100644 --- a/src/format.cc +++ b/src/format.cc @@ -41,8 +41,8 @@ template FMT_API std::locale detail::locale_ref::get() const; // Explicit instantiations for char. -template FMT_API std::string detail::grouping_impl(locale_ref); -template FMT_API char detail::thousands_sep_impl(locale_ref); +template FMT_API auto detail::thousands_sep_impl(locale_ref) + -> thousands_sep_result; template FMT_API char detail::decimal_point_impl(locale_ref); template FMT_API void detail::buffer::append(const char*, const char*); @@ -63,8 +63,8 @@ template FMT_API int detail::format_float(long double, int, detail::float_specs, // Explicit instantiations for wchar_t. -template FMT_API std::string detail::grouping_impl(locale_ref); -template FMT_API wchar_t detail::thousands_sep_impl(locale_ref); +template FMT_API auto detail::thousands_sep_impl(locale_ref) + -> thousands_sep_result; template FMT_API wchar_t detail::decimal_point_impl(locale_ref); template FMT_API void detail::buffer::append(const wchar_t*,