Improve handling of thousands separator

This commit is contained in:
Victor Zverovich
2021-06-03 17:40:00 -07:00
parent d4fbeacc33
commit f4c95f6dd9
3 changed files with 28 additions and 35 deletions

View File

@ -103,23 +103,18 @@ template <typename Locale> Locale locale_ref::get() const {
return locale_ ? *static_cast<const std::locale*>(locale_) : std::locale(); return locale_ ? *static_cast<const std::locale*>(locale_) : std::locale();
} }
template <typename Char> FMT_FUNC std::string grouping_impl(locale_ref loc) { template <typename Char>
return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>()).grouping(); FMT_FUNC auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result<Char> {
} auto& facet = std::use_facet<std::numpunct<Char>>(loc.get<std::locale>());
template <typename Char> FMT_FUNC Char thousands_sep_impl(locale_ref loc) { return {facet.grouping(), facet.thousands_sep()};
return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>())
.thousands_sep();
} }
template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref loc) { template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref loc) {
return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>()) return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>())
.decimal_point(); .decimal_point();
} }
#else #else
template <typename Char> FMT_FUNC std::string grouping_impl(locale_ref) {
return "\03";
}
template <typename Char> FMT_FUNC Char thousands_sep_impl(locale_ref) { template <typename Char> FMT_FUNC Char thousands_sep_impl(locale_ref) {
return FMT_STATIC_THOUSANDS_SEPARATOR; return {"\03", FMT_STATIC_THOUSANDS_SEPARATOR};
} }
template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref) { template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref) {
return '.'; return '.';

View File

@ -1015,22 +1015,20 @@ template <> constexpr auto digits10<uint128_t>() FMT_NOEXCEPT -> int {
return 38; return 38;
} }
// DEPRECATED! grouping will be merged into thousands_sep. template <typename Char> struct thousands_sep_result {
template <typename Char> std::string grouping;
FMT_API auto grouping_impl(locale_ref loc) -> std::string; Char thousands_sep;
template <typename Char> inline auto grouping(locale_ref loc) -> std::string { };
return grouping_impl<char>(loc);
}
template <> inline auto grouping<wchar_t>(locale_ref loc) -> std::string {
return grouping_impl<wchar_t>(loc);
}
template <typename Char> template <typename Char>
FMT_API auto thousands_sep_impl(locale_ref loc) -> Char; FMT_API auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result<Char>;
template <typename Char> inline auto thousands_sep(locale_ref loc) -> Char { template <typename Char>
return Char(thousands_sep_impl<char>(loc)); inline auto thousands_sep(locale_ref loc) -> thousands_sep_result<Char> {
auto result = thousands_sep_impl<char>(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<wchar_t> {
return thousands_sep_impl<wchar_t>(loc); return thousands_sep_impl<wchar_t>(loc);
} }
@ -1419,10 +1417,10 @@ auto write_int_localized(OutputIt& out, UInt value, unsigned prefix,
-> bool { -> bool {
static_assert(std::is_same<uint64_or_128_t<UInt>, UInt>::value, ""); static_assert(std::is_same<uint64_or_128_t<UInt>, UInt>::value, "");
const auto sep_size = 1; const auto sep_size = 1;
std::string groups = grouping<Char>(loc); auto ts = thousands_sep<Char>(loc);
if (groups.empty()) return false; const std::string& groups = ts.grouping;
auto sep = thousands_sep<Char>(loc); Char sep = ts.thousands_sep;
if (!sep) return false; if (!sep || groups.empty()) return false;
int num_digits = count_digits(value); int num_digits = count_digits(value);
int size = num_digits, n = num_digits; int size = num_digits, n = num_digits;
std::string::const_iterator group = groups.cbegin(); std::string::const_iterator group = groups.cbegin();
@ -2736,10 +2734,10 @@ extern template void vformat_to(detail::buffer<char>&, string_view,
basic_format_args<format_context>, basic_format_args<format_context>,
detail::locale_ref); detail::locale_ref);
extern template FMT_API auto grouping_impl<char>(locale_ref) -> std::string; extern template FMT_API auto thousands_sep_impl<char>(locale_ref)
extern template FMT_API auto grouping_impl<wchar_t>(locale_ref) -> std::string; -> thousands_sep_result<char>;
extern template FMT_API auto thousands_sep_impl<char>(locale_ref) -> char; extern template FMT_API auto thousands_sep_impl<wchar_t>(locale_ref)
extern template FMT_API auto thousands_sep_impl<wchar_t>(locale_ref) -> wchar_t; -> thousands_sep_result<wchar_t>;
extern template FMT_API auto decimal_point_impl(locale_ref) -> char; 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 FMT_API auto decimal_point_impl(locale_ref) -> wchar_t;
extern template auto format_float<double>(double value, int precision, extern template auto format_float<double>(double value, int precision,

View File

@ -41,8 +41,8 @@ template FMT_API std::locale detail::locale_ref::get<std::locale>() const;
// Explicit instantiations for char. // Explicit instantiations for char.
template FMT_API std::string detail::grouping_impl<char>(locale_ref); template FMT_API auto detail::thousands_sep_impl(locale_ref)
template FMT_API char detail::thousands_sep_impl(locale_ref); -> thousands_sep_result<char>;
template FMT_API char detail::decimal_point_impl(locale_ref); template FMT_API char detail::decimal_point_impl(locale_ref);
template FMT_API void detail::buffer<char>::append(const char*, const char*); template FMT_API void detail::buffer<char>::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. // Explicit instantiations for wchar_t.
template FMT_API std::string detail::grouping_impl<wchar_t>(locale_ref); template FMT_API auto detail::thousands_sep_impl(locale_ref)
template FMT_API wchar_t detail::thousands_sep_impl(locale_ref); -> thousands_sep_result<wchar_t>;
template FMT_API wchar_t detail::decimal_point_impl(locale_ref); template FMT_API wchar_t detail::decimal_point_impl(locale_ref);
template FMT_API void detail::buffer<wchar_t>::append(const wchar_t*, template FMT_API void detail::buffer<wchar_t>::append(const wchar_t*,