mirror of
https://github.com/fmtlib/fmt.git
synced 2025-02-21 03:41:05 +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
|
else
|
||||||
sep_.thousands_sep = Char();
|
sep_.thousands_sep = Char();
|
||||||
}
|
}
|
||||||
|
explicit digit_grouping(thousands_sep_result<Char> sep) : sep_(sep) {}
|
||||||
|
|
||||||
Char separator() const { return sep_.thousands_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>
|
template <typename OutputIt, typename UInt, typename Char>
|
||||||
auto write_int_localized(OutputIt& out, UInt value, unsigned prefix,
|
auto write_int_localized(OutputIt out, UInt value, unsigned prefix,
|
||||||
const basic_format_specs<Char>& specs, locale_ref loc)
|
const basic_format_specs<Char>& specs,
|
||||||
-> bool {
|
const digit_grouping<Char>& grouping) -> OutputIt {
|
||||||
static_assert(std::is_same<uint64_or_128_t<UInt>, UInt>::value, "");
|
static_assert(std::is_same<uint64_or_128_t<UInt>, UInt>::value, "");
|
||||||
int num_digits = count_digits(value);
|
int num_digits = count_digits(value);
|
||||||
char digits[40];
|
char digits[40];
|
||||||
format_decimal(digits, value, num_digits);
|
format_decimal(digits, value, num_digits);
|
||||||
|
|
||||||
auto grouping = digit_grouping<Char>(loc);
|
|
||||||
unsigned size = to_unsigned((prefix != 0 ? 1 : 0) + num_digits +
|
unsigned size = to_unsigned((prefix != 0 ? 1 : 0) + num_digits +
|
||||||
grouping.count_separators(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) {
|
out, specs, size, size, [&](reserve_iterator<OutputIt> it) {
|
||||||
if (prefix != 0) *it++ = static_cast<Char>(prefix);
|
if (prefix != 0) *it++ = static_cast<Char>(prefix);
|
||||||
return grouping.apply(it, string_view(digits, to_unsigned(num_digits)));
|
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;
|
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>
|
template <typename It, typename Sentinel, typename Char = char>
|
||||||
struct join_view : detail::view {
|
struct join_view : detail::view {
|
||||||
It begin;
|
It begin;
|
||||||
|
@ -1595,6 +1595,10 @@ TEST(format_test, bytes) {
|
|||||||
EXPECT_EQ(10, s.size());
|
EXPECT_EQ(10, s.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(format_test, thousands) {
|
||||||
|
EXPECT_EQ(fmt::format("{}", fmt::thousands(1000)), "1,000");
|
||||||
|
}
|
||||||
|
|
||||||
enum test_enum { foo, bar };
|
enum test_enum { foo, bar };
|
||||||
|
|
||||||
TEST(format_test, join) {
|
TEST(format_test, join) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user