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]>

Reply via email to