123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- // 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
- 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);
- }
- };
- 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_
|