From 854fc9567a2cbea01b0f413565705ccbaf5bde5c Mon Sep 17 00:00:00 2001 From: IfkumRfnl <63595916+IfkumRfnl@users.noreply.github.com> Date: Fri, 11 Sep 2026 19:01:06 +0400 Subject: [PATCH] Fix argument count in dynamic stores with named arguments (#4933) --- include/fmt/args.h | 6 ++++-- test/args-test.cc | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/include/fmt/args.h b/include/fmt/args.h index 3283e6fa..cef566fa 100644 --- a/include/fmt/args.h +++ b/include/fmt/args.h @@ -131,7 +131,7 @@ FMT_EXPORT template class dynamic_format_arg_store { constexpr dynamic_format_arg_store() = default; operator basic_format_args() const { - return basic_format_args(data(), static_cast(data_.size()), + return basic_format_args(data(), static_cast(size()), !named_info_.empty()); } @@ -210,7 +210,9 @@ FMT_EXPORT template class dynamic_format_arg_store { } /// Returns the number of elements in the store. - auto size() const noexcept -> size_t { return data_.size(); } + auto size() const noexcept -> size_t { + return data_.size() - (named_info_.empty() ? 0 : 1); + } }; FMT_END_NAMESPACE diff --git a/test/args-test.cc b/test/args-test.cc index 8e9f53e5..b17cee80 100644 --- a/test/args-test.cc +++ b/test/args-test.cc @@ -200,3 +200,38 @@ TEST(args_test, size) { store.clear(); EXPECT_EQ(store.size(), 0); } + +TEST(args_test, named_arg_count) { + fmt::dynamic_format_arg_store store; + EXPECT_EQ(store.size(), 0u); + EXPECT_THROW(fmt::vformat("{0}", store), fmt::format_error); + + store.push_back(fmt::arg("a", 42)); + EXPECT_EQ(store.size(), 1u); + EXPECT_EQ("42 42", fmt::vformat("{0} {a}", store)); + EXPECT_THROW(fmt::vformat("{1}", store), fmt::format_error); + + store.push_back(fmt::arg("b", 43)); + EXPECT_EQ(store.size(), 2u); + EXPECT_EQ("42 43 43", fmt::vformat("{0} {1} {b}", store)); + EXPECT_THROW(fmt::vformat("{2}", store), fmt::format_error); + + store.push_back(44); + EXPECT_EQ(store.size(), 3u); + EXPECT_EQ("42 43 44", fmt::vformat("{a} {b} {2}", store)); + EXPECT_THROW(fmt::vformat("{3}", store), fmt::format_error); + + store.clear(); + EXPECT_EQ(store.size(), 0u); + EXPECT_THROW(fmt::vformat("{0}", store), fmt::format_error); + + store.push_back(45); + EXPECT_EQ(store.size(), 1u); + EXPECT_EQ("45", fmt::vformat("{0}", store)); + EXPECT_THROW(fmt::vformat("{1}", store), fmt::format_error); + + store.push_back(fmt::arg("c", 46)); + EXPECT_EQ(store.size(), 2u); + EXPECT_EQ("45 46 46", fmt::vformat("{0} {1} {c}", store)); + EXPECT_THROW(fmt::vformat("{2}", store), fmt::format_error); +}