[libcxx-commits] [libcxx] [lib++][print] Don't pad the ostream output. (PR #128354)

Mark de Wever via libcxx-commits libcxx-commits at lists.llvm.org
Sat Feb 22 04:36:28 PST 2025


https://github.com/mordante created https://github.com/llvm/llvm-project/pull/128354

Per [ostream.formatted.reqmts]/3 padding should only be done when explicitly stated.

Fixes: #116054

>From f5dbda5281d605c6c5dd094c6ea91e128e6eef6e Mon Sep 17 00:00:00 2001
From: Mark de Wever <koraq at xs4all.nl>
Date: Sat, 22 Feb 2025 13:34:54 +0100
Subject: [PATCH] [lib++][print] Don't pad the ostream output.

Per [ostream.formatted.reqmts]/3 padding should only be done when
explicitly stated.

Fixes: #116054
---
 libcxx/include/__ostream/print.h              | 14 ++-------
 .../ostream.formatted.print/print.pass.cpp    | 30 +++++--------------
 .../vprint_nonunicode.pass.cpp                | 30 +++++--------------
 .../vprint_unicode.pass.cpp                   | 30 +++++--------------
 4 files changed, 23 insertions(+), 81 deletions(-)

diff --git a/libcxx/include/__ostream/print.h b/libcxx/include/__ostream/print.h
index eb4233342214d..a4d7506cffc48 100644
--- a/libcxx/include/__ostream/print.h
+++ b/libcxx/include/__ostream/print.h
@@ -49,21 +49,11 @@ __vprint_nonunicode(ostream& __os, string_view __fmt, format_args __args, bool _
     if (__write_nl)
       __o += '\n';
 
-    const char* __str = __o.data();
-    size_t __len      = __o.size();
-
 #    if _LIBCPP_HAS_EXCEPTIONS
     try {
 #    endif // _LIBCPP_HAS_EXCEPTIONS
-      typedef ostreambuf_iterator<char> _Ip;
-      if (std::__pad_and_output(
-              _Ip(__os),
-              __str,
-              (__os.flags() & ios_base::adjustfield) == ios_base::left ? __str + __len : __str,
-              __str + __len,
-              __os,
-              __os.fill())
-              .failed())
+      if (auto __rdbuf = __os.rdbuf();
+          !__rdbuf || __rdbuf->sputn(__o.data(), __o.size()) != static_cast<streamsize>(__o.size()))
         __os.setstate(ios_base::badbit | ios_base::failbit);
 
 #    if _LIBCPP_HAS_EXCEPTIONS
diff --git a/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/print.pass.cpp b/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/print.pass.cpp
index 711152ba6f32a..1f188b36db9a3 100644
--- a/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/print.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/print.pass.cpp
@@ -133,6 +133,7 @@ static void test_write_failure() {
   assert(os.fail());
 }
 
+// Test the formatting does no padding.
 static void test_stream_formatting() {
   std::stringstream sstr;
   auto test = [&]<class... Args>(std::string_view expected, test_format_string<char, Args...> fmt, Args&&... args) {
@@ -148,37 +149,20 @@ static void test_stream_formatting() {
   test("hello", "{}", "hello");
 
   sstr.width(10);
-  test("     hello", "{}", "hello");
+  test("hello", "{}", "hello");
+  assert(sstr.width() == 10);
 
   sstr.fill('+');
 
   sstr.width(10);
-  test("+++++hello", "{}", "hello");
+  test("hello", "{}", "hello");
+  assert(sstr.width() == 10);
 
   // *** Test embedded NUL character ***
   using namespace std::literals;
   sstr.width(15);
-  test("++++hello\0world"sv, "hello{}{}", '\0', "world");
-
-  // *** Test Unicode ***
-  // Streams count code units not code points
-  // 2-byte code points
-  sstr.width(5);
-  test("+++\u00a1", "{}", "\u00a1"); // INVERTED EXCLAMATION MARK
-  sstr.width(5);
-  test("+++\u07ff", "{}", "\u07ff"); // NKO TAMAN SIGN
-
-  // 3-byte code points
-  sstr.width(5);
-  test("++\u0800", "{}", "\u0800"); // SAMARITAN LETTER ALAF
-  sstr.width(5);
-  test("++\ufffd", "{}", "\ufffd"); // REPLACEMENT CHARACTER
-
-  // 4-byte code points
-  sstr.width(5);
-  test("+\U00010000", "{}", "\U00010000"); // LINEAR B SYLLABLE B008 A
-  sstr.width(5);
-  test("+\U0010FFFF", "{}", "\U0010FFFF"); // Undefined Character
+  test("hello\0world"sv, "hello{}{}", '\0', "world");
+  assert(sstr.width() == 15);
 }
 
 int main(int, char**) {
diff --git a/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_nonunicode.pass.cpp b/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_nonunicode.pass.cpp
index 73ad19132f17f..7aa7390216adc 100644
--- a/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_nonunicode.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_nonunicode.pass.cpp
@@ -149,6 +149,7 @@ static void test_write_failure() {
   assert(os.fail());
 }
 
+// Test the formatting does no padding.
 static void test_stream_formatting() {
   std::stringstream sstr;
   auto test = [&]<class... Args>(std::string_view expected, test_format_string<char, Args...> fmt, Args&&... args) {
@@ -164,37 +165,20 @@ static void test_stream_formatting() {
   test("hello", "{}", "hello");
 
   sstr.width(10);
-  test("     hello", "{}", "hello");
+  test("hello", "{}", "hello");
+  assert(sstr.width() == 10);
 
   sstr.fill('+');
 
   sstr.width(10);
-  test("+++++hello", "{}", "hello");
+  test("hello", "{}", "hello");
+  assert(sstr.width() == 10);
 
   // *** Test embedded NUL character ***
   using namespace std::literals;
   sstr.width(15);
-  test("++++hello\0world"sv, "hello{}{}", '\0', "world");
-
-  // *** Test Unicode ***
-  // Streams count code units not code points
-  // 2-byte code points
-  sstr.width(5);
-  test("+++\u00a1", "{}", "\u00a1"); // INVERTED EXCLAMATION MARK
-  sstr.width(5);
-  test("+++\u07ff", "{}", "\u07ff"); // NKO TAMAN SIGN
-
-  // 3-byte code points
-  sstr.width(5);
-  test("++\u0800", "{}", "\u0800"); // SAMARITAN LETTER ALAF
-  sstr.width(5);
-  test("++\ufffd", "{}", "\ufffd"); // REPLACEMENT CHARACTER
-
-  // 4-byte code points
-  sstr.width(5);
-  test("+\U00010000", "{}", "\U00010000"); // LINEAR B SYLLABLE B008 A
-  sstr.width(5);
-  test("+\U0010FFFF", "{}", "\U0010FFFF"); // Undefined Character
+  test("hello\0world"sv, "hello{}{}", '\0', "world");
+  assert(sstr.width() == 15);
 }
 
 int main(int, char**) {
diff --git a/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_unicode.pass.cpp b/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_unicode.pass.cpp
index 21f6654d5f9cf..8b43a71215ade 100644
--- a/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_unicode.pass.cpp
+++ b/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_unicode.pass.cpp
@@ -149,6 +149,7 @@ static void test_write_failure() {
   assert(os.fail());
 }
 
+// Test the formatting does no padding.
 static void test_stream_formatting() {
   std::stringstream sstr;
   auto test = [&]<class... Args>(std::string_view expected, test_format_string<char, Args...> fmt, Args&&... args) {
@@ -164,37 +165,20 @@ static void test_stream_formatting() {
   test("hello", "{}", "hello");
 
   sstr.width(10);
-  test("     hello", "{}", "hello");
+  test("hello", "{}", "hello");
+  assert(sstr.width() == 10);
 
   sstr.fill('+');
 
   sstr.width(10);
-  test("+++++hello", "{}", "hello");
+  test("hello", "{}", "hello");
+  assert(sstr.width() == 10);
 
   // *** Test embedded NUL character ***
   using namespace std::literals;
   sstr.width(15);
-  test("++++hello\0world"sv, "hello{}{}", '\0', "world");
-
-  // *** Test Unicode ***
-  // Streams count code units not code points
-  // 2-byte code points
-  sstr.width(5);
-  test("+++\u00a1", "{}", "\u00a1"); // INVERTED EXCLAMATION MARK
-  sstr.width(5);
-  test("+++\u07ff", "{}", "\u07ff"); // NKO TAMAN SIGN
-
-  // 3-byte code points
-  sstr.width(5);
-  test("++\u0800", "{}", "\u0800"); // SAMARITAN LETTER ALAF
-  sstr.width(5);
-  test("++\ufffd", "{}", "\ufffd"); // REPLACEMENT CHARACTER
-
-  // 4-byte code points
-  sstr.width(5);
-  test("+\U00010000", "{}", "\U00010000"); // LINEAR B SYLLABLE B008 A
-  sstr.width(5);
-  test("+\U0010FFFF", "{}", "\U0010FFFF"); // Undefined Character
+  test("hello\0world"sv, "hello{}{}", '\0', "world");
+  assert(sstr.width() == 15);
 }
 
 int main(int, char**) {



More information about the libcxx-commits mailing list