From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id AD6263858D39 for ; Wed, 17 Apr 2024 16:41:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AD6263858D39 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org AD6263858D39 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1713372117; cv=none; b=l+SVWtn8Ez5wPgEE0VFC5kVxY76F0I7iDFL6yTgmXWQzSLvky6gYGi3gcFx9kA2tDWG5H1hg/E9knRzDIhdIVyjSe2tGhMxjFW7KzM3/MUOVZwXOf24iX0ytK5XmyBu/skiYFpixE24k4nbUC/u4vLtfdE7fUPv9/7Lj9JOW/gg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1713372117; c=relaxed/simple; bh=vpbWRF7uesx5wdaU6PZa0zHz1SMCSB+sCDWec6Maw/o=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=e4+pPlRAD7jSxikbMo4RS2xTs1u918ldrRkUbwddLLKWjlFS+5HRf/5B/QbTn6falP4CjATIoVGYw288PAAsCzsKzCo/OJ1s6CK+/1e80fa43ffW0xX6F07yzu3lj3NmFGrLEjtcrIkDVJGvub3vCkXDjoMlI/OCQxi2WTkbW0w= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1713372115; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=pZu55Nhk9HpC25bmSalaTeEX7FSARl6oB6zOQGvLPaU=; b=KUPVA1AL6cvHoYdwrr7qls+yeeVpZeX4wdaNVQAwNMaxzoVllKraZPpPshWjPRSBCMZqJx J7yIHy3xtTy2HlX52pVFP0SGKET0ABm2KtwEFbh7JHpfsU9/2gc4MX+5m/5FiaGhxoKYS5 oOYFMaJk5l+5IYw0ZdFuNC0mBG1Xrms= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-615-CZngnrNcOS-XVT4wpps15g-1; Wed, 17 Apr 2024 12:41:53 -0400 X-MC-Unique: CZngnrNcOS-XVT4wpps15g-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 53C401044572; Wed, 17 Apr 2024 16:41:53 +0000 (UTC) Received: from localhost (unknown [10.42.28.61]) by smtp.corp.redhat.com (Postfix) with ESMTP id 22C3F1C0654B; Wed, 17 Apr 2024 16:41:53 +0000 (UTC) From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Implement "Printing blank lines with println" for C++23 Date: Wed, 17 Apr 2024 17:40:51 +0100 Message-ID: <20240417164148.1062828-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_NUMSUBJECT,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Tested x86_64-linux and x86_64-freebsd. Pushed to trunk. -- >8 -- This was recently approved for C++26 at the Tokyo meeting. As suggested by Stephan T. Lavavej, I'm defining it as an extension for C++23 mode (when std::print and std::prinln were first added) rather than as a new C++26 feature. Both MSVC and libc++ have agreed to do this too. libstdc++-v3/ChangeLog: * include/std/ostream (println(ostream&)): Define new overload. * include/std/print (println(FILE*), println()): Likewise. * testsuite/27_io/basic_ostream/print/2.cc: New test. * testsuite/27_io/print/1.cc: Remove unused header. * testsuite/27_io/print/3.cc: New test. --- libstdc++-v3/include/std/ostream | 12 +++++ libstdc++-v3/include/std/print | 14 +++++ .../testsuite/27_io/basic_ostream/print/2.cc | 47 ++++++++++++++++ libstdc++-v3/testsuite/27_io/print/1.cc | 1 - libstdc++-v3/testsuite/27_io/print/3.cc | 53 +++++++++++++++++++ 5 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 libstdc++-v3/testsuite/27_io/basic_ostream/print/2.cc create mode 100644 libstdc++-v3/testsuite/27_io/print/3.cc diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream index a136399ad0b..8a21758d0a3 100644 --- a/libstdc++-v3/include/std/ostream +++ b/libstdc++-v3/include/std/ostream @@ -995,6 +995,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::print(__os, "{}\n", std::format(__fmt, std::forward<_Args>(__args)...)); } + + // Defined for C++26, supported as an extension to C++23. + inline void println(ostream& __os) + { +#if defined(_WIN32) && !defined(__CYGWIN__) + if constexpr (__unicode::__literal_encoding_is_utf8()) + std::vprint_unicode(__os, "\n", std::make_format_args()); + else +#endif + __os.put('\n'); + } + #endif // __cpp_lib_print #endif // C++11 diff --git a/libstdc++-v3/include/std/print b/libstdc++-v3/include/std/print index d44033469de..0c259d04de3 100644 --- a/libstdc++-v3/include/std/print +++ b/libstdc++-v3/include/std/print @@ -136,6 +136,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION vprint_nonunicode(string_view __fmt, format_args __args) { std::vprint_nonunicode(stdout, __fmt, __args); } + // Defined for C++26, supported as an extension to C++23. + inline void println(FILE* __stream) + { +#if defined(_WIN32) && !defined(__CYGWIN__) + if constexpr (__unicode::__literal_encoding_is_utf8()) + std::vprint_unicode(__stream, "\n", std::make_format_args()); + else +#endif + if (std::putc('\n', __stream) == EOF) + __throw_system_error(EIO); + } + + inline void println() { std::println(stdout); } + _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // __cpp_lib_print diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/print/2.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/print/2.cc new file mode 100644 index 00000000000..5d1e3efdbf7 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/print/2.cc @@ -0,0 +1,47 @@ +// { dg-additional-options "-lstdc++exp" { target { *-*-mingw* } } } +// { dg-do run { target c++23 } } +// { dg-require-fileio "" } + +#include +#include +#include +#include +#include +#include + +void +test_println_blank_ostream() +{ + char buf[4]; + std::spanstream os(buf); + std::println(os); + std::string_view txt(os.span()); + VERIFY( txt == "\n" ); +} + +void +test_errors() +{ + // Failure to generate output is reported by setting badbit. + std::stringstream in(std::ios::in); + std::println(in); // No exception here. + VERIFY(in.bad()); +#ifdef __cpp_exceptions + in.clear(); + in.exceptions(std::ios::badbit); + try + { + std::println(in); // Should throw now. + VERIFY(false); + } + catch (const std::ios::failure&) + { + } +#endif +} + +int main() +{ + test_println_blank_ostream(); + test_errors(); +} diff --git a/libstdc++-v3/testsuite/27_io/print/1.cc b/libstdc++-v3/testsuite/27_io/print/1.cc index d570f7938be..f6585d9880a 100644 --- a/libstdc++-v3/testsuite/27_io/print/1.cc +++ b/libstdc++-v3/testsuite/27_io/print/1.cc @@ -4,7 +4,6 @@ #include #include -#include #include #include diff --git a/libstdc++-v3/testsuite/27_io/print/3.cc b/libstdc++-v3/testsuite/27_io/print/3.cc new file mode 100644 index 00000000000..ffcf7337ce5 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/print/3.cc @@ -0,0 +1,53 @@ +// { dg-additional-options "-lstdc++exp" { target { *-*-mingw* } } } +// { dg-do run { target c++23 } } +// { dg-require-fileio "" } + +#include +#include +#include +#include + +void +test_println_blank() +{ + std::print("1"); + std::println(); + std::println("2"); + // { dg-output "1\n2" } +} + +void +test_println_blank_file() +{ + __gnu_test::scoped_file f; + FILE* strm = std::fopen(f.path.string().c_str(), "w"); + VERIFY( strm ); + std::println(strm); + std::fclose(strm); + + std::ifstream in(f.path); + std::string txt(std::istreambuf_iterator(in), {}); + VERIFY( txt == "\n" ); +} + +void +test_errors() +{ +#ifdef __cpp_exceptions + try + { + std::println(stdin); + VERIFY(false); + } + catch (const std::system_error&) + { + } +#endif +} + +int main() +{ + test_println_blank(); + test_println_blank_file(); + test_errors(); +} -- 2.44.0