[libcxx-commits] [libcxx] [libc++][format] P3142R0 - Printing Blank Lines with `println` (PR #87277)
Hristo Hristov via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Apr 1 12:23:05 PDT 2024
https://github.com/H-G-Hristov created https://github.com/llvm/llvm-project/pull/87277
Implements https://wg21.link/P3142R0
>From 327f8fe8ab2bda7e7f46ba5b2cbfd2a37c51b1cc Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 29 Mar 2024 18:13:32 +0200
Subject: [PATCH] [libc++][format] P3142R0 - Printing Blank Lines with
`println`
Implements https://wg21.link/P3142R0
---
libcxx/docs/ReleaseNotes/19.rst | 1 +
libcxx/include/ostream | 3 +++
libcxx/include/print | 6 ++++++
.../locale-specific_form.pass.cpp | 4 +++-
.../ostream.formatted.print/println.pass.cpp | 4 +++-
.../print.fun/no_file_description.pass.cpp | 5 ++++-
.../print.fun/println.file.pass.cpp | 18 ++++++++++++++++++
.../iostream.format/print.fun/println.sh.cpp | 3 ++-
8 files changed, 40 insertions(+), 4 deletions(-)
diff --git a/libcxx/docs/ReleaseNotes/19.rst b/libcxx/docs/ReleaseNotes/19.rst
index dd39c1bbbc78a3..7bf1da91e2abb9 100644
--- a/libcxx/docs/ReleaseNotes/19.rst
+++ b/libcxx/docs/ReleaseNotes/19.rst
@@ -42,6 +42,7 @@ Implemented Papers
- P2652R2 - Disallow User Specialization of ``allocator_traits``
- P2819R2 - Add ``tuple`` protocol to ``complex``
- P2495R3 - Interfacing ``stringstream``\s with ``string_view``
+- P3142R0 - Printing Blank Lines with ``println`` (as DR against C++23)
- P2302R4 - ``std::ranges::contains``
- P1659R3 - ``std::ranges::starts_with`` and ``std::ranges::ends_with``
diff --git a/libcxx/include/ostream b/libcxx/include/ostream
index 42819ceb252c65..0c97f48da5c5a4 100644
--- a/libcxx/include/ostream
+++ b/libcxx/include/ostream
@@ -164,6 +164,7 @@ template<class... Args>
void print(ostream& os, format_string<Args...> fmt, Args&&... args);
template<class... Args> // since C++23
void println(ostream& os, format_string<Args...> fmt, Args&&... args);
+void println(ostream& os); // since C++26
void vprint_unicode(ostream& os, string_view fmt, format_args args); // since C++23
void vprint_nonunicode(ostream& os, string_view fmt, format_args args); // since C++23
@@ -1163,6 +1164,8 @@ _LIBCPP_HIDE_FROM_ABI void println(ostream& __os, format_string<_Args...> __fmt,
# endif // _LIBCPP_HAS_NO_UNICODE
}
+_LIBCPP_HIDE_FROM_ABI inline void println(ostream& __os) { std::print(__os, "\n"); }
+
#endif // _LIBCPP_STD_VER >= 23
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/print b/libcxx/include/print
index a9f10433a7dc61..e12dfe999c64d7 100644
--- a/libcxx/include/print
+++ b/libcxx/include/print
@@ -15,8 +15,10 @@ namespace std {
// [print.fun], print functions
template<class... Args>
void print(format_string<Args...> fmt, Args&&... args);
+ void println(); // Since C++26
template<class... Args>
void print(FILE* stream, format_string<Args...> fmt, Args&&... args);
+ void println(FILE* stream); // Since C++26
template<class... Args>
void println(format_string<Args...> fmt, Args&&... args);
@@ -356,6 +358,10 @@ _LIBCPP_HIDE_FROM_ABI void println(FILE* __stream, format_string<_Args...> __fmt
# endif // _LIBCPP_HAS_NO_UNICODE
}
+_LIBCPP_HIDE_FROM_ABI inline void println(FILE* __stream) { std::print(__stream, "\n"); }
+
+_LIBCPP_HIDE_FROM_ABI inline void println() { println(stdout); }
+
template <class... _Args>
_LIBCPP_HIDE_FROM_ABI void println(format_string<_Args...> __fmt, _Args&&... __args) {
std::println(stdout, __fmt, std::forward<_Args>(__args)...);
diff --git a/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/locale-specific_form.pass.cpp b/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/locale-specific_form.pass.cpp
index 6b62e2f1754de5..8edfb90b15b86d 100644
--- a/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/locale-specific_form.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/locale-specific_form.pass.cpp
@@ -26,6 +26,7 @@
// void print(ostream& os, format_string<Args...> fmt, Args&&... args);
// template<class... Args>
// void println(ostream& os, format_string<Args...> fmt, Args&&... args);
+// void println(ostream& os); // since C++26
//
// void vprint_unicode(ostream& os, string_view fmt, format_args args);
// void vprint_nonunicode(ostream& os, string_view fmt, format_args args);
@@ -86,10 +87,11 @@ test(std::stringstream& stream, std::string expected, test_format_string<char, A
}
// *** println ***
{
- expected += '\n'; // Tested last since it changes the expected value.
+ expected += "\n\n"; // Tested last since it changes the expected value.
stream.str("");
;
std::println(stream, fmt, std::forward<Args>(args)...);
+ std::println(stream);
std::string out = stream.str();
TEST_REQUIRE(out == expected,
TEST_WRITE_CONCATENATED(
diff --git a/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/println.pass.cpp b/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/println.pass.cpp
index 479a3de0a93c8d..24b1062775493a 100644
--- a/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/println.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/println.pass.cpp
@@ -17,6 +17,7 @@
// template<class... Args>
// void println(ostream& os, format_string<Args...> fmt, Args&&... args);
+// void println(ostream& os); // since C++26
// [ostream.formatted.print]/3
// If the function is vprint_unicode and os is a stream that refers to
@@ -37,9 +38,10 @@
#include "test_macros.h"
auto test_file = []<class... Args>(std::string_view e, test_format_string<char, Args...> fmt, Args&&... args) {
- std::string expected = std::string{e} + '\n';
+ std::string expected = '\n' + std::string{e} + '\n';
std::stringstream sstr;
+ std::println(sstr);
std::println(sstr, fmt, std::forward<Args>(args)...);
std::string out = sstr.str();
diff --git a/libcxx/test/std/input.output/iostream.format/print.fun/no_file_description.pass.cpp b/libcxx/test/std/input.output/iostream.format/print.fun/no_file_description.pass.cpp
index f502616b677b77..5144e61afaec59 100644
--- a/libcxx/test/std/input.output/iostream.format/print.fun/no_file_description.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/print.fun/no_file_description.pass.cpp
@@ -25,8 +25,10 @@
// template<class... Args>
// void print(FILE* stream, format_string<Args...> fmt, Args&&... args);
+// void println(); // Since C++26
// template<class... Args>
// void println(FILE* stream, format_string<Args...> fmt, Args&&... args);
+// void println(FILE* stream); // Since C++26
// void vprint_unicode(FILE* stream, string_view fmt, format_args args);
// void vprint_nonunicode(FILE* stream, string_view fmt, format_args args);
@@ -55,12 +57,13 @@ static void test_println() {
FILE* file = fmemopen(buffer.data(), buffer.size(), "wb");
assert(file);
+ std::println(file);
std::println(file, "hello world{}", '!');
long pos = std::ftell(file);
std::fclose(file);
assert(pos > 0);
- assert(std::string_view(buffer.data(), pos) == "hello world!\n");
+ assert(std::string_view(buffer.data(), pos) == "\nhello world!\n");
}
static void test_vprint_unicode() {
diff --git a/libcxx/test/std/input.output/iostream.format/print.fun/println.file.pass.cpp b/libcxx/test/std/input.output/iostream.format/print.fun/println.file.pass.cpp
index 07272ebb57e5fc..9e96864aa822dd 100644
--- a/libcxx/test/std/input.output/iostream.format/print.fun/println.file.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/print.fun/println.file.pass.cpp
@@ -112,6 +112,17 @@ static void test_new_line() {
FILE* file = fopen(filename.c_str(), "w");
assert(file);
+ std::println(file);
+#ifndef _WIN32
+ assert(std::ftell(file) == 1);
+#else
+ assert(std::ftell(file) == 2);
+#endif
+ }
+ {
+ FILE* file = fopen(filename.c_str(), "w");
+ assert(file);
+
std::println(file, "");
#ifndef _WIN32
assert(std::ftell(file) == 1);
@@ -124,6 +135,13 @@ static void test_new_line() {
FILE* file = fopen(filename.c_str(), "wb");
assert(file);
+ std::println(file);
+ assert(std::ftell(file) == 1);
+ }
+ {
+ FILE* file = fopen(filename.c_str(), "wb");
+ assert(file);
+
std::println(file, "");
assert(std::ftell(file) == 1);
}
diff --git a/libcxx/test/std/input.output/iostream.format/print.fun/println.sh.cpp b/libcxx/test/std/input.output/iostream.format/print.fun/println.sh.cpp
index b811b4f2a24933..b93fa723ee2174 100644
--- a/libcxx/test/std/input.output/iostream.format/print.fun/println.sh.cpp
+++ b/libcxx/test/std/input.output/iostream.format/print.fun/println.sh.cpp
@@ -36,7 +36,7 @@
// FILE_DEPENDENCIES: echo.sh
// RUN: %{build}
-// RUN: %{exec} bash echo.sh -ne "1234 一二三四\ntrue 0x0\n" > %t.expected
+// RUN: %{exec} bash echo.sh -ne "\n1234 一二三四\ntrue 0x0\n" > %t.expected
// RUN: %{exec} "%t.exe" > %t.actual
// RUN: diff -u %t.actual %t.expected
@@ -44,6 +44,7 @@
int main(int, char**) {
// The data is passed as-is so it does not depend on the encoding of the input.
+ std::println();
std::println("{} {}", 1234, "一二三四");
std::println("{} {}", true, nullptr);
More information about the libcxx-commits
mailing list