diff --git a/include/fmt/core.h b/include/fmt/core.h index 857dcc05..a543f096 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -8,7 +8,6 @@ #ifndef FMT_CORE_H_ #define FMT_CORE_H_ -#include #include // std::FILE #include #include @@ -563,24 +562,14 @@ class basic_format_parse_context : private ErrorHandler { private: basic_string_view format_str_; int next_arg_id_; - int num_args_; - - FMT_CONSTEXPR int do_check_arg_id(int id) { - if (id >= num_args_) on_error("argument not found"); - return id; - } public: using char_type = Char; using iterator = typename basic_string_view::iterator; explicit FMT_CONSTEXPR basic_format_parse_context( - basic_string_view format_str, int num_args = INT_MAX, - ErrorHandler eh = {}) - : ErrorHandler(eh), - format_str_(format_str), - next_arg_id_(0), - num_args_(num_args) {} + basic_string_view format_str, ErrorHandler eh = ErrorHandler()) + : ErrorHandler(eh), format_str_(format_str), next_arg_id_(0) {} /** Returns an iterator to the beginning of the format string range being @@ -605,7 +594,7 @@ class basic_format_parse_context : private ErrorHandler { the next argument index and switches to the automatic indexing. */ FMT_CONSTEXPR int next_arg_id() { - if (next_arg_id_ >= 0) return do_check_arg_id(next_arg_id_++); + if (next_arg_id_ >= 0) return next_arg_id_++; on_error("cannot switch from manual to automatic argument indexing"); return 0; } @@ -614,13 +603,11 @@ class basic_format_parse_context : private ErrorHandler { Reports an error if using the automatic argument indexing; otherwise switches to the manual indexing. */ - FMT_CONSTEXPR void check_arg_id(int id) { - if (next_arg_id_ > 0) { + FMT_CONSTEXPR void check_arg_id(int) { + if (next_arg_id_ > 0) on_error("cannot switch from automatic to manual argument indexing"); - return; - } - do_check_arg_id(id); - next_arg_id_ = -1; + else + next_arg_id_ = -1; } FMT_CONSTEXPR void check_arg_id(basic_string_view) {} diff --git a/include/fmt/format.h b/include/fmt/format.h index 56bcf191..d11a714b 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -2632,17 +2632,19 @@ class format_string_checker { explicit FMT_CONSTEXPR format_string_checker( basic_string_view format_str, ErrorHandler eh) : arg_id_(-1), - context_(format_str, num_args, eh), + context_(format_str, eh), parse_funcs_{&parse_format_specs...} {} FMT_CONSTEXPR void on_text(const Char*, const Char*) {} FMT_CONSTEXPR void on_arg_id() { arg_id_ = context_.next_arg_id(); + check_arg_id(); } FMT_CONSTEXPR void on_arg_id(int id) { arg_id_ = id; context_.check_arg_id(id); + check_arg_id(); } FMT_CONSTEXPR void on_arg_id(basic_string_view) { on_error("compile-time checks don't support named arguments"); @@ -2663,6 +2665,10 @@ class format_string_checker { using parse_context_type = basic_format_parse_context; enum { num_args = sizeof...(Args) }; + FMT_CONSTEXPR void check_arg_id() { + if (arg_id_ >= num_args) context_.on_error("argument not found"); + } + // Format specifier parsing function. using parse_func = const Char* (*)(parse_context_type&); diff --git a/test/format-test.cc b/test/format-test.cc index f9e75d20..fa3574bc 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -2493,8 +2493,6 @@ TEST(FormatTest, FormatStringErrors) { EXPECT_ERROR("{:+}", "format specifier requires signed argument", unsigned); EXPECT_ERROR("{:-}", "format specifier requires signed argument", unsigned); EXPECT_ERROR("{: }", "format specifier requires signed argument", unsigned); - EXPECT_ERROR("{:{}}", "argument not found", int); - EXPECT_ERROR("{:.{}}", "argument not found", double); EXPECT_ERROR("{:.2}", "precision not allowed for this argument type", int); EXPECT_ERROR("{:s}", "invalid type specifier", int); EXPECT_ERROR("{:s}", "invalid type specifier", bool);