Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement P2909R4 Fix Formatting Of Code Units As Integers #4189

Merged
merged 1 commit into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions stl/inc/format
Original file line number Diff line number Diff line change
Expand Up @@ -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<remove_const_t<_Ty>, char> && is_same_v<_CharType, wchar_t>) {
return basic_format_arg(static_cast<_Erased_type>(static_cast<unsigned char>(_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));
}
}
Expand Down Expand Up @@ -2047,13 +2050,17 @@ private:
_Arg_type = _Basic_format_arg_type::_Custom_type;
}

if constexpr (is_same_v<remove_const_t<remove_reference_t<_Ty>>, char> && is_same_v<_CharType, wchar_t>) {
_Store_impl<_Erased_type>(
_Arg_index, _Arg_type, static_cast<_Erased_type>(static_cast<unsigned char>(_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));
}
}
Expand Down Expand Up @@ -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<make_unsigned_t<_CharT>>(_Value), _Specs, _Locale);
}

_STL_INTERNAL_CHECK(_Specs._Precision == -1);
Expand Down
2 changes: 2 additions & 0 deletions stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)

Expand Down
11 changes: 11 additions & 0 deletions tests/std/tests/P0645R10_text_formatting_formatting/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<charT>(255);
constexpr int irregular_code_unit_value = static_cast<make_unsigned_t<charT>>(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 <class charT, class Float>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down