diff --git a/fmt/format.h b/fmt/format.h index 5bc2911d..a284468b 100644 --- a/fmt/format.h +++ b/fmt/format.h @@ -1331,6 +1331,8 @@ template class ArgMap; } // namespace internal +struct monostate {}; + template class basic_format_args; @@ -1352,27 +1354,22 @@ class basic_format_arg { template friend class internal::ArgMap; - void check_type() const { - FMT_ASSERT(type_ > internal::NAMED_ARG, "invalid argument type"); - } - public: basic_format_arg() : type_(internal::NONE) {} explicit operator bool() const noexcept { return type_ != internal::NONE; } bool is_integral() const { - check_type(); - return type_ <= internal::LAST_INTEGER_TYPE; + FMT_ASSERT(type_ != internal::NAMED_ARG, "invalid argument type"); + return type_ > internal::NONE && type_ <= internal::LAST_INTEGER_TYPE; } bool is_numeric() const { - check_type(); - return type_ <= internal::LAST_NUMERIC_TYPE; + FMT_ASSERT(type_ != internal::NAMED_ARG, "invalid argument type"); + return type_ > internal::NONE && type_ <= internal::LAST_NUMERIC_TYPE; } bool is_pointer() const { - check_type(); return type_ == internal::POINTER; } }; @@ -1392,6 +1389,7 @@ typename std::result_of::type visit(Visitor &&vis, basic_format_arg arg) { switch (arg.type_) { case internal::NONE: + return vis(monostate()); case internal::NAMED_ARG: FMT_ASSERT(false, "invalid argument type"); break; @@ -1986,6 +1984,10 @@ class ArgFormatterBase { ArgFormatterBase(BasicWriter &w, FormatSpec &s) : writer_(w), spec_(s) {} + void operator()(monostate) { + FMT_ASSERT(false, "invalid argument type"); + } + template typename std::enable_if::value>::type operator()(T value) { writer_.write_int(value, spec_); } diff --git a/test/util-test.cc b/test/util-test.cc index b20fe54f..69569e43 100644 --- a/test/util-test.cc +++ b/test/util-test.cc @@ -579,8 +579,11 @@ TEST(UtilTest, CustomArg) { } TEST(ArgVisitorTest, VisitInvalidArg) { - format_arg arg = format_arg(); - EXPECT_ASSERT(visit(MockVisitor(), arg), "invalid argument type"); + typedef MockVisitor Visitor; + testing::StrictMock visitor; + EXPECT_CALL(visitor, visit(_)); + format_arg arg; + visit(visitor, arg); } // Tests fmt::internal::count_digits for integer type Int.