mirror of
https://github.com/fmtlib/fmt.git
synced 2025-01-09 22:20:06 +00:00
Implement thousands separators without locales
This commit is contained in:
parent
08f98c7fac
commit
3b9c442689
@ -1467,6 +1467,7 @@ template <typename Char> class digit_grouping {
|
||||
else
|
||||
sep_.thousands_sep = Char();
|
||||
}
|
||||
explicit digit_grouping(thousands_sep_result<Char> sep) : sep_(sep) {}
|
||||
|
||||
Char separator() const { return sep_.thousands_sep; }
|
||||
|
||||
@ -1501,22 +1502,28 @@ template <typename Char> class digit_grouping {
|
||||
};
|
||||
|
||||
template <typename OutputIt, typename UInt, typename Char>
|
||||
auto write_int_localized(OutputIt& out, UInt value, unsigned prefix,
|
||||
const basic_format_specs<Char>& specs, locale_ref loc)
|
||||
-> bool {
|
||||
auto write_int_localized(OutputIt out, UInt value, unsigned prefix,
|
||||
const basic_format_specs<Char>& specs,
|
||||
const digit_grouping<Char>& grouping) -> OutputIt {
|
||||
static_assert(std::is_same<uint64_or_128_t<UInt>, UInt>::value, "");
|
||||
int num_digits = count_digits(value);
|
||||
char digits[40];
|
||||
format_decimal(digits, value, num_digits);
|
||||
|
||||
auto grouping = digit_grouping<Char>(loc);
|
||||
unsigned size = to_unsigned((prefix != 0 ? 1 : 0) + num_digits +
|
||||
grouping.count_separators(num_digits));
|
||||
out = write_padded<align::right>(
|
||||
return write_padded<align::right>(
|
||||
out, specs, size, size, [&](reserve_iterator<OutputIt> it) {
|
||||
if (prefix != 0) *it++ = static_cast<Char>(prefix);
|
||||
return grouping.apply(it, string_view(digits, to_unsigned(num_digits)));
|
||||
});
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename UInt, typename Char>
|
||||
auto write_int_localized(OutputIt& out, UInt value, unsigned prefix,
|
||||
const basic_format_specs<Char>& specs, locale_ref loc)
|
||||
-> bool {
|
||||
auto grouping = digit_grouping<Char>(loc);
|
||||
out = write_int_localized(out, value, prefix, specs, grouping);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2604,6 +2611,22 @@ template <> struct formatter<bytes> {
|
||||
}
|
||||
};
|
||||
|
||||
// thousands_view is not derived from view because it copies the argument.
|
||||
template <typename T> struct thousands_view { T value; };
|
||||
|
||||
template <typename T> auto thousands(T value) -> thousands_view<T> {
|
||||
return {value};
|
||||
}
|
||||
|
||||
template <typename T> struct formatter<thousands_view<T>> : formatter<T> {
|
||||
template <typename FormatContext>
|
||||
auto format(thousands_view<T> t, FormatContext& ctx) -> decltype(ctx.out()) {
|
||||
return detail::write_int_localized(
|
||||
ctx.out(), static_cast<detail::uint64_or_128_t<T>>(t.value), 0,
|
||||
format_specs(), detail::digit_grouping<char>({"\3", ','}));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename It, typename Sentinel, typename Char = char>
|
||||
struct join_view : detail::view {
|
||||
It begin;
|
||||
|
@ -1595,6 +1595,10 @@ TEST(format_test, bytes) {
|
||||
EXPECT_EQ(10, s.size());
|
||||
}
|
||||
|
||||
TEST(format_test, thousands) {
|
||||
EXPECT_EQ(fmt::format("{}", fmt::thousands(1000)), "1,000");
|
||||
}
|
||||
|
||||
enum test_enum { foo, bar };
|
||||
|
||||
TEST(format_test, join) {
|
||||
|
Loading…
Reference in New Issue
Block a user