|
29 | 29 | # if FMT_HAS_INCLUDE(<variant>)
|
30 | 30 | # include <variant>
|
31 | 31 | # endif
|
| 32 | +# if FMT_HAS_INCLUDE(<optional>) |
| 33 | +# include <optional> |
| 34 | +# endif |
32 | 35 | #endif
|
33 | 36 |
|
34 | 37 | // GCC 4 does not support FMT_HAS_INCLUDE.
|
@@ -91,6 +94,49 @@ template <typename Char>
|
91 | 94 | struct formatter<std::thread::id, Char> : basic_ostream_formatter<Char> {};
|
92 | 95 | FMT_END_NAMESPACE
|
93 | 96 |
|
| 97 | +#ifdef __cpp_lib_optional |
| 98 | +FMT_BEGIN_NAMESPACE |
| 99 | +template <typename T, typename Char> |
| 100 | +struct formatter<std::optional<T>, Char, |
| 101 | + std::enable_if_t<is_formattable<T, Char>::value>> { |
| 102 | + private: |
| 103 | + formatter<T, Char> underlying_; |
| 104 | + static constexpr basic_string_view<Char> optional = |
| 105 | + detail::string_literal<Char, 'o', 'p', 't', 'i', 'o', 'n', 'a', 'l', |
| 106 | + '('>{}; |
| 107 | + static constexpr basic_string_view<Char> none = |
| 108 | + detail::string_literal<Char, 'n', 'o', 'n', 'e'>{}; |
| 109 | + |
| 110 | + template <class U> |
| 111 | + FMT_CONSTEXPR static auto maybe_set_debug_format(U& u, bool set) |
| 112 | + -> decltype(u.set_debug_format(set)) { |
| 113 | + u.set_debug_format(set); |
| 114 | + } |
| 115 | + |
| 116 | + template <class U> |
| 117 | + FMT_CONSTEXPR static void maybe_set_debug_format(U&, ...) {} |
| 118 | + |
| 119 | + public: |
| 120 | + template <typename ParseContext> FMT_CONSTEXPR auto parse(ParseContext& ctx) { |
| 121 | + maybe_set_debug_format(underlying_, true); |
| 122 | + return underlying_.parse(ctx); |
| 123 | + } |
| 124 | + |
| 125 | + template <typename FormatContext> |
| 126 | + auto format(std::optional<T> const& opt, FormatContext& ctx) const |
| 127 | + -> decltype(ctx.out()) { |
| 128 | + if (!opt) return detail::write<Char>(ctx.out(), none); |
| 129 | + |
| 130 | + auto out = ctx.out(); |
| 131 | + out = detail::write<Char>(out, optional); |
| 132 | + ctx.advance_to(out); |
| 133 | + out = underlying_.format(*opt, ctx); |
| 134 | + return detail::write(out, ')'); |
| 135 | + } |
| 136 | +}; |
| 137 | +FMT_END_NAMESPACE |
| 138 | +#endif // __cpp_lib_optional |
| 139 | + |
94 | 140 | #ifdef __cpp_lib_variant
|
95 | 141 | FMT_BEGIN_NAMESPACE
|
96 | 142 | template <typename Char> struct formatter<std::monostate, Char> {
|
|
0 commit comments