Repository: fmtlib/fmt
File: include/fmt/std.h (C/C++)

Code before:
struct formatter<std::optional<T>, Char,
                 std::enable_if_t<is_formattable<T>::value>> {
  formatter<T, Char> underlying_;
  static constexpr basic_string_view<Char> OPTION =
      detail::string_literal<Char, 'o', 'p', 't', 'i', 'o', 'n', 'a', 'l', '('>{};
  static constexpr basic_string_view<Char> EMPTY =
      detail::string_literal<Char, 'n', 'o', 'n', 'e'>{};

  template <typename ParseContext> FMT_CONSTEXPR auto parse(ParseContext& ctx) {
    return underlying_.parse(ctx);
  }
  template <typename FormatContext>
  auto format(std::optional<T> const& opt, FormatContext& ctx) const
      -> decltype(ctx.out()) {
    if (opt) {
      auto out = ctx.out();
      out = detail::write<Char>(out, OPTION);
      if constexpr (detail::is_string<T>::value)
        out = detail::write_escaped_string<Char>(out,
                                                 detail::to_string_view(*opt));
      else if constexpr (std::is_same_v<T, char>)
        out = detail::write_escaped_char<Char>(out, *opt);
      else {
        ctx.advance_to(out);
        out = underlying_.format(*opt, ctx);
      }
      return detail::write(out, ')');
    }
    return detail::write<Char>(ctx.out(), EMPTY);
  }
};
FMT_END_NAMESPACE
#endif  // __cpp_lib_optional

#ifdef __cpp_lib_variant
FMT_BEGIN_NAMESPACE
template <typename Char> struct formatter<std::monostate, Char> {
  template <typename ParseContext>
  FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
    return ctx.begin();
  }

  template <typename FormatContext>
  auto format(const std::monostate&, FormatContext& ctx) const
      -> decltype(ctx.out()) {
    auto out = ctx.out();
    out = detail::write<Char>(out, "monostate");
    return out;
  }
};


Review comment (bug):
Escaping should be done by setting debug format via `underlying_.set_debug_format` in parse, not here, because it needs to work with nested types.

Code after:
struct formatter<std::optional<T>, Char,
                 std::enable_if_t<is_formattable<T, Char>::value>> {
 private:
  formatter<T, Char> underlying_;
  static constexpr basic_string_view<Char> optional =
      detail::string_literal<Char, 'o', 'p', 't', 'i', 'o', 'n', 'a', 'l',
                             '('>{};
  static constexpr basic_string_view<Char> none =
      detail::string_literal<Char, 'n', 'o', 'n', 'e'>{};

  template <class U>
  FMT_CONSTEXPR static auto maybe_set_debug_format(U& u, bool set)
      -> decltype(u.set_debug_format(set)) {
    u.set_debug_format(set);
  }

  template <class U>
  FMT_CONSTEXPR static void maybe_set_debug_format(U&, ...) {}

 public:
  template <typename ParseContext> FMT_CONSTEXPR auto parse(ParseContext& ctx) {
    maybe_set_debug_format(underlying_, true);
    return underlying_.parse(ctx);
  }

  template <typename FormatContext>
  auto format(std::optional<T> const& opt, FormatContext& ctx) const
      -> decltype(ctx.out()) {
    if (!opt) return detail::write<Char>(ctx.out(), none);

    auto out = ctx.out();
    out = detail::write<Char>(out, optional);
    ctx.advance_to(out);
    out = underlying_.format(*opt, ctx);
    return detail::write(out, ')');
  }
};
FMT_END_NAMESPACE
#endif  // __cpp_lib_optional

#ifdef __cpp_lib_variant
FMT_BEGIN_NAMESPACE
template <typename Char> struct formatter<std::monostate, Char> {
  template <typename ParseContext>
  FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
    return ctx.begin();
  }

  template <typename FormatContext>
  auto format(const std::monostate&, FormatContext& ctx) const
      -> decltype(ctx.out()) {