diff --git a/include/fmt/ostream.h b/include/fmt/ostream.h index e6c8256e..1eb9fd74 100644 --- a/include/fmt/ostream.h +++ b/include/fmt/ostream.h @@ -10,6 +10,10 @@ #include #include +#if _WIN32 && __GLIBCXX__ +# include +# include +#endif #include "format.h" @@ -92,12 +96,36 @@ inline bool write_ostream_msvc_unicode(std::wostream&, return false; } +#if _WIN32 && __GLIBCXX__ +inline bool write_ostream_gcc_mingw_unicode(std::ostream& os, + fmt::string_view data) { + auto* rdbuf = os.rdbuf(); + FILE* c_file; + if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_sync_filebuf*>(rdbuf)) + c_file = fbuf->file(); + else if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_filebuf*>(rdbuf)) + c_file = fbuf->file(); + else + return false; + if (c_file) return write_console_on_windows(c_file, data); + return false; +} + +inline bool write_ostream_gcc_mingw_unicode(std::wostream&, + fmt::basic_string_view) { + return false; +} +#endif + // Write the content of buf to os. // It is a separate function rather than a part of vprint to simplify testing. template void write_buffer(std::basic_ostream& os, buffer& buf) { - if (const_check(FMT_MSC_VERSION)) - if (write_ostream_msvc_unicode(os, {buf.data(), buf.size()})) return; +#if FMT_MSC_VERSION + if (write_ostream_msvc_unicode(os, {buf.data(), buf.size()})) return; +#elif _WIN32 && __GLIBCXX__ + if (write_ostream_gcc_mingw_unicode(os, {buf.data(), buf.size()})) return; +#endif const Char* buf_data = buf.data(); using unsigned_streamsize = std::make_unsigned::type; unsigned_streamsize size = buf.size();