@@ -853,13 +853,13 @@ _NODISCARD constexpr bool _Is_execution_charset_self_synchronizing() {
853
853
#endif // ^^^ EDG workaround ^^^
854
854
}
855
855
856
- inline constexpr char32_t _Width_estimate_intervals[] = { // Per N4885 [format.string.std]/11
856
+ inline constexpr char32_t _Width_estimate_intervals[] = { // Per N4928 [format.string.std]/12
857
857
0x1100u, 0x1160u, 0x2329u, 0x232Bu, 0x2E80u, 0x303Fu, 0x3040u, 0xA4D0u, 0xAC00u, 0xD7A4u, 0xF900u, 0xFB00u, 0xFE10u,
858
858
0xFE1Au, 0xFE30u, 0xFE70u, 0xFF00u, 0xFF61u, 0xFFE0u, 0xFFE7u, 0x1F300u, 0x1F650u, 0x1F900u, 0x1FA00u, 0x20000u,
859
859
0x2FFFEu, 0x30000u, 0x3FFFEu};
860
860
861
861
_NODISCARD constexpr int _Unicode_width_estimate(const char32_t _Ch) noexcept {
862
- // Computes the width estimation for Unicode characters from N4885 [format.string.std]/11
862
+ // Computes the width estimation for Unicode characters from N4928 [format.string.std]/12
863
863
int _Result = 1;
864
864
for (const auto& _Bound : _Width_estimate_intervals) {
865
865
if (_Ch < _Bound) {
@@ -1731,13 +1731,13 @@ struct _Format_arg_traits {
1731
1731
using _Char_type = typename _Context::char_type;
1732
1732
1733
1733
// These overloads mirror the exposition-only single-argument constructor
1734
- // set of basic_format_arg (N4885 [format.arg]). They determine the mapping
1734
+ // set of basic_format_arg (N4928 [format.arg]). They determine the mapping
1735
1735
// from "raw" to "erased" argument type for _Format_arg_store.
1736
1736
template <_Has_formatter<_Context> _Ty>
1737
1737
static auto _Phony_basic_format_arg_constructor(_Ty&&) {
1738
1738
// per the proposed resolution of LWG-3631
1739
1739
using _Td = remove_cvref_t<_Ty>;
1740
- // See N4885 [format.arg]/5
1740
+ // See N4928 [format.arg]/5
1741
1741
if constexpr (is_same_v<_Td, bool>) {
1742
1742
return bool{};
1743
1743
} else if constexpr (is_same_v<_Td, _Char_type>) {
@@ -1878,7 +1878,15 @@ private:
1878
1878
_Arg_type = _Basic_format_arg_type::_Custom_type;
1879
1879
}
1880
1880
1881
- _Store_impl<_Erased_type>(_Arg_index, _Arg_type, static_cast<_Erased_type>(_Val));
1881
+ #if !_HAS_CXX23
1882
+ // Workaround towards N4928 [format.arg]/9 and /10 in C++20
1883
+ if constexpr (is_same_v<_Erased_type, basic_string_view<_CharType>>) {
1884
+ _Store_impl<_Erased_type>(_Arg_index, _Arg_type, _Erased_type{_Val.data(), _Val.size()});
1885
+ } else
1886
+ #endif // !_HAS_CXX23
1887
+ {
1888
+ _Store_impl<_Erased_type>(_Arg_index, _Arg_type, static_cast<_Erased_type>(_Val));
1889
+ }
1882
1890
}
1883
1891
1884
1892
public:
@@ -3268,7 +3276,7 @@ struct _Format_handler {
3268
3276
};
3269
3277
3270
3278
// Generic formatter definition, the deleted default constructor
3271
- // makes it "disabled" as per N4885 [format.formatter.spec]/5
3279
+ // makes it "disabled" as per N4928 [format.formatter.spec]/5
3272
3280
_EXPORT_STD template <class _Ty, class _CharT>
3273
3281
struct formatter {
3274
3282
formatter() = delete;
@@ -3397,15 +3405,15 @@ _EXPORT_STD template <class _Context = format_context, class... _Args>
3397
3405
_NODISCARD auto make_format_args(_Args&&... _Vals) {
3398
3406
static_assert((_Has_formatter<_Args, _Context> && ...),
3399
3407
"Cannot format an argument. To make type T formattable, provide a formatter<T> specialization. "
3400
- "See N4917 [format.arg.store]/2 and [formatter.requirements].");
3408
+ "See N4928 [format.arg.store]/2 and [formatter.requirements].");
3401
3409
return _Format_arg_store<_Context, _Args...>{_Vals...};
3402
3410
}
3403
3411
3404
3412
_EXPORT_STD template <class... _Args>
3405
3413
_NODISCARD auto make_wformat_args(_Args&&... _Vals) {
3406
3414
static_assert((_Has_formatter<_Args, wformat_context> && ...),
3407
3415
"Cannot format an argument. To make type T formattable, provide a formatter<T> specialization. "
3408
- "See N4917 [format.arg.store]/2 and [formatter.requirements].");
3416
+ "See N4928 [format.arg.store]/2 and [formatter.requirements].");
3409
3417
return _Format_arg_store<wformat_context, _Args...>{_Vals...};
3410
3418
}
3411
3419
0 commit comments