// Formatting library for C++ - formatters for standard library types // // Copyright (c) 2012 - present, Victor Zverovich // All rights reserved. // // For the license information refer to format.h. #ifndef FMT_STD_H_ #define FMT_STD_H_ #include #include #include #include "ostream.h" #if FMT_HAS_INCLUDE() # include #endif // Checking FMT_CPLUSPLUS for warning suppression in MSVC. #if FMT_CPLUSPLUS >= 201703L # if FMT_HAS_INCLUDE() # include # endif # if FMT_HAS_INCLUDE() # include # endif #endif #ifdef __cpp_lib_filesystem FMT_BEGIN_NAMESPACE namespace detail { template void write_escaped_path(basic_memory_buffer& quoted, const std::filesystem::path& p) { write_escaped_string(std::back_inserter(quoted), p.string()); } # ifdef _WIN32 template <> inline void write_escaped_path(basic_memory_buffer& quoted, const std::filesystem::path& p) { auto s = p.u8string(); write_escaped_string( std::back_inserter(quoted), string_view(reinterpret_cast(s.c_str()), s.size())); } # endif template <> inline void write_escaped_path( basic_memory_buffer& quoted, const std::filesystem::path& p) { write_escaped_string( std::back_inserter(quoted), p.native()); } } // namespace detail #if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1920 // For MSVC 2017 and earlier using the partial specialization // would cause an ambiguity error, therefore we provide it only // conditionally. template struct formatter : formatter> { template auto format(const std::filesystem::path& p, FormatContext& ctx) const -> typename FormatContext::iterator { basic_memory_buffer quoted; detail::write_escaped_path(quoted, p); return formatter>::format( basic_string_view(quoted.data(), quoted.size()), ctx); } }; #endif FMT_END_NAMESPACE #endif FMT_BEGIN_NAMESPACE template struct formatter : basic_ostream_formatter {}; FMT_END_NAMESPACE #ifdef __cpp_lib_variant FMT_BEGIN_NAMESPACE template struct formatter { template FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { return ctx.begin(); } template auto format(const std::monostate&, FormatContext& ctx) const -> decltype(ctx.out()) { auto out = ctx.out(); out = detail::write(out, "monostate"); return out; } }; namespace detail { template using variant_index_sequence = std::make_index_sequence::value>; // variant_size and variant_alternative check. template struct is_variant_like_ : std::false_type {}; template struct is_variant_like_::value)>> : std::true_type {}; // formattable element check template class is_variant_formattable_ { template static std::conjunction< is_formattable, C>...> check(std::index_sequence); public: static constexpr const bool value = decltype(check(variant_index_sequence{}))::value; }; template auto write_variant_alternative(OutputIt out, const T& v) -> OutputIt { if constexpr (is_string::value) return write_escaped_string(out, detail::to_string_view(v)); else if constexpr (std::is_same_v) return write_escaped_char(out, v); else return write(out, v); } } // namespace detail template struct is_variant_like { static constexpr const bool value = detail::is_variant_like_::value; }; template struct is_variant_formattable { static constexpr const bool value = detail::is_variant_formattable_::value; }; template struct formatter< Variant, Char, std::enable_if_t, is_variant_formattable>>> { template FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { return ctx.begin(); } template auto format(const Variant& value, FormatContext& ctx) const -> decltype(ctx.out()) { auto out = ctx.out(); out = detail::write(out, "variant("); std::visit( [&](const auto& v) { out = detail::write_variant_alternative(out, v); }, value); *out++ = ')'; return out; } }; FMT_END_NAMESPACE #endif #endif // FMT_STD_H_