Fix locale-dependent formatting (#905)

This commit is contained in:
Victor Zverovich 2018-10-13 06:52:33 -07:00
parent 10e03e695b
commit ddd7caf38e
2 changed files with 12 additions and 4 deletions

View File

@ -988,6 +988,8 @@ struct no_thousands_sep {
template <typename Char> template <typename Char>
void operator()(Char *) {} void operator()(Char *) {}
enum { size = 0 };
}; };
// A functor that adds a thousands separator. // A functor that adds a thousands separator.
@ -1012,6 +1014,8 @@ class add_thousands_sep {
std::uninitialized_copy(sep_.data(), sep_.data() + sep_.size(), std::uninitialized_copy(sep_.data(), sep_.data() + sep_.size(),
internal::make_checked(buffer, sep_.size())); internal::make_checked(buffer, sep_.size()));
} }
enum { size = 1 };
}; };
template <typename Char> template <typename Char>
@ -1052,10 +1056,12 @@ template <typename OutChar, typename UInt, typename Iterator,
inline Iterator format_decimal( inline Iterator format_decimal(
Iterator out, UInt value, unsigned num_digits, ThousandsSep sep) { Iterator out, UInt value, unsigned num_digits, ThousandsSep sep) {
typedef typename ThousandsSep::char_type char_type; typedef typename ThousandsSep::char_type char_type;
// Buffer should be large enough to hold all digits (digits10 + 1) and null. // Buffer should be large enough to hold all digits (<= digits10 + 1).
char_type buffer[std::numeric_limits<UInt>::digits10 + 2]; enum { max_size = std::numeric_limits<UInt>::digits10 + 1 };
format_decimal(buffer, value, num_digits, sep); FMT_ASSERT(ThousandsSep::size <= 1, "invalid separator");
return internal::copy_str<OutChar>(buffer, buffer + num_digits, out); char_type buffer[max_size + max_size / 3];
auto end = format_decimal(buffer, value, num_digits, sep);
return internal::copy_str<OutChar>(buffer, end, out);
} }
template <typename OutChar, typename It, typename UInt> template <typename OutChar, typename It, typename UInt>

View File

@ -1378,6 +1378,8 @@ TEST(FormatterTest, FormatIntLocale) {
EXPECT_EQ("123", format("{:n}", 123)); EXPECT_EQ("123", format("{:n}", 123));
EXPECT_EQ("1,234", format("{:n}", 1234)); EXPECT_EQ("1,234", format("{:n}", 1234));
EXPECT_EQ("1,234,567", format("{:n}", 1234567)); EXPECT_EQ("1,234,567", format("{:n}", 1234567));
EXPECT_EQ("4,294,967,295",
format("{:n}", std::numeric_limits<uint32_t>::max()));
} }
struct ConvertibleToLongLong { struct ConvertibleToLongLong {