diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 17:44:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 17:44:55 +0000 |
commit | 5068d34c08f951a7ea6257d305a1627b09a95817 (patch) | |
tree | 08213e2be853396a3b07ce15dbe222644dcd9a89 /src/fmtlib/fmt/std.h | |
parent | Initial commit. (diff) | |
download | lnav-upstream.tar.xz lnav-upstream.zip |
Adding upstream version 0.11.1.upstream/0.11.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | src/fmtlib/fmt/std.h | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/src/fmtlib/fmt/std.h b/src/fmtlib/fmt/std.h new file mode 100644 index 0000000..227f484 --- /dev/null +++ b/src/fmtlib/fmt/std.h @@ -0,0 +1,176 @@ +// 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 <thread> +#include <type_traits> +#include <utility> + +#include "ostream.h" + +#if FMT_HAS_INCLUDE(<version>) +# include <version> +#endif +// Checking FMT_CPLUSPLUS for warning suppression in MSVC. +#if FMT_CPLUSPLUS >= 201703L +# if FMT_HAS_INCLUDE(<filesystem>) +# include <filesystem> +# endif +# if FMT_HAS_INCLUDE(<variant>) +# include <variant> +# endif +#endif + +#ifdef __cpp_lib_filesystem +FMT_BEGIN_NAMESPACE + +namespace detail { + +template <typename Char> +void write_escaped_path(basic_memory_buffer<Char>& quoted, + const std::filesystem::path& p) { + write_escaped_string<Char>(std::back_inserter(quoted), p.string<Char>()); +} +# ifdef _WIN32 +template <> +inline void write_escaped_path<char>(basic_memory_buffer<char>& quoted, + const std::filesystem::path& p) { + auto s = p.u8string(); + write_escaped_string<char>( + std::back_inserter(quoted), + string_view(reinterpret_cast<const char*>(s.c_str()), s.size())); +} +# endif +template <> +inline void write_escaped_path<std::filesystem::path::value_type>( + basic_memory_buffer<std::filesystem::path::value_type>& quoted, + const std::filesystem::path& p) { + write_escaped_string<std::filesystem::path::value_type>( + 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 <typename Char> +struct formatter<std::filesystem::path, Char> + : formatter<basic_string_view<Char>> { + template <typename FormatContext> + auto format(const std::filesystem::path& p, FormatContext& ctx) const -> + typename FormatContext::iterator { + basic_memory_buffer<Char> quoted; + detail::write_escaped_path(quoted, p); + return formatter<basic_string_view<Char>>::format( + basic_string_view<Char>(quoted.data(), quoted.size()), ctx); + } +}; +#endif +FMT_END_NAMESPACE +#endif + +FMT_BEGIN_NAMESPACE +template <typename Char> +struct formatter<std::thread::id, Char> : basic_ostream_formatter<Char> {}; +FMT_END_NAMESPACE + +#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; + } +}; + +namespace detail { + +template <typename T> +using variant_index_sequence = + std::make_index_sequence<std::variant_size<T>::value>; + +// variant_size and variant_alternative check. +template <typename T, typename U = void> +struct is_variant_like_ : std::false_type {}; +template <typename T> +struct is_variant_like_<T, std::void_t<decltype(std::variant_size<T>::value)>> + : std::true_type {}; + +// formattable element check +template <typename T, typename C> class is_variant_formattable_ { + template <std::size_t... I> + static std::conjunction< + is_formattable<std::variant_alternative_t<I, T>, C>...> + check(std::index_sequence<I...>); + + public: + static constexpr const bool value = + decltype(check(variant_index_sequence<T>{}))::value; +}; + +template <typename Char, typename OutputIt, typename T> +auto write_variant_alternative(OutputIt out, const T& v) -> OutputIt { + if constexpr (is_string<T>::value) + return write_escaped_string<Char>(out, detail::to_string_view(v)); + else if constexpr (std::is_same_v<T, Char>) + return write_escaped_char(out, v); + else + return write<Char>(out, v); +} + +} // namespace detail + +template <typename T> struct is_variant_like { + static constexpr const bool value = detail::is_variant_like_<T>::value; +}; + +template <typename T, typename C> struct is_variant_formattable { + static constexpr const bool value = + detail::is_variant_formattable_<T, C>::value; +}; + +template <typename Variant, typename Char> +struct formatter< + Variant, Char, + std::enable_if_t<std::conjunction_v< + is_variant_like<Variant>, is_variant_formattable<Variant, Char>>>> { + template <typename ParseContext> + FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + + template <typename FormatContext> + auto format(const Variant& value, FormatContext& ctx) const + -> decltype(ctx.out()) { + auto out = ctx.out(); + + out = detail::write<Char>(out, "variant("); + std::visit( + [&](const auto& v) { + out = detail::write_variant_alternative<Char>(out, v); + }, + value); + *out++ = ')'; + return out; + } +}; +FMT_END_NAMESPACE +#endif + +#endif // FMT_STD_H_ |