17 # include <ext/stdio_filebuf.h> 18 # include <ext/stdio_sync_filebuf.h> 25 #ifdef _MSVC_STL_UPDATE 26 # define FMT_MSVC_STL_UPDATE _MSVC_STL_UPDATE 27 #elif defined(_MSC_VER) && _MSC_VER < 1912 // VS 15.5 28 # define FMT_MSVC_STL_UPDATE _MSVC_LANG 30 # define FMT_MSVC_STL_UPDATE 0 39 struct file_access_tag {};
41 template <
typename Tag,
typename BufType, FILE* BufType::*FileMemberPtr>
43 friend auto get_file(BufType& obj) -> FILE* {
return obj.*FileMemberPtr; }
46 #if FMT_MSVC_STL_UPDATE 47 template class file_access<file_access_tag, std::filebuf,
48 &std::filebuf::_Myfile>;
49 auto get_file(std::filebuf&) -> FILE*;
54 template <
typename Char>
55 void write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf) {
56 const Char* buf_data = buf.data();
57 using unsigned_streamsize = make_unsigned_t<std::streamsize>;
58 unsigned_streamsize size = buf.size();
59 unsigned_streamsize max_size = to_unsigned(max_value<std::streamsize>());
61 unsigned_streamsize n = size <= max_size ? size : max_size;
62 os.write(buf_data, static_cast<std::streamsize>(n));
68 template <
typename T>
struct streamed_view {
74 template <
typename Char>
75 struct basic_ostream_formatter : formatter<basic_string_view<Char>, Char> {
76 void set_debug_format() =
delete;
78 template <
typename T,
typename Context>
79 auto format(
const T& value, Context& ctx)
const -> decltype(ctx.out()) {
81 auto&& formatbuf = detail::formatbuf<std::basic_streambuf<Char>>(buffer);
82 auto&& output = std::basic_ostream<Char>(&formatbuf);
83 output.imbue(std::locale::classic());
85 output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
86 return formatter<basic_string_view<Char>, Char>::format(
87 {buffer.data(), buffer.size()}, ctx);
91 using ostream_formatter = basic_ostream_formatter<char>;
93 template <
typename T,
typename Char>
94 struct formatter<
detail::streamed_view<T>, Char>
95 : basic_ostream_formatter<Char> {
96 template <
typename Context>
97 auto format(detail::streamed_view<T> view, Context& ctx)
const 98 -> decltype(ctx.out()) {
99 return basic_ostream_formatter<Char>::format(view.value, ctx);
111 template <
typename T>
112 constexpr
auto streamed(
const T& value) -> detail::streamed_view<T> {
118 detail::vformat_to(buffer, fmt, args);
120 #if FMT_MSVC_STL_UPDATE && FMT_USE_RTTI 121 if (
auto* buf = dynamic_cast<std::filebuf*>(os.rdbuf()))
122 f = detail::get_file(*buf);
123 #elif defined(_WIN32) && defined(__GLIBCXX__) && FMT_USE_RTTI 124 auto* rdbuf = os.rdbuf();
125 if (
auto* sfbuf =
dynamic_cast<__gnu_cxx::stdio_sync_filebuf<char>*
>(rdbuf))
127 else if (
auto* fbuf =
dynamic_cast<__gnu_cxx::stdio_filebuf<char>*
>(rdbuf))
135 if (detail::write_console(fd, {buffer.data(), buffer.size()}))
return;
139 detail::ignore_unused(f);
140 detail::write_buffer(os, buffer);
150 FMT_EXPORT
template <
typename... T>
151 void print(std::ostream& os, format_string<T...> fmt, T&&... args) {
152 fmt::vargs<T...> vargs = {{args...}};
153 if (detail::const_check(detail::use_utf8))
return vprint(os, fmt.str, vargs);
155 detail::vformat_to(buffer, fmt.str, vargs);
156 detail::write_buffer(os, buffer);
159 FMT_EXPORT
template <
typename... T>
160 void println(std::ostream& os, format_string<T...> fmt, T&&... args) {
161 fmt::print(os, FMT_STRING(
"{}\n"),
162 fmt::format(fmt, std::forward<T>(args)...));
167 #endif // FMT_OSTREAM_H_ A dynamically growing memory buffer for trivially copyable/constructible types with the first SIZE el...
Definition: format.h:785
Converts a string literal into a format string that will be parsed at compile time and converted into...
Definition: args.h:20