diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index d77e5c82..75fa163b 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -133,12 +133,13 @@ struct localize_int { appender out; const format_specs& specs; std::string sep; + std::string grouping; template ::value)> void operator()(T value) { auto arg = make_write_int_arg(value, specs.sign); write_int(out, static_cast>(arg.abs_value), arg.prefix, - specs, digit_grouping("\3", sep)); + specs, digit_grouping(grouping, sep)); } template ::value)> void operator()(T) {} @@ -152,7 +153,8 @@ template <> FMT_API FMT_FUNC void format_facet::do_put( appender out, basic_format_arg val, const format_specs& specs) const { - visit_format_arg(detail::localize_int{out, specs, separator_}, val); + visit_format_arg(detail::localize_int{out, specs, separator_, grouping_}, + val); } #endif diff --git a/include/fmt/format.h b/include/fmt/format.h index ab98dbd5..5e17a0a1 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -33,13 +33,14 @@ #ifndef FMT_FORMAT_H_ #define FMT_FORMAT_H_ -#include // std::signbit -#include // uint32_t -#include // std::memcpy -#include // std::numeric_limits -#include // std::uninitialized_copy -#include // std::runtime_error -#include // std::system_error +#include // std::signbit +#include // uint32_t +#include // std::memcpy +#include // std::initializer_list +#include // std::numeric_limits +#include // std::uninitialized_copy +#include // std::runtime_error +#include // std::system_error #ifdef __cpp_lib_bit_cast # include // std::bitcast @@ -990,6 +991,7 @@ constexpr auto compile_string_to_view(detail::std_string_view s) template class format_facet : public Locale::facet { private: std::string separator_; + std::string grouping_; protected: virtual void do_put(appender out, basic_format_arg val, @@ -998,8 +1000,9 @@ template class format_facet : public Locale::facet { public: static FMT_API typename Locale::id id; - explicit format_facet(string_view sep = ",") - : separator_(sep.data(), sep.size()) {} + explicit format_facet(string_view sep = ",", + std::initializer_list g = {3}) + : separator_(sep.data(), sep.size()), grouping_(g.begin(), g.end()) {} void put(appender out, basic_format_arg val, const format_specs& specs) const { diff --git a/test/format-test.cc b/test/format-test.cc index 6fb38cb9..85f1af49 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -2348,11 +2348,17 @@ TEST(format_test, format_facet) { TEST(format_test, format_facet_separator) { // U+2019 RIGHT SINGLE QUOTATION MARK is a digit separator in the de_CH // locale. - auto loc = std::locale(std::locale(), - new fmt::format_facet("\xe2\x80\x99")); + auto loc = + std::locale({}, new fmt::format_facet("\xe2\x80\x99")); EXPECT_EQ(fmt::format(loc, "{:L}", 1000), "1\xe2\x80\x99" "000"); } +TEST(format_test, format_facet_grouping) { + auto loc = + std::locale({}, new fmt::format_facet(",", {1, 2, 3})); + EXPECT_EQ(fmt::format(loc, "{:L}", 1234567890), "1,234,567,89,0"); +} + #endif // FMT_STATIC_THOUSANDS_SEPARATOR