diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index d0080907..ea4821c2 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -1365,7 +1365,26 @@ FMT_FUNC void report_system_error(int error_code, report_error(format_system_error, error_code, message); } +struct stringifier { + template FMT_INLINE std::string operator()(T value) const { + return to_string(value); + } + std::string operator()(basic_format_arg::handle h) const { + memory_buffer buf; + internal::buffer& base = buf; + format_parse_context parse_ctx({}); + format_context format_ctx(std::back_inserter(base), {}, {}); + h.format(parse_ctx, format_ctx); + return to_string(buf); + } +}; + FMT_FUNC std::string detail::vformat(string_view format_str, format_args args) { + if (format_str.size() == 2 && equal2(format_str.data(), "{}")) { + auto arg = args.get(0); + if (!arg) error_handler().on_error("argument not found"); + return visit_format_arg(stringifier(), arg); + } memory_buffer buffer; detail::vformat_to(buffer, format_str, args); return to_string(buffer); diff --git a/include/fmt/format.h b/include/fmt/format.h index 7dab11b5..2f13c8ec 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -1766,8 +1766,7 @@ template struct default_arg_formatter { } OutputIt operator()(typename basic_format_arg::handle handle) { - auto s = Char('}'); - basic_format_parse_context parse_ctx(basic_string_view(&s, 1)); + basic_format_parse_context parse_ctx({}); basic_format_context format_ctx(out, args, loc); handle.format(parse_ctx, format_ctx); return format_ctx.out(); diff --git a/test/format-test.cc b/test/format-test.cc index 5edd9460..22fd12be 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1475,7 +1475,7 @@ template <> struct formatter { template FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { auto it = ctx.begin(); - if (*it == 'd') ++it; + if (it != ctx.end() && *it == 'd') ++it; return it; }