get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2224450/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2224450,
    "url": "http://patchwork.ozlabs.org/api/patches/2224450/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/20260417124712.324159-1-jwakely@redhat.com/",
    "project": {
        "id": 17,
        "url": "http://patchwork.ozlabs.org/api/projects/17/?format=api",
        "name": "GNU Compiler Collection",
        "link_name": "gcc",
        "list_id": "gcc-patches.gcc.gnu.org",
        "list_email": "gcc-patches@gcc.gnu.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20260417124712.324159-1-jwakely@redhat.com>",
    "list_archive_url": null,
    "date": "2026-04-17T12:45:36",
    "name": "[committed,v2] libstdc++: Optionally define std::print functions non-inline [PR124410]",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "0c53d853ea71b23c9d743c7d1475430653e5da53",
    "submitter": {
        "id": 48004,
        "url": "http://patchwork.ozlabs.org/api/people/48004/?format=api",
        "name": "Jonathan Wakely",
        "email": "jwakely@redhat.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/20260417124712.324159-1-jwakely@redhat.com/mbox/",
    "series": [
        {
            "id": 500328,
            "url": "http://patchwork.ozlabs.org/api/series/500328/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=500328",
            "date": "2026-04-17T12:45:36",
            "name": "[committed,v2] libstdc++: Optionally define std::print functions non-inline [PR124410]",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/500328/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2224450/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2224450/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "gcc-patches@gcc.gnu.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@legolas.ozlabs.org",
            "gcc-patches@gcc.gnu.org"
        ],
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=d0sa8ekW;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)",
            "sourceware.org;\n\tdkim=pass (1024-bit key,\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=d0sa8ekW",
            "sourceware.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com",
            "sourceware.org; spf=pass smtp.mailfrom=redhat.com",
            "server2.sourceware.org;\n arc=none smtp.remote-ip=170.10.133.124"
        ],
        "Received": [
            "from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fxvn154Vwz1yCv\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 17 Apr 2026 22:48:04 +1000 (AEST)",
            "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 1D1F04AA3971\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 17 Apr 2026 12:48:02 +0000 (GMT)",
            "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.133.124])\n by sourceware.org (Postfix) with ESMTP id 7AB434BA2E32\n for <gcc-patches@gcc.gnu.org>; Fri, 17 Apr 2026 12:47:20 +0000 (GMT)",
            "from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-60-Mg-7o3SGMn-1lsHBdWwOdw-1; Fri,\n 17 Apr 2026 08:47:16 -0400",
            "from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id A2B5818002C6; Fri, 17 Apr 2026 12:47:15 +0000 (UTC)",
            "from zen.kayari.org (unknown [10.44.48.52])\n by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP\n id ADC70195608E; Fri, 17 Apr 2026 12:47:13 +0000 (UTC)"
        ],
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 sourceware.org 1D1F04AA3971",
            "OpenDKIM Filter v2.11.0 sourceware.org 7AB434BA2E32"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org 7AB434BA2E32",
        "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org 7AB434BA2E32",
        "ARC-Seal": "i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776430040; cv=none;\n b=Zr4xL54d9tN6HcvIx2eZMAjcPXfGj2MCcS+F3GgK3RwJ4KjUzjUQ/SPstGkKCoNH0dmRYOEFiCVkhHdvS4K9JaHcD+rtBs4gUXIyLsg3IQVASBy8lman8u7OVpzgL1qhWZA5hoI+NNNrIrQrmggmqqqPxY0KEW+jgF1BaNxR5Tg=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1776430040; c=relaxed/simple;\n bh=gtHHUg02dKbb7Bak095xjV75oW1QBRv9vg0J4T2tS+c=;\n h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version;\n b=rISQSfh8f2sGId2vBVp2hVm7DfF2bhMGi64RNgQvd6RDz/gPWHIpu7qrzU3ZVJwPGJYOi0RrEJvWVTmwys9lj2MVNl0zg7AW6Xqpl+KePtWMYPHxCYxcINvA5ayMo7evhlwZVM3rMYD75assBOsPXd2FBZEcRL0avdvgO2N1g0Y=",
        "ARC-Authentication-Results": "i=1; server2.sourceware.org",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1776430040;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding;\n bh=O9QQMAG9dhbqa4h+bXZEi5ncMAav8MruVHNz694E/Ss=;\n b=d0sa8ekWoN4iq0xPEssmMrtuJ3n43qGjO/2QZYOAuQh2u72VftIXmvrwldSbGCOMAUXSsP\n ooF7T/j9Uh79FmtX10znkX6Ioliql7vgXX8njwXdW6Ib8nSorePJqsfp4fRERbAvL49Ica\n vtXdLicPLZ5qkNT9f5jSsoYre1zWWWI=",
        "X-MC-Unique": "Mg-7o3SGMn-1lsHBdWwOdw-1",
        "X-Mimecast-MFC-AGG-ID": "Mg-7o3SGMn-1lsHBdWwOdw_1776430035",
        "From": "Jonathan Wakely <jwakely@redhat.com>",
        "To": "libstdc++@gcc.gnu.org,\n\tgcc-patches@gcc.gnu.org",
        "Subject": "[committed v2] libstdc++: Optionally define std::print functions\n non-inline [PR124410]",
        "Date": "Fri, 17 Apr 2026 13:45:36 +0100",
        "Message-ID": "<20260417124712.324159-1-jwakely@redhat.com>",
        "MIME-Version": "1.0",
        "X-Scanned-By": "MIMEDefang 3.0 on 10.30.177.17",
        "X-Mimecast-Spam-Score": "0",
        "X-Mimecast-MFC-PROC-ID": "r5GtzYF73j-5sjGrhIy2WrVFgAXVHQ_zaW-HEfInWnw_1776430035",
        "X-Mimecast-Originator": "redhat.com",
        "Content-Type": "text/plain",
        "Content-Transfer-Encoding": "quoted-printable",
        "X-BeenThere": "gcc-patches@gcc.gnu.org",
        "X-Mailman-Version": "2.1.30",
        "Precedence": "list",
        "List-Id": "Gcc-patches mailing list <gcc-patches.gcc.gnu.org>",
        "List-Unsubscribe": "<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>",
        "List-Archive": "<https://gcc.gnu.org/pipermail/gcc-patches/>",
        "List-Post": "<mailto:gcc-patches@gcc.gnu.org>",
        "List-Help": "<mailto:gcc-patches-request@gcc.gnu.org?subject=help>",
        "List-Subscribe": "<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>",
        "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"
    },
    "content": "We don't want to export std::vprint_unicode etc. from libstdc++.so yet,\nbut we can give users the option of improving compile times by getting\nthe definitions of the std::print internals from libstdc++exp.a instead.\n\nThis commit adds a macro, _GLIBCXX_NO_INLINE_PRINT, which disables the\ninline definitions of std::vprint_unicode etc. so that extern\ndefinitions in libstdc++exp.a can be used instead.\n\nWith this change compiling a helloworld using std::print goes from 8s to\nunder 2s with trunk. For release branches with --enable-checking=release\nwe should see even faster times. The object file size is also\ndramatically smaller, because there's just a single call to an extern\nfunction instead of instantiating the entire std::print and std::format\nimplementation inline.\n\nlibstdc++-v3/ChangeLog:\n\n\tPR libstdc++/124410\n\t* doc/html/*: Regenerate.\n\t* doc/xml/manual/using.xml (_GLIBCXX_NO_INLINE_PRINT): Document\n\tmacro.\n\t* include/Makefile.am: Add bits/print.h and bits/ostream_print.h\n\theaders.\n\t* include/Makefile.in: Regenerate.\n\t* include/std/ostream (vprint_nonunicode, vprint_unicode): Move\n\tdefinitions to new bits/ostream_print.h header.\n\t* include/std/print (__format::_File_sink, vprint_nonunicode)\n\t(vprint_nonunicode_buffered, vprint_unicode)\n\t(vprint_unicode_buffered): Move definitions to new bits/print.h\n\theader.\n\t* src/c++23/print.cc: Include new headers to define symbols for\n\tinline print functions.\n\t* include/bits/ostream_print.h: New file.\n\t* include/bits/print.h: New file.\n---\n\nv2: Added a sentence to the docs about linking to the non-inline\ndefinitions from a TU with a non-UTF-8 literal encoding.\n\nTested x86_64-linux, aarch64-linux, sparc-solaris.\nPushed to trunk.\n\n libstdc++-v3/doc/html/index.html              |   4 +-\n libstdc++-v3/doc/html/manual/using.html       |   2 +\n .../doc/html/manual/using_macros.html         |   9 +\n libstdc++-v3/doc/xml/manual/using.xml         |  15 +\n libstdc++-v3/include/Makefile.am              |   2 +\n libstdc++-v3/include/Makefile.in              |   2 +\n libstdc++-v3/include/bits/ostream_print.h     | 161 +++++++++\n libstdc++-v3/include/bits/print.h             | 339 ++++++++++++++++++\n libstdc++-v3/include/std/ostream              | 112 +-----\n libstdc++-v3/include/std/print                | 295 ++-------------\n libstdc++-v3/src/c++23/print.cc               |   7 +\n 11 files changed, 583 insertions(+), 365 deletions(-)\n create mode 100644 libstdc++-v3/include/bits/ostream_print.h\n create mode 100644 libstdc++-v3/include/bits/print.h",
    "diff": "diff --git a/libstdc++-v3/doc/html/index.html b/libstdc++-v3/doc/html/index.html\nindex 01d7bb787dce..782f3bbc299c 100644\n--- a/libstdc++-v3/doc/html/index.html\n+++ b/libstdc++-v3/doc/html/index.html\n@@ -1,6 +1,6 @@\n <?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n-<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html xmlns=\"http://www.w3.org/1999/xhtml\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /><title>The GNU C++ Library</title><meta name=\"generator\" content=\"DocBook XSL Stylesheets Vsnapshot\" /><meta name=\"description\" content=\"Short Contents Copyright (C) 2008-2025 FSF Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. This is the top level of the libstdc++ documentation set. The documentation is divided into the following three sections. Manual Frequently Asked Questions API and Source Documentation\" /><meta name=\"keywords\" content=\"ISO C++, runtime, library\" /><link rel=\"home\" href=\"index.html\" title=\"The GNU C++ Library\" /><link rel=\"next\" href=\"manual/index.html\" title=\"The GNU C++ Library Manual\" /></head><body><div class=\"navheader\"><table width=\"100%\" summary=\"Navigation header\"><tr><th colspan=\"3\" align=\"center\">The GNU C++ Library</th></tr><tr><td width=\"20%\" align=\"left\"> </td><th width=\"60%\" align=\"center\"> </th><td width=\"20%\" align=\"right\"> <a accesskey=\"n\" href=\"manual/index.html\">Next</a></td></tr></table><hr /></div><div class=\"set\" lang=\"en\" xml:lang=\"en\"><div class=\"titlepage\"><div><div><h1 class=\"title\"><a id=\"set-index\"></a>The GNU C++ Library</h1></div><div><div class=\"abstract\"><a id=\"contents\"></a><p class=\"title\"><strong>Short Contents</strong></p><p>\n-      Copyright (C) 2008-2025\n+<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html xmlns=\"http://www.w3.org/1999/xhtml\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /><title>The GNU C++ Library</title><meta name=\"generator\" content=\"DocBook XSL Stylesheets Vsnapshot\" /><meta name=\"description\" content=\"Short Contents Copyright (C) 2008-2026 FSF Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. This is the top level of the libstdc++ documentation set. The documentation is divided into the following three sections. Manual Frequently Asked Questions API and Source Documentation\" /><meta name=\"keywords\" content=\"ISO C++, runtime, library\" /><link rel=\"home\" href=\"index.html\" title=\"The GNU C++ Library\" /><link rel=\"next\" href=\"manual/index.html\" title=\"The GNU C++ Library Manual\" /></head><body><div class=\"navheader\"><table width=\"100%\" summary=\"Navigation header\"><tr><th colspan=\"3\" align=\"center\">The GNU C++ Library</th></tr><tr><td width=\"20%\" align=\"left\"> </td><th width=\"60%\" align=\"center\"> </th><td width=\"20%\" align=\"right\"> <a accesskey=\"n\" href=\"manual/index.html\">Next</a></td></tr></table><hr /></div><div class=\"set\" lang=\"en\" xml:lang=\"en\"><div class=\"titlepage\"><div><div><h1 class=\"title\"><a id=\"set-index\"></a>The GNU C++ Library</h1></div><div><div class=\"abstract\"><a id=\"contents\"></a><p class=\"title\"><strong>Short Contents</strong></p><p>\n+      Copyright (C) 2008-2026\n       <a class=\"link\" href=\"https://www.fsf.org\" target=\"_top\">FSF\n       </a>\n     </p><p>\ndiff --git a/libstdc++-v3/doc/html/manual/using.html b/libstdc++-v3/doc/html/manual/using.html\nindex fcd1b96de0d7..27f503ecaccc 100644\n--- a/libstdc++-v3/doc/html/manual/using.html\n+++ b/libstdc++-v3/doc/html/manual/using.html\n@@ -34,6 +34,8 @@\n         is required for use of experimental C++ library features.\n         This currently provides support for the C++23 types defined in the\n         <code class=\"filename\">&lt;stacktrace&gt;</code> header,\n+\tthe C++23 functions defined in the\n+\t<code class=\"filename\">&lt;print&gt;</code> header,\n         the Filesystem library extensions defined in the\n         <code class=\"filename\">&lt;experimental/filesystem&gt;</code>\n         header,\ndiff --git a/libstdc++-v3/doc/html/manual/using_macros.html b/libstdc++-v3/doc/html/manual/using_macros.html\nindex b1d05d99d760..f1d8492fb9ef 100644\n--- a/libstdc++-v3/doc/html/manual/using_macros.html\n+++ b/libstdc++-v3/doc/html/manual/using_macros.html\n@@ -147,4 +147,13 @@\n \tmode will revert to the non-conforming implementation used prior to the\n \t<a class=\"link\" href=\"https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112591\" target=\"_top\">PR112591</a>\n \tin GCC-16. Has no impact for C++20 or later modes.\n+      </p></dd><dt><span class=\"term\"><code class=\"code\">_GLIBCXX_NO_INLINE_PRINT</code></span></dt><dd><p>\n+\tUndefined by default. When defined <code class=\"code\">std::print</code> and\n+\t<code class=\"code\">std::println</code> are not implemented using inline functions.\n+\tThis means that code using those functions will compile faster,\n+\tbut <code class=\"option\">-lstdc++exp</code> must be used when linking.\n+\tThe non-inline definitions are compiled using\n+\t<code class=\"option\">-fexec-charset=UTF-8</code> so might give incorrect results\n+\tif called from a source file that uses a non-Unicode encoding,\n+\tespecially for format strings using non-ASCII fill characters.\n       </p></dd></dl></div></div><div class=\"navfooter\"><hr /><table width=\"100%\" summary=\"Navigation footer\"><tr><td width=\"40%\" align=\"left\"><a accesskey=\"p\" href=\"using_headers.html\">Prev</a> </td><td width=\"20%\" align=\"center\"><a accesskey=\"u\" href=\"using.html\">Up</a></td><td width=\"40%\" align=\"right\"> <a accesskey=\"n\" href=\"using_dual_abi.html\">Next</a></td></tr><tr><td width=\"40%\" align=\"left\" valign=\"top\">Headers </td><td width=\"20%\" align=\"center\"><a accesskey=\"h\" href=\"../index.html\">Home</a></td><td width=\"40%\" align=\"right\" valign=\"top\"> Dual ABI</td></tr></table></div></body></html>\n\\ No newline at end of file\ndiff --git a/libstdc++-v3/doc/xml/manual/using.xml b/libstdc++-v3/doc/xml/manual/using.xml\nindex 8adfecfe54ba..682669d91d4b 100644\n--- a/libstdc++-v3/doc/xml/manual/using.xml\n+++ b/libstdc++-v3/doc/xml/manual/using.xml\n@@ -83,6 +83,8 @@\n         is required for use of experimental C++ library features.\n         This currently provides support for the C++23 types defined in the\n         <filename class=\"headerfile\">&lt;stacktrace&gt;</filename> header,\n+\tthe C++23 functions defined in the\n+\t<filename class=\"headerfile\">&lt;print&gt;</filename> header,\n         the Filesystem library extensions defined in the\n         <filename class=\"headerfile\">&lt;experimental/filesystem&gt;</filename>\n         header,\n@@ -1363,6 +1365,19 @@ g++ -Winvalid-pch -I. -include stdc++.h -H -g -O2 hello.cc -o test.exe\n \tin GCC-16. Has no impact for C++20 or later modes.\n       </para>\n     </listitem></varlistentry>\n+    <varlistentry><term><code>_GLIBCXX_NO_INLINE_PRINT</code></term>\n+    <listitem>\n+      <para>\n+\tUndefined by default. When defined <code>std::print</code> and\n+\t<code>std::println</code> are not implemented using inline functions.\n+\tThis means that code using those functions will compile faster,\n+\tbut <option>-lstdc++exp</option> must be used when linking.\n+\tThe non-inline definitions are compiled using\n+\t<option>-fexec-charset=UTF-8</option> so might give incorrect results\n+\tif called from a source file that uses a non-Unicode encoding,\n+\tespecially for format strings using non-ASCII fill characters.\n+      </para>\n+    </listitem></varlistentry>\n     </variablelist>\n \n   </section>\ndiff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am\nindex d0c97370700b..e9e46139da2f 100644\n--- a/libstdc++-v3/include/Makefile.am\n+++ b/libstdc++-v3/include/Makefile.am\n@@ -244,7 +244,9 @@ bits_headers = \\\n \t${bits_srcdir}/node_handle.h \\\n \t${bits_srcdir}/ostream.tcc \\\n \t${bits_srcdir}/ostream_insert.h \\\n+\t${bits_srcdir}/ostream_print.h \\\n \t${bits_srcdir}/postypes.h \\\n+\t${bits_srcdir}/print.h \\\n \t${bits_srcdir}/quoted_string.h \\\n \t${bits_srcdir}/random.h \\\n \t${bits_srcdir}/random.tcc \\\ndiff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in\nindex a57fc00ce742..f3d2f58dbe42 100644\n--- a/libstdc++-v3/include/Makefile.in\n+++ b/libstdc++-v3/include/Makefile.in\n@@ -600,7 +600,9 @@ bits_freestanding = \\\n @GLIBCXX_HOSTED_TRUE@\t${bits_srcdir}/node_handle.h \\\n @GLIBCXX_HOSTED_TRUE@\t${bits_srcdir}/ostream.tcc \\\n @GLIBCXX_HOSTED_TRUE@\t${bits_srcdir}/ostream_insert.h \\\n+@GLIBCXX_HOSTED_TRUE@\t${bits_srcdir}/ostream_print.h \\\n @GLIBCXX_HOSTED_TRUE@\t${bits_srcdir}/postypes.h \\\n+@GLIBCXX_HOSTED_TRUE@\t${bits_srcdir}/print.h \\\n @GLIBCXX_HOSTED_TRUE@\t${bits_srcdir}/quoted_string.h \\\n @GLIBCXX_HOSTED_TRUE@\t${bits_srcdir}/random.h \\\n @GLIBCXX_HOSTED_TRUE@\t${bits_srcdir}/random.tcc \\\ndiff --git a/libstdc++-v3/include/bits/ostream_print.h b/libstdc++-v3/include/bits/ostream_print.h\nnew file mode 100644\nindex 000000000000..0adf16d4fe3e\n--- /dev/null\n+++ b/libstdc++-v3/include/bits/ostream_print.h\n@@ -0,0 +1,161 @@\n+// Inline implementation details for std::print functions -*- C++ -*-\n+\n+// Copyright The GNU Toolchain Authors.\n+//\n+// This file is part of the GNU ISO C++ Library.  This library is free\n+// software; you can redistribute it and/or modify it under the\n+// terms of the GNU General Public License as published by the\n+// Free Software Foundation; either version 3, or (at your option)\n+// any later version.\n+\n+// This library is distributed in the hope that it will be useful,\n+// but WITHOUT ANY WARRANTY; without even the implied warranty of\n+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+// GNU General Public License for more details.\n+\n+// Under Section 7 of GPL version 3, you are granted additional\n+// permissions described in the GCC Runtime Library Exception, version\n+// 3.1, as published by the Free Software Foundation.\n+\n+// You should have received a copy of the GNU General Public License and\n+// a copy of the GCC Runtime Library Exception along with this program;\n+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see\n+// <http://www.gnu.org/licenses/>.\n+\n+/** @file include/bits/ostream_print.h\n+ *  This is an internal header file, included by other library headers.\n+ *  Do not attempt to use it directly. @headername{ostream}\n+ *\n+ *  This file contains the parts of `<ostream>` which are currently defined\n+ *  inline, but should be moved into the library eventually.\n+ */\n+\n+#ifndef _GLIBCXX_OSTREAM_PRINT_H\n+#define _GLIBCXX_OSTREAM_PRINT_H 1\n+\n+#ifdef _GLIBCXX_SYSHDR\n+#pragma GCC system_header\n+#endif\n+\n+#include <bits/requires_hosted.h> // for std::format\n+\n+#include <bits/version.h>\n+\n+#ifdef __glibcxx_print // C++ >= 23\n+#include <format>\n+\n+namespace std _GLIBCXX_VISIBILITY(default)\n+{\n+_GLIBCXX_BEGIN_NAMESPACE_VERSION\n+\n+#ifdef _GLIBCXX_NO_INLINE_PRINT\n+# define _GLIBCXX_PRINT_INLINE_USED [[__gnu__::__used__]]\n+#else\n+# define _GLIBCXX_PRINT_INLINE_USED\n+#endif\n+\n+  _GLIBCXX_PRINT_INLINE_USED\n+  inline void\n+  vprint_nonunicode(ostream& __os, string_view __fmt, format_args __args)\n+  {\n+    ostream::sentry __cerb(__os);\n+    if (__cerb)\n+      {\n+\t__format::_Str_sink<char> __buf;\n+\tstd::vformat_to(__buf.out(), __os.getloc(), __fmt, __args);\n+\tauto __out = __buf.view();\n+\n+\t__try\n+\t  {\n+\t    std::__ostream_write(__os, __out.data(), __out.size());\n+\t  }\n+\t__catch(const __cxxabiv1::__forced_unwind&)\n+\t  {\n+\t    __os._M_setstate(ios_base::badbit);\n+\t    __throw_exception_again;\n+\t  }\n+\t__catch(...)\n+\t  { __os._M_setstate(ios_base::badbit); }\n+      }\n+  }\n+\n+  _GLIBCXX_PRINT_INLINE_USED\n+  inline void\n+  vprint_unicode(ostream& __os, string_view __fmt, format_args __args)\n+  {\n+#if !defined(_WIN32) || defined(__CYGWIN__)\n+    // For most targets we don't need to do anything special to write\n+    // Unicode to a terminal.\n+    std::vprint_nonunicode(__os, __fmt, __args);\n+#else\n+    ostream::sentry __cerb(__os);\n+    if (__cerb)\n+      {\n+\t__format::_Str_sink<char> __buf;\n+\tstd::vformat_to(__buf.out(), __os.getloc(), __fmt, __args);\n+\tauto __out = __buf._M_span();\n+\n+\tvoid* __open_terminal(streambuf*);\n+\terror_code __write_to_terminal(void*, span<char>);\n+\t// If stream refers to a terminal, write a Unicode string to it.\n+\tif (auto __term = __open_terminal(__os.rdbuf()))\n+\t  {\n+#if !defined(_WIN32) || defined(__CYGWIN__)\n+\t    // For POSIX, __open_terminal(streambuf*) uses fdopen to open a\n+\t    // new file, so we would need to close it here. This code is not\n+\t    // actually compiled because it's inside an #ifdef _WIN32 group,\n+\t    // but just in case that changes in future ...\n+\t    struct _Guard\n+\t    {\n+\t      _Guard(void* __p) : _M_f((FILE*)__p) { }\n+\t      ~_Guard() { std::fclose(_M_f); }\n+\t      _Guard(_Guard&&) = delete;\n+\t      _Guard& operator=(_Guard&&) = delete;\n+\t      FILE* _M_f;\n+\t    };\n+\t    _Guard __g(__term);\n+#endif\n+\n+\t    ios_base::iostate __err = ios_base::goodbit;\n+\t    __try\n+\t      {\n+\t\tif (__os.rdbuf()->pubsync() == -1)\n+\t\t  __err = ios::badbit;\n+\t\telse if (auto __e = __write_to_terminal(__term, __out))\n+\t\t  if (__e != std::make_error_code(errc::illegal_byte_sequence))\n+\t\t    __err = ios::badbit;\n+\t      }\n+\t    __catch(const __cxxabiv1::__forced_unwind&)\n+\t      {\n+\t\t__os._M_setstate(ios_base::badbit);\n+\t\t__throw_exception_again;\n+\t      }\n+\t    __catch(...)\n+\t      { __os._M_setstate(ios_base::badbit); }\n+\n+\t    if (__err)\n+\t      __os.setstate(__err);\n+\t    return;\n+\t  }\n+\n+\t// Otherwise just insert the string as vprint_nonunicode does.\n+\t__try\n+\t  {\n+\t    std::__ostream_write(__os, __out.data(), __out.size());\n+\t  }\n+\t__catch(const __cxxabiv1::__forced_unwind&)\n+\t  {\n+\t    __os._M_setstate(ios_base::badbit);\n+\t    __throw_exception_again;\n+\t  }\n+\t__catch(...)\n+\t  { __os._M_setstate(ios_base::badbit); }\n+      }\n+#endif // _WIN32\n+  }\n+#undef _GLIBCXX_PRINT_INLINE_USED\n+\n+_GLIBCXX_END_NAMESPACE_VERSION\n+} // namespace std\n+#endif // __glibcxx_print\n+#endif // _GLIBCXX_OSTREAM_PRINT_H\ndiff --git a/libstdc++-v3/include/bits/print.h b/libstdc++-v3/include/bits/print.h\nnew file mode 100644\nindex 000000000000..67a5a1729135\n--- /dev/null\n+++ b/libstdc++-v3/include/bits/print.h\n@@ -0,0 +1,339 @@\n+// Inline implementation details for std::print functions -*- C++ -*-\n+\n+// Copyright The GNU Toolchain Authors.\n+//\n+// This file is part of the GNU ISO C++ Library.  This library is free\n+// software; you can redistribute it and/or modify it under the\n+// terms of the GNU General Public License as published by the\n+// Free Software Foundation; either version 3, or (at your option)\n+// any later version.\n+\n+// This library is distributed in the hope that it will be useful,\n+// but WITHOUT ANY WARRANTY; without even the implied warranty of\n+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+// GNU General Public License for more details.\n+\n+// Under Section 7 of GPL version 3, you are granted additional\n+// permissions described in the GCC Runtime Library Exception, version\n+// 3.1, as published by the Free Software Foundation.\n+\n+// You should have received a copy of the GNU General Public License and\n+// a copy of the GCC Runtime Library Exception along with this program;\n+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see\n+// <http://www.gnu.org/licenses/>.\n+\n+/** @file include/bits/print.h\n+ *  This is an internal header file, included by other library headers.\n+ *  Do not attempt to use it directly. @headername{print}\n+ *\n+ *  This file contains the parts of `<print>` which are currently defined\n+ *  inline, but should be moved into the library eventually.\n+ */\n+\n+#ifndef _GLIBCXX_PRINT_H\n+#define _GLIBCXX_PRINT_H 1\n+\n+#ifdef _GLIBCXX_SYSHDR\n+#pragma GCC system_header\n+#endif\n+\n+#include <bits/requires_hosted.h> // for std::format\n+\n+#include <bits/version.h>\n+\n+#ifdef __glibcxx_print // C++ >= 23\n+\n+#include <format>\n+#include <cstdio>             // FILE, EOF, flockfile, etc.\n+#include <cerrno>             // EACCES, EIO\n+#include <bits/functexcept.h> // __throw_system_error\n+\n+#ifdef _WIN32\n+# include <system_error> // system_error\n+#endif\n+\n+namespace std _GLIBCXX_VISIBILITY(default)\n+{\n+_GLIBCXX_BEGIN_NAMESPACE_VERSION\n+\n+namespace __format\n+{\n+#if _GLIBCXX_USE_STDIO_LOCKING && _GLIBCXX_USE_GLIBC_STDIO_EXT\n+  // These are defined in <stdio_ext.h> but we don't want to include that.\n+  extern \"C\" int __fwritable(FILE*) noexcept;\n+  extern \"C\" int __flbf(FILE*) noexcept;\n+  extern \"C\" size_t __fbufsize(FILE*) noexcept;\n+\n+  // A format sink that writes directly to a Glibc FILE.\n+  // The file is locked on construction and its buffer is accessed directly.\n+  class _File_sink final : _Buf_sink<char>\n+  {\n+    struct _File\n+    {\n+      explicit\n+      _File(FILE* __f) : _M_file(__f)\n+      {\n+\t::flockfile(__f);\n+\t// Ensure stream is in write mode\n+\tif (!__fwritable(__f))\n+\t  {\n+\t    ::funlockfile(__f);\n+\t    __throw_system_error(EACCES);\n+\t  }\n+\t// Allocate buffer if needed:\n+\tif (_M_write_buf().empty())\n+\t  if (::__overflow(__f, EOF) == EOF)\n+\t    {\n+\t      const int __err = errno;\n+\t      ::funlockfile(__f);\n+\t      __throw_system_error(__err);\n+\t    }\n+      }\n+\n+      ~_File() { ::funlockfile(_M_file); }\n+\n+      _File(_File&&) = delete;\n+\n+      // A span viewing the unused portion of the stream's output buffer.\n+      std::span<char>\n+      _M_write_buf() noexcept\n+      {\n+\treturn {_M_file->_IO_write_ptr,\n+\t\tsize_t(_M_file->_IO_buf_end - _M_file->_IO_write_ptr)};\n+      }\n+\n+      // Flush the output buffer to the file so we can write to it again.\n+      void\n+      _M_flush()\n+      {\n+\tif (::fflush_unlocked(_M_file))\n+\t  __throw_system_error(errno);\n+      }\n+\n+      // Update the current position in the output buffer.\n+      void\n+      _M_bump(size_t __n) noexcept\n+      { _M_file->_IO_write_ptr += __n; }\n+\n+      bool\n+      _M_line_buffered() const noexcept\n+      { return __flbf(_M_file); } // Or: _M_file->_flags & 0x200\n+\n+      bool\n+      _M_unbuffered() const noexcept\n+      { return __fbufsize(_M_file) == 1; } // Or: _M_file->_flags & 0x2\n+\n+      FILE* _M_file;\n+    } _M_file;\n+\n+    bool _M_add_newline; // True for std::println, false for std::print.\n+\n+    // Flush the stream's put area so it can be refilled.\n+    void\n+    _M_overflow() override\n+    {\n+      auto __s = this->_M_used();\n+      if (__s.data() == this->_M_buf)\n+\t{\n+\t  // Characters in internal buffer need to be transferred to the FILE.\n+\t  auto __n = ::fwrite_unlocked(__s.data(), 1, __s.size(),\n+\t\t\t\t       _M_file._M_file);\n+\t  if (__n != __s.size())\n+\t    __throw_system_error(errno);\n+\t  this->_M_reset(this->_M_buf);\n+\t}\n+      else\n+\t{\n+\t  // Characters were written directly to the FILE's output buffer.\n+\t  _M_file._M_bump(__s.size());\n+\t  _M_file._M_flush();\n+\t  this->_M_reset(_M_file._M_write_buf());\n+\t}\n+    }\n+\n+  public:\n+    _File_sink(FILE* __f, bool __add_newline)\n+    : _M_file(__f), _M_add_newline(__add_newline)\n+    {\n+      if (!_M_file._M_unbuffered())\n+\t// Write directly to the FILE's output buffer.\n+\tthis->_M_reset(_M_file._M_write_buf());\n+    }\n+\n+    ~_File_sink() noexcept(false)\n+    {\n+      auto __s = this->_M_used();\n+      if (__s.data() == this->_M_buf) // Unbuffered stream\n+\t{\n+\t  _File_sink::_M_overflow();\n+\t  if (_M_add_newline)\n+\t    ::putc_unlocked('\\n', _M_file._M_file);\n+\t}\n+      else\n+\t{\n+\t  _M_file._M_bump(__s.size());\n+\t  if (_M_add_newline)\n+\t    ::putc_unlocked('\\n', _M_file._M_file);\n+\t  else if (_M_file._M_line_buffered() && __s.size()\n+\t\t     && (__s.back() == '\\n'\n+\t\t\t   || __builtin_memchr(__s.data(), '\\n', __s.size())))\n+\t    _M_file._M_flush();\n+\t}\n+    }\n+\n+    using _Sink<char>::out;\n+  };\n+#elif _GLIBCXX_USE_STDIO_LOCKING\n+  // A format sink that buffers output and then copies it to a stdio FILE.\n+  // The file is locked on construction and written to using fwrite_unlocked.\n+  class _File_sink final : _Buf_sink<char>\n+  {\n+    FILE* _M_file;\n+    bool _M_add_newline;\n+\n+    // Transfer buffer contents to the FILE, so buffer can be refilled.\n+    void\n+    _M_overflow() override\n+    {\n+      auto __s = this->_M_used();\n+#if _GLIBCXX_HAVE_FWRITE_UNLOCKED\n+      auto __n = ::fwrite_unlocked(__s.data(), 1, __s.size(), _M_file);\n+      if (__n != __s.size())\n+\t__throw_system_error(errno);\n+#else\n+      for (char __c : __s)\n+\t::putc_unlocked(__c, _M_file);\n+      if (::ferror(_M_file))\n+\t__throw_system_error(errno);\n+#endif\n+      this->_M_reset(this->_M_buf);\n+    }\n+\n+  public:\n+    _File_sink(FILE* __f, bool __add_newline) noexcept\n+    : _Buf_sink<char>(), _M_file(__f), _M_add_newline(__add_newline)\n+    { ::flockfile(__f); }\n+\n+    ~_File_sink() noexcept(false)\n+    {\n+      _File_sink::_M_overflow();\n+      if (_M_add_newline)\n+\t::putc_unlocked('\\n', _M_file);\n+      ::funlockfile(_M_file);\n+    }\n+\n+    using _Sink<char>::out;\n+  };\n+#else\n+  // A wrapper around a format sink that copies the output to a stdio FILE.\n+  // This is not actually a _Sink itself, but it creates one to hold the\n+  // formatted characters and then copies them to the file when finished.\n+  class _File_sink final\n+  {\n+    FILE* _M_file;\n+    _Str_sink<char> _M_sink;\n+    bool _M_add_newline;\n+\n+  public:\n+    _File_sink(FILE* __f, bool __add_newline) noexcept\n+    : _M_file(__f), _M_add_newline(__add_newline)\n+    { }\n+\n+    ~_File_sink() noexcept(false)\n+    {\n+      string __s = std::move(_M_sink).get();\n+      if (_M_add_newline)\n+\t__s += '\\n';\n+      auto __n = std::fwrite(__s.data(), 1, __s.size(), _M_file);\n+      if (__n < __s.size())\n+\t__throw_system_error(EIO);\n+    }\n+\n+    auto out() { return _M_sink.out(); }\n+  };\n+#endif\n+} // namespace __format\n+\n+#ifdef _GLIBCXX_NO_INLINE_PRINT\n+# define _GLIBCXX_PRINT_INLINE_USED [[__gnu__::__used__]]\n+#else\n+# define _GLIBCXX_PRINT_INLINE_USED\n+#endif\n+\n+  _GLIBCXX_PRINT_INLINE_USED\n+  inline void\n+  vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args)\n+  {\n+    std::vformat_to(__format::_File_sink(__stream, false).out(), __fmt, __args);\n+  }\n+\n+  _GLIBCXX_PRINT_INLINE_USED\n+  inline void\n+  vprint_nonunicode_buffered(FILE* __stream, string_view __fmt,\n+\t\t\t     format_args __args)\n+  {\n+    __format::_Str_sink<char> __buf;\n+    std::vformat_to(__buf.out(), __fmt, __args);\n+    auto __out = __buf.view();\n+    if (std::fwrite(__out.data(), 1, __out.size(), __stream) != __out.size())\n+      __throw_system_error(EIO);\n+  }\n+\n+  _GLIBCXX_PRINT_INLINE_USED\n+  inline void\n+  vprint_unicode(FILE* __stream, string_view __fmt, format_args __args)\n+  {\n+#if !defined(_WIN32) || defined(__CYGWIN__)\n+    // For most targets we don't need to do anything special to write\n+    // Unicode to a terminal.\n+    std::vprint_nonunicode(__stream, __fmt, __args);\n+#else\n+    __format::_Str_sink<char> __buf;\n+    std::vformat_to(__buf.out(), __fmt, __args);\n+    auto __out = __buf._M_span();\n+\n+    void* __open_terminal(FILE*);\n+    error_code __write_to_terminal(void*, span<char>);\n+    // If stream refers to a terminal, write a native Unicode string to it.\n+    if (auto __term = __open_terminal(__stream))\n+      {\n+\terror_code __e;\n+\tif (!std::fflush(__stream))\n+\t  {\n+\t    __e = __write_to_terminal(__term, __out);\n+\t    if (!__e)\n+\t      return;\n+\t    if (__e == std::make_error_code(errc::illegal_byte_sequence))\n+\t      return;\n+\t  }\n+\telse\n+\t  __e = error_code(errno, generic_category());\n+\t_GLIBCXX_THROW_OR_ABORT(system_error(__e, \"std::vprint_unicode\"));\n+      }\n+\n+    // Otherwise just write the string to the file.\n+    if (std::fwrite(__out.data(), 1, __out.size(), __stream) != __out.size())\n+      __throw_system_error(EIO);\n+#endif\n+  }\n+\n+  _GLIBCXX_PRINT_INLINE_USED\n+  inline void\n+  vprint_unicode_buffered(FILE* __stream, string_view __fmt, format_args __args)\n+  {\n+#if !defined(_WIN32) || defined(__CYGWIN__)\n+    // For most targets we don't need to do anything special to write\n+    // Unicode to a terminal. Just use the nonunicode function.\n+    std::vprint_nonunicode_buffered(__stream, __fmt, __args);\n+#else\n+    // For Windows the locking function formats everything first anyway,\n+    // so no formatting happens while a lock is taken. Just use that.\n+    std::vprint_unicode(__stream, __fmt, __args);\n+#endif\n+  }\n+#undef _GLIBCXX_PRINT_INLINE_USED\n+\n+_GLIBCXX_END_NAMESPACE_VERSION\n+} // namespace std\n+#endif // __glibcxx_print\n+#endif // _GLIBCXX_PRINT_H\ndiff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream\nindex e8dcfda2682f..b99c0f92d345 100644\n--- a/libstdc++-v3/include/std/ostream\n+++ b/libstdc++-v3/include/std/ostream\n@@ -40,12 +40,17 @@\n #include <bits/requires_hosted.h> // iostreams\n \n #include <bits/ostream.h>\n-#if __cplusplus > 202002L\n-# include <format>\n+\n+#ifdef __glibcxx_print\n+# include <format> // format_string, make_format_args\n+#endif\n+\n+#ifndef _GLIBCXX_NO_INLINE_PRINT\n+# include <bits/ostream_print.h>\n #endif\n \n # define __glibcxx_want_print\n-#include <bits/version.h> // __glibcxx_syncbuf\n+#include <bits/version.h> // __cpp_lib_print, __glibcxx_syncbuf\n \n namespace std _GLIBCXX_VISIBILITY(default)\n {\n@@ -156,103 +161,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n #endif // __glibcxx_syncbuf\n \n #if __cpp_lib_print // C++ >= 23\n-  inline void\n-  vprint_nonunicode(ostream& __os, string_view __fmt, format_args __args)\n-  {\n-    ostream::sentry __cerb(__os);\n-    if (__cerb)\n-      {\n-\t__format::_Str_sink<char> __buf;\n-\tstd::vformat_to(__buf.out(), __os.getloc(), __fmt, __args);\n-\tauto __out = __buf.view();\n+  void\n+  vprint_nonunicode(ostream& __os, string_view __fmt, format_args __args);\n \n-\t__try\n-\t  {\n-\t    std::__ostream_write(__os, __out.data(), __out.size());\n-\t  }\n-\t__catch(const __cxxabiv1::__forced_unwind&)\n-\t  {\n-\t    __os._M_setstate(ios_base::badbit);\n-\t    __throw_exception_again;\n-\t  }\n-\t__catch(...)\n-\t  { __os._M_setstate(ios_base::badbit); }\n-      }\n-  }\n-\n-  inline void\n-  vprint_unicode(ostream& __os, string_view __fmt, format_args __args)\n-  {\n-#if !defined(_WIN32) || defined(__CYGWIN__)\n-    // For most targets we don't need to do anything special to write\n-    // Unicode to a terminal.\n-    std::vprint_nonunicode(__os, __fmt, __args);\n-#else\n-    ostream::sentry __cerb(__os);\n-    if (__cerb)\n-      {\n-\t__format::_Str_sink<char> __buf;\n-\tstd::vformat_to(__buf.out(), __os.getloc(), __fmt, __args);\n-\tauto __out = __buf._M_span();\n-\n-\tvoid* __open_terminal(streambuf*);\n-\terror_code __write_to_terminal(void*, span<char>);\n-\t// If stream refers to a terminal, write a Unicode string to it.\n-\tif (auto __term = __open_terminal(__os.rdbuf()))\n-\t  {\n-#if !defined(_WIN32) || defined(__CYGWIN__)\n-\t    // For POSIX, __open_terminal(streambuf*) uses fdopen to open a\n-\t    // new file, so we would need to close it here. This code is not\n-\t    // actually compiled because it's inside an #ifdef _WIN32 group,\n-\t    // but just in case that changes in future ...\n-\t    struct _Guard\n-\t    {\n-\t      _Guard(void* __p) : _M_f((FILE*)__p) { }\n-\t      ~_Guard() { std::fclose(_M_f); }\n-\t      _Guard(_Guard&&) = delete;\n-\t      _Guard& operator=(_Guard&&) = delete;\n-\t      FILE* _M_f;\n-\t    };\n-\t    _Guard __g(__term);\n-#endif\n-\n-\t    ios_base::iostate __err = ios_base::goodbit;\n-\t    __try\n-\t      {\n-\t\tif (__os.rdbuf()->pubsync() == -1)\n-\t\t  __err = ios::badbit;\n-\t\telse if (auto __e = __write_to_terminal(__term, __out))\n-\t\t  if (__e != std::make_error_code(errc::illegal_byte_sequence))\n-\t\t    __err = ios::badbit;\n-\t      }\n-\t    __catch(const __cxxabiv1::__forced_unwind&)\n-\t      {\n-\t\t__os._M_setstate(ios_base::badbit);\n-\t\t__throw_exception_again;\n-\t      }\n-\t    __catch(...)\n-\t      { __os._M_setstate(ios_base::badbit); }\n-\n-\t    if (__err)\n-\t      __os.setstate(__err);\n-\t    return;\n-\t  }\n-\n-\t// Otherwise just insert the string as vprint_nonunicode does.\n-\t__try\n-\t  {\n-\t    std::__ostream_write(__os, __out.data(), __out.size());\n-\t  }\n-\t__catch(const __cxxabiv1::__forced_unwind&)\n-\t  {\n-\t    __os._M_setstate(ios_base::badbit);\n-\t    __throw_exception_again;\n-\t  }\n-\t__catch(...)\n-\t  { __os._M_setstate(ios_base::badbit); }\n-      }\n-#endif // _WIN32\n-  }\n+  void\n+  vprint_unicode(ostream& __os, string_view __fmt, format_args __args);\n \n   template<typename... _Args>\n     inline void\n@@ -294,7 +207,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n #endif\n       __os.put('\\n');\n   }\n-\n #endif // __cpp_lib_print\n \n _GLIBCXX_END_NAMESPACE_VERSION\ndiff --git a/libstdc++-v3/include/std/print b/libstdc++-v3/include/std/print\nindex 1b9e810419f0..459bb9fb7462 100644\n--- a/libstdc++-v3/include/std/print\n+++ b/libstdc++-v3/include/std/print\n@@ -40,284 +40,42 @@\n \n #ifdef __cpp_lib_print // C++ >= 23\n \n-#include <format>\n-#include <cstdio>\n-#include <cerrno>\n-#include <bits/functexcept.h>\n+#include <format>             // format_args (TODO: move to bits/formatfwd.h?)\n+#include <cstdio>             // FILE, EOF, putc\n+#include <cerrno>             // EACCES, EIO\n+#include <bits/functexcept.h> // __throw_system_error\n \n #ifdef _WIN32\n # include <system_error>\n #endif\n \n+#ifndef _GLIBCXX_NO_INLINE_PRINT\n+# include <bits/print.h>\n+#endif\n+\n namespace std _GLIBCXX_VISIBILITY(default)\n {\n _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \n-namespace __format\n-{\n-#if _GLIBCXX_USE_STDIO_LOCKING && _GLIBCXX_USE_GLIBC_STDIO_EXT\n-  // These are defined in <stdio_ext.h> but we don't want to include that.\n-  extern \"C\" int __fwritable(FILE*) noexcept;\n-  extern \"C\" int __flbf(FILE*) noexcept;\n-  extern \"C\" size_t __fbufsize(FILE*) noexcept;\n+  void\n+  vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args);\n \n-  // A format sink that writes directly to a Glibc FILE.\n-  // The file is locked on construction and its buffer is accessed directly.\n-  class _File_sink final : _Buf_sink<char>\n-  {\n-    struct _File\n-    {\n-      explicit\n-      _File(FILE* __f) : _M_file(__f)\n-      {\n-\t::flockfile(__f);\n-\t// Ensure stream is in write mode\n-        if (!__fwritable(__f))\n-\t  {\n-\t    ::funlockfile(__f);\n-\t    __throw_system_error(EACCES);\n-\t  }\n-\t// Allocate buffer if needed:\n-        if (_M_write_buf().empty())\n-\t  if (::__overflow(__f, EOF) == EOF)\n-\t    {\n-\t      const int __err = errno;\n-\t      ::funlockfile(__f);\n-\t      __throw_system_error(__err);\n-\t    }\n-      }\n-\n-      ~_File() { ::funlockfile(_M_file); }\n-\n-      _File(_File&&) = delete;\n-\n-      // A span viewing the unused portion of the stream's output buffer.\n-      std::span<char>\n-      _M_write_buf() noexcept\n-      {\n-\treturn {_M_file->_IO_write_ptr,\n-\t\tsize_t(_M_file->_IO_buf_end - _M_file->_IO_write_ptr)};\n-      }\n-\n-      // Flush the output buffer to the file so we can write to it again.\n-      void\n-      _M_flush()\n-      {\n-\tif (::fflush_unlocked(_M_file))\n-\t  __throw_system_error(errno);\n-      }\n-\n-      // Update the current position in the output buffer.\n-      void\n-      _M_bump(size_t __n) noexcept\n-      { _M_file->_IO_write_ptr += __n; }\n-\n-      bool\n-      _M_line_buffered() const noexcept\n-      { return __flbf(_M_file); } // Or: _M_file->_flags & 0x200\n-\n-      bool\n-      _M_unbuffered() const noexcept\n-      { return __fbufsize(_M_file) == 1; } // Or: _M_file->_flags & 0x2\n-\n-      FILE* _M_file;\n-    } _M_file;\n-\n-    bool _M_add_newline; // True for std::println, false for std::print.\n-\n-    // Flush the stream's put area so it can be refilled.\n-    void\n-    _M_overflow() override\n-    {\n-      auto __s = this->_M_used();\n-      if (__s.data() == this->_M_buf)\n-\t{\n-\t  // Characters in internal buffer need to be transferred to the FILE.\n-\t  auto __n = ::fwrite_unlocked(__s.data(), 1, __s.size(),\n-\t\t\t\t       _M_file._M_file);\n-\t  if (__n != __s.size())\n-\t    __throw_system_error(errno);\n-\t  this->_M_reset(this->_M_buf);\n-\t}\n-      else\n-\t{\n-\t  // Characters were written directly to the FILE's output buffer.\n-\t  _M_file._M_bump(__s.size());\n-\t  _M_file._M_flush();\n-\t  this->_M_reset(_M_file._M_write_buf());\n-\t}\n-    }\n-\n-  public:\n-    _File_sink(FILE* __f, bool __add_newline)\n-    : _M_file(__f), _M_add_newline(__add_newline)\n-    {\n-      if (!_M_file._M_unbuffered())\n-\t// Write directly to the FILE's output buffer.\n-\tthis->_M_reset(_M_file._M_write_buf());\n-    }\n-\n-    ~_File_sink() noexcept(false)\n-    {\n-      auto __s = this->_M_used();\n-      if (__s.data() == this->_M_buf) // Unbuffered stream\n-\t{\n-\t  _File_sink::_M_overflow();\n-\t  if (_M_add_newline)\n-\t    ::putc_unlocked('\\n', _M_file._M_file);\n-\t}\n-      else\n-\t{\n-\t  _M_file._M_bump(__s.size());\n-\t  if (_M_add_newline)\n-\t    ::putc_unlocked('\\n', _M_file._M_file);\n-\t  else if (_M_file._M_line_buffered() && __s.size()\n-\t\t     && (__s.back() == '\\n'\n-\t\t\t   || __builtin_memchr(__s.data(), '\\n', __s.size())))\n-\t    _M_file._M_flush();\n-\t}\n-    }\n-\n-    using _Sink<char>::out;\n-  };\n-#elif _GLIBCXX_USE_STDIO_LOCKING\n-  // A format sink that buffers output and then copies it to a stdio FILE.\n-  // The file is locked on construction and written to using fwrite_unlocked.\n-  class _File_sink final : _Buf_sink<char>\n-  {\n-    FILE* _M_file;\n-    bool _M_add_newline;\n-\n-    // Transfer buffer contents to the FILE, so buffer can be refilled.\n-    void\n-    _M_overflow() override\n-    {\n-      auto __s = this->_M_used();\n-#if _GLIBCXX_HAVE_FWRITE_UNLOCKED\n-      auto __n = ::fwrite_unlocked(__s.data(), 1, __s.size(), _M_file);\n-      if (__n != __s.size())\n-\t__throw_system_error(errno);\n-#else\n-      for (char __c : __s)\n-\t::putc_unlocked(__c, _M_file);\n-      if (::ferror(_M_file))\n-\t__throw_system_error(errno);\n-#endif\n-      this->_M_reset(this->_M_buf);\n-    }\n-\n-  public:\n-    _File_sink(FILE* __f, bool __add_newline) noexcept\n-    : _Buf_sink<char>(), _M_file(__f), _M_add_newline(__add_newline)\n-    { ::flockfile(__f); }\n-\n-    ~_File_sink() noexcept(false)\n-    {\n-      _File_sink::_M_overflow();\n-      if (_M_add_newline)\n-\t::putc_unlocked('\\n', _M_file);\n-      ::funlockfile(_M_file);\n-    }\n-\n-    using _Sink<char>::out;\n-  };\n-#else\n-  // A wrapper around a format sink that copies the output to a stdio FILE.\n-  // This is not actually a _Sink itself, but it creates one to hold the\n-  // formatted characters and then copies them to the file when finished.\n-  class _File_sink final\n-  {\n-    FILE* _M_file;\n-    _Str_sink<char> _M_sink;\n-    bool _M_add_newline;\n-\n-  public:\n-    _File_sink(FILE* __f, bool __add_newline) noexcept\n-    : _M_file(__f), _M_add_newline(__add_newline)\n-    { }\n-\n-    ~_File_sink() noexcept(false)\n-    {\n-      string __s = std::move(_M_sink).get();\n-      if (_M_add_newline)\n-\t__s += '\\n';\n-      auto __n = std::fwrite(__s.data(), 1, __s.size(), _M_file);\n-      if (__n < __s.size())\n-\t__throw_system_error(EIO);\n-    }\n-\n-    auto out() { return _M_sink.out(); }\n-  };\n-#endif\n-} // namespace __format\n-\n-  inline void\n-  vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args)\n-  {\n-    std::vformat_to(__format::_File_sink(__stream, false).out(), __fmt, __args);\n-  }\n-\n-  inline void\n+  void\n   vprint_nonunicode_buffered(FILE* __stream, string_view __fmt,\n-\t\t\t     format_args __args)\n-  {\n-    __format::_Str_sink<char> __buf;\n-    std::vformat_to(__buf.out(), __fmt, __args);\n-    auto __out = __buf.view();\n-    if (std::fwrite(__out.data(), 1, __out.size(), __stream) != __out.size())\n-      __throw_system_error(EIO);\n-  }\n+\t\t\t     format_args __args);\n \n-  inline void\n-  vprint_unicode(FILE* __stream, string_view __fmt, format_args __args)\n-  {\n-#if !defined(_WIN32) || defined(__CYGWIN__)\n-    // For most targets we don't need to do anything special to write\n-    // Unicode to a terminal.\n-    std::vprint_nonunicode(__stream, __fmt, __args);\n-#else\n-    __format::_Str_sink<char> __buf;\n-    std::vformat_to(__buf.out(), __fmt, __args);\n-    auto __out = __buf._M_span();\n+  void\n+  vprint_unicode(FILE* __stream, string_view __fmt, format_args __args);\n \n-    void* __open_terminal(FILE*);\n-    error_code __write_to_terminal(void*, span<char>);\n-    // If stream refers to a terminal, write a native Unicode string to it.\n-    if (auto __term = __open_terminal(__stream))\n-      {\n-\terror_code __e;\n-\tif (!std::fflush(__stream))\n-\t  {\n-\t    __e = __write_to_terminal(__term, __out);\n-\t    if (!__e)\n-\t      return;\n-\t    if (__e == std::make_error_code(errc::illegal_byte_sequence))\n-\t      return;\n-\t  }\n-\telse\n-\t  __e = error_code(errno, generic_category());\n-\t_GLIBCXX_THROW_OR_ABORT(system_error(__e, \"std::vprint_unicode\"));\n-      }\n+  void\n+  vprint_unicode_buffered(FILE* __stream, string_view __fmt,\n+\t\t\t  format_args __args);\n \n-    // Otherwise just write the string to the file.\n-    if (std::fwrite(__out.data(), 1, __out.size(), __stream) != __out.size())\n-      __throw_system_error(EIO);\n-#endif\n-  }\n+  void\n+  vprint_unicode_buffered(string_view __fmt, format_args __args);\n \n-  inline void\n-  vprint_unicode_buffered(FILE* __stream, string_view __fmt, format_args __args)\n-  {\n-#if !defined(_WIN32) || defined(__CYGWIN__)\n-    // For most targets we don't need to do anything special to write\n-    // Unicode to a terminal. Just use the nonunicode function.\n-    std::vprint_nonunicode_buffered(__stream, __fmt, __args);\n-#else\n-    // For Windows the locking function formats everything first anyway,\n-    // so no formatting happens while a lock is taken. Just use that.\n-    std::vprint_unicode(__stream, __fmt, __args);\n-#endif\n-  }\n+  void\n+  vprint_nonunicode_buffered(string_view __fmt, format_args __args);\n \n   template<typename... _Args>\n     inline void\n@@ -357,6 +115,7 @@ namespace __format\n       // and we know what that would call, so we can call that directly.\n \n       auto __fmtargs = std::make_format_args(__args...);\n+\n #if defined(_WIN32) && !defined(__CYGWIN__)\n       if constexpr (__unicode::__literal_encoding_is_utf8())\n \t{\n@@ -371,6 +130,15 @@ namespace __format\n       else\n #endif\n \n+#ifdef _GLIBCXX_NO_INLINE_PRINT\n+\t{\n+\t  string __fmtn;\n+\t  __fmtn.reserve(__fmt.get().size() + 1);\n+\t  __fmtn = __fmt.get();\n+\t  __fmtn += '\\n';\n+\t  std::vprint_nonunicode(__stream, __fmtn, __fmtargs);\n+\t}\n+#else\n       // For non-Windows and for non-Unicode on Windows, we know that print\n       // would call vprint_nonunicode or vprint_nonunicode_buffered with a\n       // newline appended to the format-string. Use a _File_sink that adds\n@@ -387,6 +155,7 @@ namespace __format\n \t  string_view __s(__buf.view());\n \t  __format::_File_sink(__stream, true).out() = __s;\n \t}\n+#endif\n     }\n \n   template<typename... _Args>\ndiff --git a/libstdc++-v3/src/c++23/print.cc b/libstdc++-v3/src/c++23/print.cc\nindex f34369950096..290e0b8dfa2d 100644\n--- a/libstdc++-v3/src/c++23/print.cc\n+++ b/libstdc++-v3/src/c++23/print.cc\n@@ -22,6 +22,13 @@\n // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see\n // <http://www.gnu.org/licenses/>.\n \n+// We want to emit symbols for the inline functions in bits/print.h here.\n+#define _GLIBCXX_NO_INLINE_PRINT 1\n+#include <ostream>\n+#include <bits/ostream_print.h>\n+#include <print>\n+#include <bits/print.h>\n+\n #include <span>\n #include <string>\n #include <streambuf>\n",
    "prefixes": [
        "committed",
        "v2"
    ]
}