Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore zero-padding for non-finite floating points #2310

Merged
merged 5 commits into from
May 27, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/fmt/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -1948,7 +1948,7 @@ template <typename Char> class specs_setter {
FMT_CONSTEXPR void on_localized() { specs_.localized = true; }

FMT_CONSTEXPR void on_zero() {
specs_.align = align::numeric;
if (specs_.align == align::none) specs_.align = align::numeric;
specs_.fill[0] = Char('0');
}

Expand Down
6 changes: 5 additions & 1 deletion include/fmt/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -1584,13 +1584,17 @@ FMT_CONSTEXPR OutputIt write(OutputIt out, const Char* s,

template <typename Char, typename OutputIt>
OutputIt write_nonfinite(OutputIt out, bool isinf,
const basic_format_specs<Char>& specs,
basic_format_specs<Char> specs,
const float_specs& fspecs) {
auto str =
isinf ? (fspecs.upper ? "INF" : "inf") : (fspecs.upper ? "NAN" : "nan");
constexpr size_t str_size = 3;
auto sign = fspecs.sign;
auto size = str_size + (sign ? 1 : 0);
// replace '0'-padding with space for non-finite values
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: please make this a proper sentence:

// Replace '0'-padding with space for non-finite values.

const bool is_zero_fill =
specs.fill.size() == 1 && *specs.fill.data() == static_cast<Char>('0');
if (is_zero_fill) specs.fill[0] = static_cast<Char>(' ');
return write_padded(out, specs, size, [=](reserve_iterator<OutputIt> it) {
if (sign) *it++ = static_cast<Char>(data::signs[sign]);
return copy_str<Char>(str, str + str_size, it);
Expand Down
14 changes: 12 additions & 2 deletions test/format-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1272,9 +1272,14 @@ TEST(format_test, format_nan) {
double nan = std::numeric_limits<double>::quiet_NaN();
EXPECT_EQ("nan", fmt::format("{}", nan));
EXPECT_EQ("+nan", fmt::format("{:+}", nan));
if (std::signbit(-nan))
EXPECT_EQ(" +nan", fmt::format("{:+06}", nan));
EXPECT_EQ("+nan ", fmt::format("{:<+06}", nan));
EXPECT_EQ(" +nan ", fmt::format("{:^+06}", nan));
EXPECT_EQ(" +nan", fmt::format("{:>+06}", nan));
if (std::signbit(-nan)) {
EXPECT_EQ("-nan", fmt::format("{}", -nan));
else
EXPECT_EQ(" -nan", fmt::format("{:+06}", -nan));
} else
fmt::print("Warning: compiler doesn't handle negative NaN correctly");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: please wrap the else statement in {} for consistency with if:

} else {
  fmt::print("Warning: compiler doesn't handle negative NaN correctly");
}

EXPECT_EQ(" nan", fmt::format("{: }", nan));
EXPECT_EQ("NAN", fmt::format("{:F}", nan));
Expand All @@ -1288,6 +1293,11 @@ TEST(format_test, format_infinity) {
EXPECT_EQ("inf", fmt::format("{}", inf));
EXPECT_EQ("+inf", fmt::format("{:+}", inf));
EXPECT_EQ("-inf", fmt::format("{}", -inf));
EXPECT_EQ(" +inf", fmt::format("{:+06}", inf));
EXPECT_EQ(" -inf", fmt::format("{:+06}", -inf));
EXPECT_EQ("+inf ", fmt::format("{:<+06}", inf));
EXPECT_EQ(" +inf ", fmt::format("{:^+06}", inf));
EXPECT_EQ(" +inf", fmt::format("{:>+06}", inf));
EXPECT_EQ(" inf", fmt::format("{: }", inf));
EXPECT_EQ("INF", fmt::format("{:F}", inf));
EXPECT_EQ("inf ", fmt::format("{:<7}", inf));
Expand Down