[libcxx-commits] [libcxx] [libc++][format] P3142R0: Printing Blank Lines with `println` (PR #87277)
Hristo Hristov via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Apr 5 13:12:12 PDT 2024
https://github.com/H-G-Hristov updated https://github.com/llvm/llvm-project/pull/87277
>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 1/9] [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);
>From d39dbbedf29b09a35787841041ca43a8460ed4bf Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 1 Apr 2024 23:20:52 +0300
Subject: [PATCH 2/9] Try to fix Apple CI
---
libcxx/include/ostream | 1 +
libcxx/include/print | 2 ++
2 files changed, 3 insertions(+)
diff --git a/libcxx/include/ostream b/libcxx/include/ostream
index 0c97f48da5c5a4..d4fc1c58b8a941 100644
--- a/libcxx/include/ostream
+++ b/libcxx/include/ostream
@@ -1164,6 +1164,7 @@ _LIBCPP_HIDE_FROM_ABI void println(ostream& __os, format_string<_Args...> __fmt,
# endif // _LIBCPP_HAS_NO_UNICODE
}
+template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
_LIBCPP_HIDE_FROM_ABI inline void println(ostream& __os) { std::print(__os, "\n"); }
#endif // _LIBCPP_STD_VER >= 23
diff --git a/libcxx/include/print b/libcxx/include/print
index e12dfe999c64d7..e0bcf214ea239b 100644
--- a/libcxx/include/print
+++ b/libcxx/include/print
@@ -358,8 +358,10 @@ _LIBCPP_HIDE_FROM_ABI void println(FILE* __stream, format_string<_Args...> __fmt
# endif // _LIBCPP_HAS_NO_UNICODE
}
+template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
_LIBCPP_HIDE_FROM_ABI inline void println(FILE* __stream) { std::print(__stream, "\n"); }
+template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
_LIBCPP_HIDE_FROM_ABI inline void println() { println(stdout); }
template <class... _Args>
>From 36c65f2c06c9d2350bd7104777d4a6a1f86ce056 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Mon, 1 Apr 2024 23:24:26 +0300
Subject: [PATCH 3/9] Updated tests for consistency
---
.../ostream.formatted.print/println.pass.cpp | 4 ++--
.../iostream.format/print.fun/no_file_description.pass.cpp | 4 ++--
.../std/input.output/iostream.format/print.fun/println.sh.cpp | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
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 24b1062775493a..b61fcf174422af 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
@@ -38,11 +38,11 @@
#include "test_macros.h"
auto test_file = []<class... Args>(std::string_view e, test_format_string<char, Args...> fmt, Args&&... args) {
- std::string expected = '\n' + std::string{e} + '\n';
+ std::string expected = std::string{e} + "\n\n";
std::stringstream sstr;
- std::println(sstr);
std::println(sstr, fmt, std::forward<Args>(args)...);
+ std::println(sstr);
std::string out = sstr.str();
TEST_REQUIRE(out == expected,
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 5144e61afaec59..450ca45a6d4b7e 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
@@ -57,13 +57,13 @@ static void test_println() {
FILE* file = fmemopen(buffer.data(), buffer.size(), "wb");
assert(file);
- std::println(file);
std::println(file, "hello world{}", '!');
+ std::println(file);
long pos = std::ftell(file);
std::fclose(file);
assert(pos > 0);
- assert(std::string_view(buffer.data(), pos) == "\nhello world!\n");
+ assert(std::string_view(buffer.data(), pos) == "hello world!\n\n");
}
static void test_vprint_unicode() {
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 b93fa723ee2174..67343b3a730c54 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 "\n1234 一二三四\ntrue 0x0\n" > %t.expected
+// RUN: %{exec} bash echo.sh -ne "1234 一二三四\ntrue 0x0\n\n" > %t.expected
// RUN: %{exec} "%t.exe" > %t.actual
// RUN: diff -u %t.actual %t.expected
@@ -44,9 +44,9 @@
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);
+ std::println();
return 0;
}
>From 8c93e195cc58a256b0929971f8518cf63938cc6e Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Thu, 4 Apr 2024 23:19:38 +0300
Subject: [PATCH 4/9] Addressed review comments
---
libcxx/docs/Status/Cxx2cPapers.csv | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index a34dad58168078..e0e54d75a8850b 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -51,7 +51,7 @@
"`P2869R4 <https://wg21.link/P2869R4>`__","LWG","Remove Deprecated ``shared_ptr`` Atomic Access APIs from C++26","Tokyo March 2024","","",""
"`P2872R3 <https://wg21.link/P2872R3>`__","LWG","Remove ``wstring_convert`` >From C++26","Tokyo March 2024","","",""
"`P3107R5 <https://wg21.link/P3107R5>`__","LWG","Permit an efficient implementation of ``std::print``","Tokyo March 2024","","","|format| |DR|"
-"`P3142R0 <https://wg21.link/P3142R0>`__","LWG","Printing Blank Lines with ``println``","Tokyo March 2024","","","|format|"
+"`P3142R0 <https://wg21.link/P3142R0>`__","LWG","Printing Blank Lines with ``println``","Tokyo March 2024","|Complete|","19.0","|format|"
"`P2845R8 <https://wg21.link/P2845R8>`__","LWG","Formatting of ``std::filesystem::path``","Tokyo March 2024","","","|format|"
"`P0493R5 <https://wg21.link/P0493R5>`__","LWG","Atomic minimum/maximum","Tokyo March 2024","","",""
"`P2542R8 <https://wg21.link/P2542R8>`__","LWG","``views::concat``","Tokyo March 2024","","","|ranges|"
>From 02fbb0b66af6c14ce5ff6ffd0d45128dd00dabf6 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 5 Apr 2024 00:07:37 +0300
Subject: [PATCH 5/9] Split tests 1
---
.../locale-specific_form.pass.cpp | 3 +--
.../ostream.formatted.print/println.pass.cpp | 3 +--
.../print.fun/no_file_description.pass.cpp | 16 ++++++++++++-
.../print.fun/println.file.pass.cpp | 24 ++++++++++++-------
4 files changed, 32 insertions(+), 14 deletions(-)
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 8edfb90b15b86d..231c790eee5d26 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
@@ -87,11 +87,10 @@ test(std::stringstream& stream, std::string expected, test_format_string<char, A
}
// *** println ***
{
- expected += "\n\n"; // Tested last since it changes the expected value.
+ expected += '\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 b61fcf174422af..a752323c2aa039 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
@@ -38,11 +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\n";
+ std::string expected = std::string{e} + '\n';
std::stringstream sstr;
std::println(sstr, fmt, std::forward<Args>(args)...);
- std::println(sstr);
std::string out = sstr.str();
TEST_REQUIRE(out == expected,
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 450ca45a6d4b7e..ffa48c5e745d65 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
@@ -58,12 +58,25 @@ static void test_println() {
assert(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");
+}
+
+static void test_println_blank_line() {
+ std::array<char, 100> buffer{0};
+
+ FILE* file = fmemopen(buffer.data(), buffer.size(), "wb");
+ assert(file);
+
std::println(file);
long pos = std::ftell(file);
std::fclose(file);
assert(pos > 0);
- assert(std::string_view(buffer.data(), pos) == "hello world!\n\n");
+ assert(std::string_view(buffer.data(), pos) == "\n");
}
static void test_vprint_unicode() {
@@ -99,6 +112,7 @@ static void test_vprint_nonunicode() {
int main(int, char**) {
test_print();
test_println();
+ test_println_blank_line();
test_vprint_unicode();
test_vprint_nonunicode();
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 9e96864aa822dd..2f088e7a7db5f2 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,37 +112,42 @@ static void test_new_line() {
FILE* file = fopen(filename.c_str(), "w");
assert(file);
- std::println(file);
+ std::println(file, "");
#ifndef _WIN32
assert(std::ftell(file) == 1);
#else
assert(std::ftell(file) == 2);
#endif
}
+ // Binary no newline translation.
{
- FILE* file = fopen(filename.c_str(), "w");
+ FILE* file = fopen(filename.c_str(), "wb");
assert(file);
std::println(file, "");
-#ifndef _WIN32
assert(std::ftell(file) == 1);
-#else
- assert(std::ftell(file) == 2);
-#endif
}
- // Binary no newline translation.
+}
+
+static void test_println_blank_line() {
+ // Text does newline translation.
{
- FILE* file = fopen(filename.c_str(), "wb");
+ 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
}
+ // Binary no newline translation.
{
FILE* file = fopen(filename.c_str(), "wb");
assert(file);
- std::println(file, "");
+ std::println(file);
assert(std::ftell(file) == 1);
}
}
@@ -155,6 +160,7 @@ int main(int, char**) {
#endif
test_read_only();
test_new_line();
+ test_println_blank_line();
return 0;
}
>From 6de4539ae0b97411aeca7a98ed88a7961a4c9bda Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 5 Apr 2024 00:30:48 +0300
Subject: [PATCH 6/9] Split tests 2
---
.../locale-specific_form.pass.cpp | 10 ++++++++++
.../ostream.formatted.print/println.pass.cpp | 12 ++++++++++++
2 files changed, 22 insertions(+)
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 231c790eee5d26..b6c755a7a5776a 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
@@ -96,6 +96,16 @@ test(std::stringstream& stream, std::string expected, test_format_string<char, A
TEST_WRITE_CONCATENATED(
"\nFormat string ", fmt.get(), "\nExpected output ", expected, "\nActual output ", out, '\n'));
}
+ // *** println blank line***
+ {
+ expected = "\n";
+ stream.str("");
+ ;
+ std::println(stream);
+ std::string out = stream.str();
+ TEST_REQUIRE(out == expected,
+ TEST_WRITE_CONCATENATED("\nExpected output ", expected, "\nActual output ", out, '\n'));
+ }
}
template <class... Args>
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 a752323c2aa039..17aedc076cf2d0 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
@@ -56,8 +56,20 @@ auto test_exception = []<class... Args>(std::string_view, std::string_view, Args
// The exceptions are tested by other functions that don't use the basic-format-string as fmt argument.
};
+void test_println_blank_line() {
+ std::string expected{'\n'};
+
+ std::stringstream sstr;
+ std::println(sstr);
+
+ std::string out = sstr.str();
+ TEST_REQUIRE(out == expected,
+ TEST_WRITE_CONCATENATED("\nExpected output ", expected, "\nActual output ", out, '\n'));
+};
+
int main(int, char**) {
print_tests(test_file, test_exception);
+ test_println_blank_line();
return 0;
}
>From 853bae680a36ee572eded08db6699d981d84ec62 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 5 Apr 2024 21:15:08 +0300
Subject: [PATCH 7/9] Addressed review comments
---
.../ostream.formatted.print/locale-specific_form.pass.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
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 b6c755a7a5776a..debe80f1a1920c 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
@@ -68,7 +68,7 @@ test(std::stringstream& stream, std::string expected, test_format_string<char, A
// *** vprint_unicode ***
{
stream.str("");
- ;
+
std::vprint_unicode(stream, fmt.get(), std::make_format_args(args...));
std::string out = stream.str();
TEST_REQUIRE(out == expected,
@@ -78,7 +78,7 @@ test(std::stringstream& stream, std::string expected, test_format_string<char, A
// *** vprint_nonunicode ***
{
stream.str("");
- ;
+
std::vprint_nonunicode(stream, fmt.get(), std::make_format_args(args...));
std::string out = stream.str();
TEST_REQUIRE(out == expected,
@@ -89,7 +89,7 @@ test(std::stringstream& stream, std::string expected, test_format_string<char, A
{
expected += '\n'; // Tested last since it changes the expected value.
stream.str("");
- ;
+
std::println(stream, fmt, std::forward<Args>(args)...);
std::string out = stream.str();
TEST_REQUIRE(out == expected,
@@ -100,7 +100,7 @@ test(std::stringstream& stream, std::string expected, test_format_string<char, A
{
expected = "\n";
stream.str("");
- ;
+
std::println(stream);
std::string out = stream.str();
TEST_REQUIRE(out == expected,
>From 32cfe093dda21eaa09618aac4a37b3c178ebedf4 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 5 Apr 2024 21:43:48 +0300
Subject: [PATCH 8/9] Addressed review comments
---
.../locale-specific_form.pass.cpp | 2 +-
.../ostream.formatted.print/println.pass.cpp | 2 +-
.../print.fun/println.blank_line.sh.cpp | 48 +++++++++++++++++++
3 files changed, 50 insertions(+), 2 deletions(-)
create mode 100644 libcxx/test/std/input.output/iostream.format/print.fun/println.blank_line.sh.cpp
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 debe80f1a1920c..89a5cbb3edf823 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
@@ -104,7 +104,7 @@ test(std::stringstream& stream, std::string expected, test_format_string<char, A
std::println(stream);
std::string out = stream.str();
TEST_REQUIRE(out == expected,
- TEST_WRITE_CONCATENATED("\nExpected output ", expected, "\nActual output ", out, '\n'));
+ TEST_WRITE_CONCATENATED("\nExpected output (blank line) ", expected, "\nActual output ", out, '\n'));
}
}
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 17aedc076cf2d0..19a02638a9da18 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
@@ -64,7 +64,7 @@ void test_println_blank_line() {
std::string out = sstr.str();
TEST_REQUIRE(out == expected,
- TEST_WRITE_CONCATENATED("\nExpected output ", expected, "\nActual output ", out, '\n'));
+ TEST_WRITE_CONCATENATED("\nExpected output (blank line) ", expected, "\nActual output ", out, '\n'));
};
int main(int, char**) {
diff --git a/libcxx/test/std/input.output/iostream.format/print.fun/println.blank_line.sh.cpp b/libcxx/test/std/input.output/iostream.format/print.fun/println.blank_line.sh.cpp
new file mode 100644
index 00000000000000..93c3563d501b20
--- /dev/null
+++ b/libcxx/test/std/input.output/iostream.format/print.fun/println.blank_line.sh.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+// UNSUPPORTED: no-filesystem
+// UNSUPPORTED: executor-has-no-bash
+// UNSUPPORTED: GCC-ALWAYS_INLINE-FIXME
+
+// FIXME PRINT How to test println on Windows?
+// XFAIL: msvc, target={{.+}}-windows-gnu
+
+// XFAIL: availability-fp_to_chars-missing
+
+// <print>
+
+// void println();
+
+// Testing this properly is quite hard; the function unconditionally
+// writes to stdout. When stdout is redirected to a file it is no longer
+// considered a terminal. The function is a small wrapper around
+//
+// template<class... Args>
+// void println(FILE* stream, format_string<Args...> fmt, Args&&... args);
+//
+// So do minimal tests for this function and rely on the FILE* overload
+// to do more testing.
+//
+// The testing is based on the testing for std::cout.
+
+// TODO PRINT Use lit builtin echo
+
+// FILE_DEPENDENCIES: echo.sh
+// RUN: %{build}
+// RUN: %{exec} bash echo.sh -ne "\n" > %t.expected
+// RUN: %{exec} "%t.exe" > %t.actual
+// RUN: diff -u %t.actual %t.expected
+
+#include <print>
+
+int main(int, char**) {
+ std::println();
+
+ return 0;
+}
>From 689a46e69b8aefef3ed6be115dbe79bd37314bd1 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 5 Apr 2024 22:00:07 +0300
Subject: [PATCH 9/9] Addressed review comments
---
.../locale-specific_form.pass.cpp | 49 +++++++++++++++----
1 file changed, 39 insertions(+), 10 deletions(-)
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 89a5cbb3edf823..336be7455cf80d 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
@@ -96,16 +96,6 @@ test(std::stringstream& stream, std::string expected, test_format_string<char, A
TEST_WRITE_CONCATENATED(
"\nFormat string ", fmt.get(), "\nExpected output ", expected, "\nActual output ", out, '\n'));
}
- // *** println blank line***
- {
- expected = "\n";
- stream.str("");
-
- std::println(stream);
- std::string out = stream.str();
- TEST_REQUIRE(out == expected,
- TEST_WRITE_CONCATENATED("\nExpected output (blank line) ", expected, "\nActual output ", out, '\n'));
- }
}
template <class... Args>
@@ -122,6 +112,7 @@ static void test(std::string expected, std::locale loc, test_format_string<char,
}
#ifndef TEST_HAS_NO_UNICODE
+
struct numpunct_unicode : std::numpunct<char> {
string_type do_truename() const override { return "gültig"; }
string_type do_falsename() const override { return "ungültig"; }
@@ -2199,12 +2190,50 @@ static void test_floating_point() {
test_floating_point_default_precision<F>();
}
+static void test_println_blank_line(std::stringstream& stream) {
+ std::string expected{'\n'};
+ stream.str("");
+
+ std::println(stream);
+ std::string out = stream.str();
+ TEST_REQUIRE(out == expected,
+ TEST_WRITE_CONCATENATED("\nExpected output (blank line) ", expected, "\nActual output ", out, '\n'));
+}
+
+static void test_println_blank_line(std::locale loc) {
+ std::stringstream stream;
+ stream.imbue(loc);
+ test_println_blank_line(stream);
+}
+
+static void test_println_blank_line() {
+ std::locale loc = std::locale(std::locale(), new numpunct<char>());
+
+ std::locale::global(std::locale(LOCALE_en_US_UTF_8));
+ assert(std::locale().name() == LOCALE_en_US_UTF_8);
+
+ std::stringstream stream;
+ test_println_blank_line(stream);
+
+ std::locale::global(loc);
+
+ test_println_blank_line(std::locale(LOCALE_en_US_UTF_8));
+ test_println_blank_line(std::locale(LOCALE_en_US_UTF_8));
+
+#ifndef TEST_HAS_NO_UNICODE
+ std::locale loc_unicode = std::locale(std::locale(), new numpunct_unicode());
+
+ test_println_blank_line(loc_unicode);
+#endif // TEST_HAS_NO_UNICODE
+}
+
int main(int, char**) {
test_bool();
test_integer();
test_floating_point<float>();
test_floating_point<double>();
test_floating_point<long double>();
+ test_println_blank_line();
return 0;
}
More information about the libcxx-commits
mailing list