public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-6469] libstdc++: Fix std::format("{}", 'c')
@ 2023-12-12 22:46 Jonathan Wakely
0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2023-12-12 22:46 UTC (permalink / raw)
To: gcc-cvs, libstdc++-cvs
https://gcc.gnu.org/g:52de6aa1a8582208b519b6998389d3a801b0de7b
commit r14-6469-g52de6aa1a8582208b519b6998389d3a801b0de7b
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Tue Dec 12 20:53:08 2023 +0000
libstdc++: Fix std::format("{}", 'c')
When I added a fast path for std::format("{}", x) in
r14-5587-g41a5ea4cab2c59 I forgot to handle char separately from other
integral types. That caused std::format("{}", 'c') to return "99"
instead of "c".
libstdc++-v3/ChangeLog:
* include/std/format (__do_vformat_to): Handle char separately
from other integral types.
* testsuite/std/format/functions/format.cc: Check for expected
output for char and bool arguments.
* testsuite/std/format/string.cc: Check that 0 filling is
rejected for character and string formats.
Diff:
---
libstdc++-v3/include/std/format | 9 ++++
.../testsuite/std/format/functions/format.cc | 56 ++++++++++++++++++++++
libstdc++-v3/testsuite/std/format/string.cc | 3 ++
3 files changed, 68 insertions(+)
diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 04d03e0ceb7..1f8cd5c06be 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -3968,6 +3968,15 @@ namespace __format
__done = true;
}
}
+ else if constexpr (is_same_v<_Tp, char>)
+ {
+ if (auto __res = __sink_out._M_reserve(1))
+ {
+ *__res.get() = __arg;
+ __res._M_bump(1);
+ __done = true;
+ }
+ }
else if constexpr (is_integral_v<_Tp>)
{
make_unsigned_t<_Tp> __uval;
diff --git a/libstdc++-v3/testsuite/std/format/functions/format.cc b/libstdc++-v3/testsuite/std/format/functions/format.cc
index 9328dec8875..b3b4f0647bc 100644
--- a/libstdc++-v3/testsuite/std/format/functions/format.cc
+++ b/libstdc++-v3/testsuite/std/format/functions/format.cc
@@ -256,12 +256,42 @@ test_width()
}
}
+void
+test_char()
+{
+ std::string s;
+
+ s = std::format("{}", 'a');
+ VERIFY( s == "a" );
+
+ s = std::format("{:c} {:d} {:o}", 'b', '\x17', '\x3f');
+ VERIFY( s == "b 23 77" );
+
+ s = std::format("{:#d} {:#o}", '\x17', '\x3f');
+ VERIFY( s == "23 077" );
+
+ s = std::format("{:04d} {:04o}", '\x17', '\x3f');
+ VERIFY( s == "0023 0077" );
+
+ s = std::format("{:b} {:B} {:#b} {:#B}", '\xff', '\xa0', '\x17', '\x3f');
+ if constexpr (std::is_unsigned_v<char>)
+ VERIFY( s == "11111111 10100000 0b10111 0B111111" );
+ else
+ VERIFY( s == "-1 -1100000 0b10111 0B111111" );
+
+ s = std::format("{:x} {:#x} {:#X}", '\x12', '\x34', '\x45');
+ VERIFY( s == "12 0x34 0X45" );
+}
+
void
test_wchar()
{
using namespace std::literals;
std::wstring s;
+ s = std::format(L"{}", L'a');
+ VERIFY( s == L"a" );
+
s = std::format(L"{} {} {} {} {} {}", L'0', 1, 2LL, 3.4, L"five", L"six"s);
VERIFY( s == L"0 1 2 3.4 five six" );
@@ -353,6 +383,9 @@ test_pointer()
const void* pc = p;
std::string s, str_int;
+ s = std::format("{}", p);
+ VERIFY( s == "0x0" );
+
s = std::format("{} {} {}", p, pc, nullptr);
VERIFY( s == "0x0 0x0 0x0" );
s = std::format("{:p} {:p} {:p}", p, pc, nullptr);
@@ -385,6 +418,27 @@ test_pointer()
#endif
}
+void
+test_bool()
+{
+ std::string s;
+
+ s = std::format("{}", true);
+ VERIFY( s == "true" );
+ s = std::format("{:} {:s}", true, false);
+ VERIFY( s == "true false" );
+ s = std::format("{:b} {:#b}", true, false);
+ VERIFY( s == "1 0b0" );
+ s = std::format("{:B} {:#B}", false, true);
+ VERIFY( s == "0 0B1" );
+ s = std::format("{:d} {:#d}", false, true);
+ VERIFY( s == "0 1" );
+ s = std::format("{:o} {:#o} {:#o}", false, true, false);
+ VERIFY( s == "0 01 0" );
+ s = std::format("{:x} {:#x} {:#X}", false, true, false);
+ VERIFY( s == "0 0x1 0X0" );
+}
+
int main()
{
test_no_args();
@@ -393,8 +447,10 @@ int main()
test_alternate_forms();
test_locale();
test_width();
+ test_char();
test_wchar();
test_minmax();
test_p1652r1();
test_pointer();
+ test_bool();
}
diff --git a/libstdc++-v3/testsuite/std/format/string.cc b/libstdc++-v3/testsuite/std/format/string.cc
index 5d338644c62..40aaebae04e 100644
--- a/libstdc++-v3/testsuite/std/format/string.cc
+++ b/libstdc++-v3/testsuite/std/format/string.cc
@@ -109,6 +109,9 @@ test_format_spec()
VERIFY( ! is_format_string_for("{:#?}", "str") );
VERIFY( ! is_format_string_for("{:#?}", 'c') );
+ VERIFY( ! is_format_string_for("{:0c}", 'c') );
+ VERIFY( ! is_format_string_for("{:0s}", true) );
+
// Precision only valid for string and floating-point types.
VERIFY( ! is_format_string_for("{:.3d}", 1) );
VERIFY( ! is_format_string_for("{:3.3d}", 1) );
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-12-12 22:46 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-12 22:46 [gcc r14-6469] libstdc++: Fix std::format("{}", 'c') Jonathan Wakely
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).