https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121790
--- Comment #2 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Tomasz Kaminski <[email protected]>: https://gcc.gnu.org/g:8bd872f1ea74143aed0bd5148804a25dc6a9caf0 commit r16-4350-g8bd872f1ea74143aed0bd5148804a25dc6a9caf0 Author: Jonathan Wakely <[email protected]> Date: Wed Feb 21 16:11:53 2024 +0000 libstdc++: Implement P3107R5 optimizations for std::print [PR121790] The names of the vprint functions follow the convention from P3235R3. This takes advantage of the additional permission proposed by P3107R5 so that std::print can write directly to a FILE stream, rather than formatting to an intermediate std::string temporary and then writing that to the stream. The change is to write to a new _File_sink type instead of a _Str_sink that populates a std::string. There are three implementations of _File_sink. For non-Glibc targets that support POSIX flockfile and putc_unlocked, the stream will be locked and then formatted characters will be buffered on the stack (instead of allocating a std::string) and copied to the stream when the buffer fills up. For Glibc, _File_sink will lock the stream but then if the file is line-buffered or fully buffered, characters will be written directly into the file's output buffer. This avoids two levels of buffering and copying the characters from one to the other. For an unbuffered stream (like stderr) the _File_sink buffer will still be used, to avoid the overhead of lots of small writes to the stream. Because this version of _File_sink accesses the stream's buffer directly it relies on glibc-specific implementation details that are exposed in public headers. A fallback definition of _File_sink just wraps a _Str_sink so is equivalent to the original code, and is used when flockfile isn't available. Both forms of std::println (taking a FILE* and a std::ostream) can be implemented more efficiently by appending a newline to the format string, to avoid formatting twice. PR libstdc++/121790 libstdc++-v3/ChangeLog: * acinclude.m4 (GLIBCXX_CHECK_STDIO_LOCKING): New macro to check for std::print dependencies. * config.h.in: Regenerate. * configure: Regenerate. * configure.ac: Use GLIBCXX_CHECK_STDIO_LOCKING. * include/bits/formatfwd.h (enable_nonlocking_formatter_optimization): Define new variable template. * include/bits/version.def (print): Bump value. * include/bits/version.h: Regenerate. * include/std/format (enable_nonlocking_formatter_optimization): Define specializations for variable template. * include/std/ostream (print) [!_WIN32]: Do not use vprint_unicode at all. (println): Append newline to format string instead of formatting twice. * include/std/print (_File_sink): New class. (vprint_nonunicode_locking): New function. (vprint_unicode_locking): New function reusing previous code from vprint_unicode. (vprintf_unicode): Defer to vprint_nonunicode for Windows or to vprint_unicode_locking otherwise. (print): [!_WIN32]: Do no use vprint_unicode at all. Check enable_nonlocking_formatter_optimization and defer to either vprint_nonunicode_locking or vprint_nonunicode. (println): Use vprint_unicode or format directly to a _File_sink instead of formatting twice. * testsuite/27_io/print/1.cc: Updated and added new tests. * testsuite/std/format/formatter/nonlocking.cc: New tests. Reviewed-by: Jonathan Wakely <[email protected]> Reviewed-by: Tomasz KamiÅski <[email protected]> Co-authored-by: Tomasz KamiÅski <[email protected]>
