Warning, file /include/fmt/ostream.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef FMT_OSTREAM_H_
0009 #define FMT_OSTREAM_H_
0010
0011 #ifndef FMT_MODULE
0012 # include <fstream> // std::filebuf
0013 #endif
0014
0015 #ifdef _WIN32
0016 # ifdef __GLIBCXX__
0017 # include <ext/stdio_filebuf.h>
0018 # include <ext/stdio_sync_filebuf.h>
0019 # endif
0020 # include <io.h>
0021 #endif
0022
0023 #include "chrono.h" // formatbuf
0024
0025 #ifdef _MSVC_STL_UPDATE
0026 # define FMT_MSVC_STL_UPDATE _MSVC_STL_UPDATE
0027 #elif defined(_MSC_VER) && _MSC_VER < 1912
0028 # define FMT_MSVC_STL_UPDATE _MSVC_LANG
0029 #else
0030 # define FMT_MSVC_STL_UPDATE 0
0031 #endif
0032
0033 FMT_BEGIN_NAMESPACE
0034 namespace detail {
0035
0036
0037
0038 namespace {
0039 struct file_access_tag {};
0040 }
0041 template <typename Tag, typename BufType, FILE* BufType::*FileMemberPtr>
0042 class file_access {
0043 friend auto get_file(BufType& obj) -> FILE* { return obj.*FileMemberPtr; }
0044 };
0045
0046 #if FMT_MSVC_STL_UPDATE
0047 template class file_access<file_access_tag, std::filebuf,
0048 &std::filebuf::_Myfile>;
0049 auto get_file(std::filebuf&) -> FILE*;
0050 #endif
0051
0052
0053
0054 template <typename Char>
0055 void write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf) {
0056 const Char* buf_data = buf.data();
0057 using unsigned_streamsize = make_unsigned_t<std::streamsize>;
0058 unsigned_streamsize size = buf.size();
0059 unsigned_streamsize max_size = to_unsigned(max_value<std::streamsize>());
0060 do {
0061 unsigned_streamsize n = size <= max_size ? size : max_size;
0062 os.write(buf_data, static_cast<std::streamsize>(n));
0063 buf_data += n;
0064 size -= n;
0065 } while (size != 0);
0066 }
0067
0068 template <typename T> struct streamed_view {
0069 const T& value;
0070 };
0071 }
0072
0073
0074 template <typename Char>
0075 struct basic_ostream_formatter : formatter<basic_string_view<Char>, Char> {
0076 void set_debug_format() = delete;
0077
0078 template <typename T, typename Context>
0079 auto format(const T& value, Context& ctx) const -> decltype(ctx.out()) {
0080 auto buffer = basic_memory_buffer<Char>();
0081 auto&& formatbuf = detail::formatbuf<std::basic_streambuf<Char>>(buffer);
0082 auto&& output = std::basic_ostream<Char>(&formatbuf);
0083 output.imbue(std::locale::classic());
0084 output << value;
0085 output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
0086 return formatter<basic_string_view<Char>, Char>::format(
0087 {buffer.data(), buffer.size()}, ctx);
0088 }
0089 };
0090
0091 using ostream_formatter = basic_ostream_formatter<char>;
0092
0093 template <typename T, typename Char>
0094 struct formatter<detail::streamed_view<T>, Char>
0095 : basic_ostream_formatter<Char> {
0096 template <typename Context>
0097 auto format(detail::streamed_view<T> view, Context& ctx) const
0098 -> decltype(ctx.out()) {
0099 return basic_ostream_formatter<Char>::format(view.value, ctx);
0100 }
0101 };
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111 template <typename T>
0112 constexpr auto streamed(const T& value) -> detail::streamed_view<T> {
0113 return {value};
0114 }
0115
0116 inline void vprint(std::ostream& os, string_view fmt, format_args args) {
0117 auto buffer = memory_buffer();
0118 detail::vformat_to(buffer, fmt, args);
0119 FILE* f = nullptr;
0120 #if FMT_MSVC_STL_UPDATE && FMT_USE_RTTI
0121 if (auto* buf = dynamic_cast<std::filebuf*>(os.rdbuf()))
0122 f = detail::get_file(*buf);
0123 #elif defined(_WIN32) && defined(__GLIBCXX__) && FMT_USE_RTTI
0124 auto* rdbuf = os.rdbuf();
0125 if (auto* sfbuf = dynamic_cast<__gnu_cxx::stdio_sync_filebuf<char>*>(rdbuf))
0126 f = sfbuf->file();
0127 else if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_filebuf<char>*>(rdbuf))
0128 f = fbuf->file();
0129 #endif
0130 #ifdef _WIN32
0131 if (f) {
0132 int fd = _fileno(f);
0133 if (_isatty(fd)) {
0134 os.flush();
0135 if (detail::write_console(fd, {buffer.data(), buffer.size()})) return;
0136 }
0137 }
0138 #endif
0139 detail::ignore_unused(f);
0140 detail::write_buffer(os, buffer);
0141 }
0142
0143
0144
0145
0146
0147
0148
0149
0150 FMT_EXPORT template <typename... T>
0151 void print(std::ostream& os, format_string<T...> fmt, T&&... args) {
0152 fmt::vargs<T...> vargs = {{args...}};
0153 if (detail::const_check(detail::use_utf8)) return vprint(os, fmt.str, vargs);
0154 auto buffer = memory_buffer();
0155 detail::vformat_to(buffer, fmt.str, vargs);
0156 detail::write_buffer(os, buffer);
0157 }
0158
0159 FMT_EXPORT template <typename... T>
0160 void println(std::ostream& os, format_string<T...> fmt, T&&... args) {
0161 fmt::print(os, FMT_STRING("{}\n"),
0162 fmt::format(fmt, std::forward<T>(args)...));
0163 }
0164
0165 FMT_END_NAMESPACE
0166
0167 #endif