From 045aa3b067941b6350b208ee6ae74fe86d3116dd Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 14 Nov 2023 00:51:36 +0800 Subject: [PATCH] Implement P2909R4 Fix Formatting Of Code Units As Integers --- stl/inc/format | 21 ++++++++++++------- stl/inc/yvals_core.h | 2 ++ .../test.cpp | 11 ++++++++++ .../test.compile.pass.cpp | 6 ++++++ 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index 105307688f..3d7807dcdb 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -744,12 +744,15 @@ public: template <_Formattable_with<_Context> _Ty> static basic_format_arg _Make_from(_Ty& _Val) noexcept { using _Erased_type = _Format_arg_traits<_Context>::template _Storage_type<_Ty>; + if constexpr (is_same_v, char> && is_same_v<_CharType, wchar_t>) { + return basic_format_arg(static_cast<_Erased_type>(static_cast(_Val))); + } #if !_HAS_CXX23 - if constexpr (is_same_v<_Erased_type, basic_string_view<_CharType>>) { + else if constexpr (is_same_v<_Erased_type, basic_string_view<_CharType>>) { return basic_format_arg(_Erased_type{_Val.data(), _Val.size()}); - } else + } #endif // !_HAS_CXX23 - { + else { return basic_format_arg(static_cast<_Erased_type>(_Val)); } } @@ -2047,13 +2050,17 @@ private: _Arg_type = _Basic_format_arg_type::_Custom_type; } + if constexpr (is_same_v>, char> && is_same_v<_CharType, wchar_t>) { + _Store_impl<_Erased_type>( + _Arg_index, _Arg_type, static_cast<_Erased_type>(static_cast(_Val))); + } #if !_HAS_CXX23 // Workaround towards N4950 [format.arg]/6.8 in C++20 - if constexpr (is_same_v<_Erased_type, basic_string_view<_CharType>>) { + else if constexpr (is_same_v<_Erased_type, basic_string_view<_CharType>>) { _Store_impl<_Erased_type>(_Arg_index, _Arg_type, _Erased_type{_Val.data(), _Val.size()}); - } else + } #endif // !_HAS_CXX23 - { + else { _Store_impl<_Erased_type>(_Arg_index, _Arg_type, static_cast<_Erased_type>(_Val)); } } @@ -2941,7 +2948,7 @@ _NODISCARD _OutputIt _Fmt_write( && _Specs._Type != '?' #endif // _HAS_CXX23 ) { - return _Write_integral(_STD move(_Out), _Value, _Specs, _Locale); + return _Write_integral(_STD move(_Out), static_cast>(_Value), _Specs, _Locale); } _STL_INTERNAL_CHECK(_Specs._Precision == -1); diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 1c494ad110..5abef80106 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -306,6 +306,7 @@ // P2711R1 Making Multi-Param Constructors Of Views explicit // P2736R2 Referencing The Unicode Standard // P2770R0 Stashing Stashing Iterators For Proper Flattening +// P2909R4 Fix Formatting Of Code Units As Integers // _HAS_CXX20 indirectly controls: // P0619R4 Removing C++17-Deprecated Features @@ -1748,6 +1749,7 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #ifdef __cpp_lib_concepts #define __cpp_lib_format 202207L +#define __cpp_lib_format_uchar 202311L #define __cpp_lib_freestanding_ranges 202306L #endif // defined(__cpp_lib_concepts) diff --git a/tests/std/tests/P0645R10_text_formatting_formatting/test.cpp b/tests/std/tests/P0645R10_text_formatting_formatting/test.cpp index 9954c85d77..4fa15eefa3 100644 --- a/tests/std/tests/P0645R10_text_formatting_formatting/test.cpp +++ b/tests/std/tests/P0645R10_text_formatting_formatting/test.cpp @@ -725,6 +725,17 @@ void test_char_specs() { test_type(STR("{:X}"), charT{'X'}); test_type(STR("{:+d}"), charT{'X'}); + + // P2909R4 Fix formatting of code units as integers + constexpr charT irregular_code_unit = static_cast(255); + constexpr int irregular_code_unit_value = static_cast>(irregular_code_unit); + assert(format(STR("{:b}"), irregular_code_unit) == format(STR("{:b}"), irregular_code_unit_value)); + assert(format(STR("{:B}"), irregular_code_unit) == format(STR("{:B}"), irregular_code_unit_value)); + assert(format(STR("{:d}"), irregular_code_unit) == format(STR("{:d}"), irregular_code_unit_value)); + assert(format(STR("{:o}"), irregular_code_unit) == format(STR("{:o}"), irregular_code_unit_value)); + assert(format(STR("{:x}"), irregular_code_unit) == format(STR("{:x}"), irregular_code_unit_value)); + assert(format(STR("{:X}"), irregular_code_unit) == format(STR("{:X}"), irregular_code_unit_value)); + assert(format(STR("{:+d}"), irregular_code_unit) == format(STR("{:+d}"), irregular_code_unit_value)); } template diff --git a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp index 3ab7a981fe..4b4c118f69 100644 --- a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp +++ b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp @@ -361,6 +361,12 @@ STATIC_ASSERT(__cpp_lib_format == 202207L); #error __cpp_lib_format is defined #endif +#if _HAS_CXX20 && defined(__cpp_lib_concepts) // TRANSITION, GH-395 +STATIC_ASSERT(__cpp_lib_format_uchar == 202311L); +#elif defined(__cpp_lib_format_uchar) +#error __cpp_lib_format_uchar is defined +#endif + #if _HAS_CXX23 && defined(__cpp_lib_concepts) // TRANSITION, GH-395 STATIC_ASSERT(__cpp_lib_formatters == 202302L); #elif defined(__cpp_lib_formatters)