1 // Formatting library for C++ - std::ostream support
3 // Copyright (c) 2012 - present, Victor Zverovich
4 // All rights reserved.
6 // For the license information refer to format.h.
17 template <typename OutputIt
, typename Char
> class basic_printf_context
;
21 // Checks if T has a user-defined operator<<.
22 template <typename T
, typename Char
, typename Enable
= void>
27 -> bool_constant
<sizeof(std::declval
<std::basic_ostream
<Char
>&>()
28 << std::declval
<U
>()) != 0>;
30 template <typename
> static auto test(...) -> std::false_type
;
32 using result
= decltype(test
<T
>(0));
35 is_streamable() = default;
37 static const bool value
= result::value
;
40 // Formatting of built-in types and arrays is intentionally disabled because
41 // it's handled by standard (non-ostream) formatters.
42 template <typename T
, typename Char
>
46 std::is_arithmetic
<T
>::value
|| std::is_array
<T
>::value
||
47 std::is_pointer
<T
>::value
|| std::is_same
<T
, char8_type
>::value
||
48 std::is_same
<T
, std::basic_string
<Char
>>::value
||
49 std::is_same
<T
, std_string_view
<Char
>>::value
||
50 (std::is_convertible
<T
, int>::value
&& !std::is_enum
<T
>::value
)>>
53 // Write the content of buf to os.
54 // It is a separate function rather than a part of vprint to simplify testing.
55 template <typename Char
>
56 void write_buffer(std::basic_ostream
<Char
>& os
, buffer
<Char
>& buf
) {
57 const Char
* buf_data
= buf
.data();
58 using unsigned_streamsize
= std::make_unsigned
<std::streamsize
>::type
;
59 unsigned_streamsize size
= buf
.size();
60 unsigned_streamsize max_size
= to_unsigned(max_value
<std::streamsize
>());
62 unsigned_streamsize n
= size
<= max_size
? size
: max_size
;
63 os
.write(buf_data
, static_cast<std::streamsize
>(n
));
69 template <typename Char
, typename T
>
70 void format_value(buffer
<Char
>& buf
, const T
& value
,
71 locale_ref loc
= locale_ref()) {
72 auto&& format_buf
= formatbuf
<std::basic_streambuf
<Char
>>(buf
);
73 auto&& output
= std::basic_ostream
<Char
>(&format_buf
);
74 #if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
75 if (loc
) output
.imbue(loc
.get
<std::locale
>());
78 output
.exceptions(std::ios_base::failbit
| std::ios_base::badbit
);
79 buf
.try_resize(buf
.size());
82 // Formats an object of type T that has an overloaded ostream operator<<.
83 template <typename T
, typename Char
>
84 struct fallback_formatter
<T
, Char
, enable_if_t
<is_streamable
<T
, Char
>::value
>>
85 : private formatter
<basic_string_view
<Char
>, Char
> {
86 using formatter
<basic_string_view
<Char
>, Char
>::parse
;
88 template <typename OutputIt
>
89 auto format(const T
& value
, basic_format_context
<OutputIt
, Char
>& ctx
)
91 auto buffer
= basic_memory_buffer
<Char
>();
92 format_value(buffer
, value
, ctx
.locale());
93 return formatter
<basic_string_view
<Char
>, Char
>::format(
94 {buffer
.data(), buffer
.size()}, ctx
);
98 template <typename OutputIt
>
99 auto format(const T
& value
, basic_printf_context
<OutputIt
, Char
>& ctx
)
101 auto buffer
= basic_memory_buffer
<Char
>();
102 format_value(buffer
, value
, ctx
.locale());
103 return std::copy(buffer
.begin(), buffer
.end(), ctx
.out());
106 } // namespace detail
109 template <typename Char
>
110 void vprint(std::basic_ostream
<Char
>& os
, basic_string_view
<Char
> format_str
,
111 basic_format_args
<buffer_context
<type_identity_t
<Char
>>> args
) {
112 auto buffer
= basic_memory_buffer
<Char
>();
113 detail::vformat_to(buffer
, format_str
, args
);
114 detail::write_buffer(os
, buffer
);
119 Prints formatted data to the stream *os*.
123 fmt::print(cerr, "Don't {}!", "panic");
127 template <typename S
, typename
... Args
,
128 typename Char
= enable_if_t
<detail::is_string
<S
>::value
, char_t
<S
>>>
129 void print(std::basic_ostream
<Char
>& os
, const S
& format_str
, Args
&&... args
) {
130 vprint(os
, to_string_view(format_str
),
131 fmt::make_args_checked
<Args
...>(format_str
, args
...));
135 #endif // FMT_OSTREAM_H_