1 // Formatting library for C++ - formatters for standard library types
3 // Copyright (c) 2012 - present, Victor Zverovich
4 // All rights reserved.
6 // For the license information refer to format.h.
12 #include <type_traits>
17 #if FMT_HAS_INCLUDE(<version>)
20 // Checking FMT_CPLUSPLUS for warning suppression in MSVC.
21 #if FMT_CPLUSPLUS >= 201703L
22 # if FMT_HAS_INCLUDE(<filesystem>)
23 # include <filesystem>
25 # if FMT_HAS_INCLUDE(<variant>)
30 #ifdef __cpp_lib_filesystem
35 template <typename Char
>
36 void write_escaped_path(basic_memory_buffer
<Char
>& quoted
,
37 const std::filesystem::path
& p
) {
38 write_escaped_string
<Char
>(std::back_inserter(quoted
), p
.string
<Char
>());
42 inline void write_escaped_path
<char>(basic_memory_buffer
<char>& quoted
,
43 const std::filesystem::path
& p
) {
44 auto s
= p
.u8string();
45 write_escaped_string
<char>(
46 std::back_inserter(quoted
),
47 string_view(reinterpret_cast<const char*>(s
.c_str()), s
.size()));
51 inline void write_escaped_path
<std::filesystem::path::value_type
>(
52 basic_memory_buffer
<std::filesystem::path::value_type
>& quoted
,
53 const std::filesystem::path
& p
) {
54 write_escaped_string
<std::filesystem::path::value_type
>(
55 std::back_inserter(quoted
), p
.native());
60 template <typename Char
>
61 struct formatter
<std::filesystem::path
, Char
>
62 : formatter
<basic_string_view
<Char
>> {
63 template <typename FormatContext
>
64 auto format(const std::filesystem::path
& p
, FormatContext
& ctx
) const ->
65 typename
FormatContext::iterator
{
66 basic_memory_buffer
<Char
> quoted
;
67 detail::write_escaped_path(quoted
, p
);
68 return formatter
<basic_string_view
<Char
>>::format(
69 basic_string_view
<Char
>(quoted
.data(), quoted
.size()), ctx
);
76 template <typename Char
>
77 struct formatter
<std::thread::id
, Char
> : basic_ostream_formatter
<Char
> {};
80 #ifdef __cpp_lib_variant
82 template <typename Char
> struct formatter
<std::monostate
, Char
> {
83 template <typename ParseContext
>
84 FMT_CONSTEXPR
auto parse(ParseContext
& ctx
) -> decltype(ctx
.begin()) {
88 template <typename FormatContext
>
89 auto format(const std::monostate
&, FormatContext
& ctx
) const
90 -> decltype(ctx
.out()) {
92 out
= detail::write
<Char
>(out
, "monostate");
100 using variant_index_sequence
=
101 std::make_index_sequence
<std::variant_size
<T
>::value
>;
103 // variant_size and variant_alternative check.
104 template <typename T
, typename U
= void>
105 struct is_variant_like_
: std::false_type
{};
106 template <typename T
>
107 struct is_variant_like_
<T
, std::void_t
<decltype(std::variant_size
<T
>::value
)>>
110 // formattable element check
111 template <typename T
, typename C
> class is_variant_formattable_
{
112 template <std::size_t... I
>
113 static std::conjunction
<
114 is_formattable
<std::variant_alternative_t
<I
, T
>, C
>...>
115 check(std::index_sequence
<I
...>);
118 static constexpr const bool value
=
119 decltype(check(variant_index_sequence
<T
>{}))::value
;
122 template <typename Char
, typename OutputIt
, typename T
>
123 auto write_variant_alternative(OutputIt out
, const T
& v
) -> OutputIt
{
124 if constexpr (is_string
<T
>::value
)
125 return write_escaped_string
<Char
>(out
, detail::to_string_view(v
));
126 else if constexpr (std::is_same_v
<T
, Char
>)
127 return write_escaped_char(out
, v
);
129 return write
<Char
>(out
, v
);
132 } // namespace detail
134 template <typename T
> struct is_variant_like
{
135 static constexpr const bool value
= detail::is_variant_like_
<T
>::value
;
138 template <typename T
, typename C
> struct is_variant_formattable
{
139 static constexpr const bool value
=
140 detail::is_variant_formattable_
<T
, C
>::value
;
143 template <typename Variant
, typename Char
>
146 std::enable_if_t
<std::conjunction_v
<
147 is_variant_like
<Variant
>, is_variant_formattable
<Variant
, Char
>>>> {
148 template <typename ParseContext
>
149 FMT_CONSTEXPR
auto parse(ParseContext
& ctx
) -> decltype(ctx
.begin()) {
153 template <typename FormatContext
>
154 auto format(const Variant
& value
, FormatContext
& ctx
) const
155 -> decltype(ctx
.out()) {
156 auto out
= ctx
.out();
158 out
= detail::write
<Char
>(out
, "variant(");
161 out
= detail::write_variant_alternative
<Char
>(out
, v
);