From 18495bf25dad3a4e8c2fe3777a5f79acecde27e3 Mon Sep 17 00:00:00 2001 From: Eli Boyarski Date: Tue, 8 Nov 2022 01:14:01 +0200 Subject: [PATCH] Bundle fmt 9.1.0's std.h, and provide a header to include either it or the external fmt's version (#2539) --- include/spdlog/fmt/bundled/std.h | 171 +++++++++++++++++++++++++++++++ include/spdlog/fmt/std.h | 23 +++++ 2 files changed, 194 insertions(+) create mode 100644 include/spdlog/fmt/bundled/std.h create mode 100644 include/spdlog/fmt/std.h diff --git a/include/spdlog/fmt/bundled/std.h b/include/spdlog/fmt/bundled/std.h new file mode 100644 index 00000000..41d2b283 --- /dev/null +++ b/include/spdlog/fmt/bundled/std.h @@ -0,0 +1,171 @@ +// 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 + +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); + } +}; +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_ diff --git a/include/spdlog/fmt/std.h b/include/spdlog/fmt/std.h new file mode 100644 index 00000000..0490cab0 --- /dev/null +++ b/include/spdlog/fmt/std.h @@ -0,0 +1,23 @@ +// +// Copyright(c) 2016 Gabi Melman. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) +// + +#pragma once +// +// include bundled or external copy of fmtlib's std support (for formatting e.g. std::filesystem::path, std::thread::id, std::monostate, +// std::variant, ...) +// + +#if !defined(SPDLOG_USE_STD_FORMAT) +# if !defined(SPDLOG_FMT_EXTERNAL) +# ifdef SPDLOG_HEADER_ONLY +# ifndef FMT_HEADER_ONLY +# define FMT_HEADER_ONLY +# endif +# endif +# include +# else +# include +# endif +#endif