Implement grouping

This commit is contained in:
Victor Zverovich 2022-09-04 09:01:26 -07:00
parent 1b94271ff6
commit 58a5563a9f
3 changed files with 24 additions and 13 deletions

View File

@ -133,12 +133,13 @@ struct localize_int {
appender out; appender out;
const format_specs& specs; const format_specs& specs;
std::string sep; std::string sep;
std::string grouping;
template <typename T, FMT_ENABLE_IF(detail::is_integer<T>::value)> template <typename T, FMT_ENABLE_IF(detail::is_integer<T>::value)>
void operator()(T value) { void operator()(T value) {
auto arg = make_write_int_arg(value, specs.sign); auto arg = make_write_int_arg(value, specs.sign);
write_int(out, static_cast<uint64_or_128_t<T>>(arg.abs_value), arg.prefix, write_int(out, static_cast<uint64_or_128_t<T>>(arg.abs_value), arg.prefix,
specs, digit_grouping<char>("\3", sep)); specs, digit_grouping<char>(grouping, sep));
} }
template <typename T, FMT_ENABLE_IF(!detail::is_integer<T>::value)> template <typename T, FMT_ENABLE_IF(!detail::is_integer<T>::value)>
void operator()(T) {} void operator()(T) {}
@ -152,7 +153,8 @@ template <>
FMT_API FMT_FUNC void format_facet<std::locale>::do_put( FMT_API FMT_FUNC void format_facet<std::locale>::do_put(
appender out, basic_format_arg<format_context> val, appender out, basic_format_arg<format_context> val,
const format_specs& specs) const { 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 #endif

View File

@ -36,6 +36,7 @@
#include <cmath> // std::signbit #include <cmath> // std::signbit
#include <cstdint> // uint32_t #include <cstdint> // uint32_t
#include <cstring> // std::memcpy #include <cstring> // std::memcpy
#include <initializer_list> // std::initializer_list
#include <limits> // std::numeric_limits #include <limits> // std::numeric_limits
#include <memory> // std::uninitialized_copy #include <memory> // std::uninitialized_copy
#include <stdexcept> // std::runtime_error #include <stdexcept> // std::runtime_error
@ -990,6 +991,7 @@ constexpr auto compile_string_to_view(detail::std_string_view<Char> s)
template <typename Locale> class format_facet : public Locale::facet { template <typename Locale> class format_facet : public Locale::facet {
private: private:
std::string separator_; std::string separator_;
std::string grouping_;
protected: protected:
virtual void do_put(appender out, basic_format_arg<format_context> val, virtual void do_put(appender out, basic_format_arg<format_context> val,
@ -998,8 +1000,9 @@ template <typename Locale> class format_facet : public Locale::facet {
public: public:
static FMT_API typename Locale::id id; static FMT_API typename Locale::id id;
explicit format_facet(string_view sep = ",") explicit format_facet(string_view sep = ",",
: separator_(sep.data(), sep.size()) {} std::initializer_list<unsigned char> g = {3})
: separator_(sep.data(), sep.size()), grouping_(g.begin(), g.end()) {}
void put(appender out, basic_format_arg<format_context> val, void put(appender out, basic_format_arg<format_context> val,
const format_specs& specs) const { const format_specs& specs) const {

View File

@ -2348,11 +2348,17 @@ TEST(format_test, format_facet) {
TEST(format_test, format_facet_separator) { TEST(format_test, format_facet_separator) {
// U+2019 RIGHT SINGLE QUOTATION MARK is a digit separator in the de_CH // U+2019 RIGHT SINGLE QUOTATION MARK is a digit separator in the de_CH
// locale. // locale.
auto loc = std::locale(std::locale(), auto loc =
new fmt::format_facet<std::locale>("\xe2\x80\x99")); std::locale({}, new fmt::format_facet<std::locale>("\xe2\x80\x99"));
EXPECT_EQ(fmt::format(loc, "{:L}", 1000), EXPECT_EQ(fmt::format(loc, "{:L}", 1000),
"1\xe2\x80\x99" "1\xe2\x80\x99"
"000"); "000");
} }
TEST(format_test, format_facet_grouping) {
auto loc =
std::locale({}, new fmt::format_facet<std::locale>(",", {1, 2, 3}));
EXPECT_EQ(fmt::format(loc, "{:L}", 1234567890), "1,234,567,89,0");
}
#endif // FMT_STATIC_THOUSANDS_SEPARATOR #endif // FMT_STATIC_THOUSANDS_SEPARATOR