diff --git a/include/fmt/ranges.h b/include/fmt/ranges.h index 0d3dfbd8d378..100a5b27d18d 100644 --- a/include/fmt/ranges.h +++ b/include/fmt/ranges.h @@ -330,7 +330,14 @@ struct formatter FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { auto it = ctx.begin(); - if (it != ctx.end() && *it != '}') report_error("invalid format specifier"); + auto end = ctx.end(); + if (it != end && detail::to_ascii(*it) == 'n') { + ++it; + set_brackets({}, {}); + set_separator({}); + } + if (it != end && *it != '}') report_error("invalid format specifier"); + ctx.advance_to(it); detail::for_each(formatters_, detail::parse_empty_specs{ctx}); return it; } diff --git a/test/ranges-test.cc b/test/ranges-test.cc index 1a5b5a706321..40d545b146ab 100644 --- a/test/ranges-test.cc +++ b/test/ranges-test.cc @@ -170,6 +170,8 @@ TEST(ranges_test, format_adl_begin_end) { TEST(ranges_test, format_pair) { auto p = std::pair(42, 1.5f); EXPECT_EQ(fmt::format("{}", p), "(42, 1.5)"); + EXPECT_EQ(fmt::format("{:}", p), "(42, 1.5)"); + EXPECT_EQ(fmt::format("{:n}", p), "421.5"); } struct unformattable {}; @@ -178,6 +180,7 @@ TEST(ranges_test, format_tuple) { auto t = std::tuple(42, 1.5f, "this is tuple", 'i'); EXPECT_EQ(fmt::format("{}", t), "(42, 1.5, \"this is tuple\", 'i')"); + EXPECT_EQ(fmt::format("{:n}", t), "421.5\"this is tuple\"'i'"); EXPECT_EQ(fmt::format("{}", std::tuple<>()), "()");