From 9fda7a36fd542ae1adf37f08abe1439a146979e2 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Wed, 8 Nov 2017 06:43:56 -0800 Subject: [PATCH] Check integral type specs at compile time --- include/fmt/format.h | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/include/fmt/format.h b/include/fmt/format.h index c1653be3..4bf79b4c 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -1707,8 +1707,14 @@ typedef basic_format_specs format_specs; namespace internal { +struct error_handler { + void on_error(const char *message) { + FMT_THROW(format_error(message)); + } +}; + template -void handle_integral_type_spec(char c, Handler &&handler) { +constexpr void handle_integral_type_spec(char c, Handler &&handler) { switch (c) { case 0: case 'd': handler.on_dec(); @@ -1730,6 +1736,20 @@ void handle_integral_type_spec(char c, Handler &&handler) { } } +struct int_type_checker { + constexpr void on_dec() {} + constexpr void on_hex() {} + constexpr void on_bin() {} + constexpr void on_oct() {} + constexpr void on_num() {} + + template + constexpr void on_error() { + error_handler eh; + eh.on_error("invalid type specifier"); + } +}; + template class arg_map { private: @@ -3169,12 +3189,6 @@ class precision_checker { ErrorHandler &handler_; }; -struct error_handler { - void on_error(const char *message) { - FMT_THROW(format_error(message)); - } -}; - // A format specifier handler that sets fields in basic_format_specs. template class specs_setter : public error_handler { @@ -3658,6 +3672,8 @@ struct formatter< internal::specs_checker handler(handler_type(specs_, ctx), internal::get_type()); it = parse_format_specs(it, handler); + if (std::is_integral::value) + handle_integral_type_spec(specs_.type(), internal::int_type_checker()); return pointer_from(it); }