From 4405b3403f75f93a9c8b3a0ceb2a7c79896a7694 Mon Sep 17 00:00:00 2001 From: Daniel Hannon Date: Sun, 14 Jun 2026 20:06:03 +0100 Subject: [PATCH 1/5] P3395R6 Fix encoding issues and add a formatter for std::error_code --- source/diagnostics.tex | 91 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 2 deletions(-) diff --git a/source/diagnostics.tex b/source/diagnostics.tex index d842475bd9..88b079fc32 100644 --- a/source/diagnostics.tex +++ b/source/diagnostics.tex @@ -764,6 +764,9 @@ constexpr bool @\libglobal{is_error_code_enum_v}@ = is_error_code_enum::value; template constexpr bool @\libglobal{is_error_condition_enum_v}@ = is_error_condition_enum::value; + + // \ref{system.error.fmt}, formatter + template struct formatter; } \end{codeblock} @@ -836,7 +839,7 @@ \begin{itemdescr} \pnum \returns -A string naming the error category. +A string in the ordinary literal encoding naming the error category. \end{itemdescr} \indexlibrarymember{default_error_condition}{error_category}% @@ -880,7 +883,8 @@ \begin{itemdescr} \pnum \returns -A string that describes the error condition denoted by \tcode{ev}. +A string of multibyte characters in the execution character set that describes the error condition +denoted by \tcode{ev}. \end{itemdescr} \rSec3[syserr.errcat.nonvirtuals]{Non-virtual members} @@ -1235,6 +1239,89 @@ Equivalent to: \tcode{return os << ec.category().name() << ':' << ec.value();} \end{itemdescr} +\rSec3[system.error.fmt]{Formatting} +\pnum +\begin{codeblock} +template struct formatter { + constexpr void set_debug_format(); + + constexpr typename basic_format_parse_context::iterator + parse(basic_format_parse_context& ctx); + + template + typename basic_format_context::iterator + format(const error_code& ec, basic_format_context& ctx) const; +}; +\end{codeblock} + +\pnum +\begin{itemdecl} +constexpr void set_debug_format(); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Modifies the state of the \tcode{formatter} to be as if the +\defnx{error-code-format-spec}{error-code-format-spec!syserr err fmt} passed by the +last call to \tcode{parse} contained the \tcode{?} option. +\end{itemdescr} + +\pnum +\begin{itemdecl} +constexpr typename basic_format_parse_context::iterator + parse(basic_format_parse_context& ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Parses the format specifier as a \defnx{error-code-format-spec}{error-code-format-spec!syserr err fmt} +and stores the parsed specifiers in \tcode{*this}. + +\begin{ncbnf} +\fmtnontermdef{error-code-format-spec}\br + \opt{fill-and-align} \opt{width} \opt{\tcode{?}} \opt{\tcode{s}} +\end{ncbnf} + +where the productions and \defnx{width}{width!format string} are described in\iref{format.string} + +\pnum +\returns +An iterator past the end of the \defnx{error-code-format-spec}{error-code-format-spec!syserr err fmt}. +\end{itemdescr} + +\pnum +\begin{itemdecl} +template + typename basic_format_context::iterator + format(const error_code& ec, basic_format_context& ctx) const; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If the \tcode{s} option is used, then: +\begin{itemize} +\item If \tcode{charT} is \tcode{char} and the ordinary literal encoding is UTF-8, let + \tcode{msg} be \tcode{ec.message()} transcoded to UTF-8 with maximal subparts of ill-formed + subsequences substituted with \unicode{fffd}{replacement character} per the Unicode Standard, Chapter + 3.9 \unicode{fffd} Substitution in Conversion. +\item Otherwise, let \tcode{msg} be \tcode{ec.message()} transcoded to an implementation-defined encoding. +\end{itemize} + +\pnum +Otherwise, let \tcode{msg} be \tcode{std::format("{}:{}", ec.category().name(), ec.value())}. + +\pnum +If the \tcode{?} option is used then \tcode{msg} is formatted as an escaped string(\iref{format.string.escaped}). +Writes \tcode{msg} into \tcode{ctx.out()}, adjusted according to the \defnx{error-code-format-spec}{error-code-format-spec!syserr err fmt}. + +\pnum +\returns +An iterator past the end of the output range. +\end{itemdescr} + \rSec2[syserr.errcondition]{Class \tcode{error_condition}} From 84ceb13e0eba63daf4fc497009758b86f7e46d1d Mon Sep 17 00:00:00 2001 From: Daniel Hannon Date: Sat, 20 Jun 2026 15:19:02 +0100 Subject: [PATCH 2/5] fixup: apply feedback --- source/diagnostics.tex | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/source/diagnostics.tex b/source/diagnostics.tex index 88b079fc32..94812b55ff 100644 --- a/source/diagnostics.tex +++ b/source/diagnostics.tex @@ -765,7 +765,7 @@ template constexpr bool @\libglobal{is_error_condition_enum_v}@ = is_error_condition_enum::value; - // \ref{system.error.fmt}, formatter + // \ref{syserr.fmt}, formatter template struct formatter; } \end{codeblock} @@ -1239,8 +1239,9 @@ Equivalent to: \tcode{return os << ec.category().name() << ':' << ec.value();} \end{itemdescr} -\rSec3[system.error.fmt]{Formatting} +\rSec3[syserr.fmt]{Formatting} \pnum +\indexlibraryglobal{formatter}% \begin{codeblock} template struct formatter { constexpr void set_debug_format(); @@ -1254,7 +1255,7 @@ }; \end{codeblock} -\pnum +\indexlibrarymember{set_debug_format}{formatter}% \begin{itemdecl} constexpr void set_debug_format(); \end{itemdecl} @@ -1263,11 +1264,11 @@ \pnum \effects Modifies the state of the \tcode{formatter} to be as if the -\defnx{error-code-format-spec}{error-code-format-spec!syserr err fmt} passed by the +\fmtgrammarterm{error-code-format-spec} passed by the last call to \tcode{parse} contained the \tcode{?} option. \end{itemdescr} -\pnum +\indexlibrarymember{parse}{formatter}% \begin{itemdecl} constexpr typename basic_format_parse_context::iterator parse(basic_format_parse_context& ctx); @@ -1276,7 +1277,7 @@ \begin{itemdescr} \pnum \effects -Parses the format specifier as a \defnx{error-code-format-spec}{error-code-format-spec!syserr err fmt} +Parses the format specifier as a \fmtgrammarterm{error-code-format-spec} and stores the parsed specifiers in \tcode{*this}. \begin{ncbnf} @@ -1284,14 +1285,15 @@ \opt{fill-and-align} \opt{width} \opt{\tcode{?}} \opt{\tcode{s}} \end{ncbnf} -where the productions and \defnx{width}{width!format string} are described in\iref{format.string} +where the productions and \fmtgrammarterm{fill-and-align} and \fmtgrammarterm{width} are +described in\iref{format.string} \pnum \returns -An iterator past the end of the \defnx{error-code-format-spec}{error-code-format-spec!syserr err fmt}. +An iterator past the end of the \fmtgrammarterm{error-code-format-spec}. \end{itemdescr} -\pnum +\indexlibrarymember{format}{formatter}% \begin{itemdecl} template typename basic_format_context::iterator @@ -1303,11 +1305,14 @@ \effects If the \tcode{s} option is used, then: \begin{itemize} -\item If \tcode{charT} is \tcode{char} and the ordinary literal encoding is UTF-8, let - \tcode{msg} be \tcode{ec.message()} transcoded to UTF-8 with maximal subparts of ill-formed - subsequences substituted with \unicode{fffd}{replacement character} per the Unicode Standard, Chapter - 3.9 \unicode{fffd} Substitution in Conversion. -\item Otherwise, let \tcode{msg} be \tcode{ec.message()} transcoded to an implementation-defined encoding. +\item +If \tcode{charT} is \tcode{char} and the ordinary literal encoding is UTF-8, +let \tcode{msg} be \tcode{ec.message()} transcoded to UTF-8 +with maximal subparts of ill-formed subsequences substituted with \unicode{fffd}{replacement character} +per the Unicode Standard, Chapter 3.9 \unicode{fffd} Substitution in Conversion. +\item +Otherwise, let \tcode{msg} be \tcode{ec.message()} +transcoded to an implementation-defined encoding. \end{itemize} \pnum @@ -1315,7 +1320,7 @@ \pnum If the \tcode{?} option is used then \tcode{msg} is formatted as an escaped string(\iref{format.string.escaped}). -Writes \tcode{msg} into \tcode{ctx.out()}, adjusted according to the \defnx{error-code-format-spec}{error-code-format-spec!syserr err fmt}. +Writes \tcode{msg} into \tcode{ctx.out()}, adjusted according to the \fmtgrammarterm{error-code-format-spec}. \pnum \returns From 3670a2c941d329f67550d300492e1882ba17f967 Mon Sep 17 00:00:00 2001 From: Daniel Hannon Date: Sat, 20 Jun 2026 15:21:05 +0100 Subject: [PATCH 3/5] fixup: missing puncuation --- source/diagnostics.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/diagnostics.tex b/source/diagnostics.tex index 94812b55ff..82dfabeb02 100644 --- a/source/diagnostics.tex +++ b/source/diagnostics.tex @@ -1286,7 +1286,7 @@ \end{ncbnf} where the productions and \fmtgrammarterm{fill-and-align} and \fmtgrammarterm{width} are -described in\iref{format.string} +described in\iref{format.string}. \pnum \returns From ab3fc5dd81828b592f974970f1b3368b3ca04369 Mon Sep 17 00:00:00 2001 From: Daniel Hannon Date: Sun, 21 Jun 2026 13:01:33 +0100 Subject: [PATCH 4/5] fixup: idea for multi-paragraph effects block --- source/diagnostics.tex | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/source/diagnostics.tex b/source/diagnostics.tex index 82dfabeb02..e5c848e871 100644 --- a/source/diagnostics.tex +++ b/source/diagnostics.tex @@ -1286,7 +1286,7 @@ \end{ncbnf} where the productions and \fmtgrammarterm{fill-and-align} and \fmtgrammarterm{width} are -described in\iref{format.string}. +described in \ref{format.string}. \pnum \returns @@ -1303,24 +1303,28 @@ \begin{itemdescr} \pnum \effects +\begin{itemize} +\item If the \tcode{s} option is used, then: \begin{itemize} \item If \tcode{charT} is \tcode{char} and the ordinary literal encoding is UTF-8, -let \tcode{msg} be \tcode{ec.message()} transcoded to UTF-8 +then let \tcode{msg} be \tcode{ec.message()} transcoded to UTF-8 with maximal subparts of ill-formed subsequences substituted with \unicode{fffd}{replacement character} -per the Unicode Standard, Chapter 3.9 \unicode{fffd} Substitution in Conversion. +per the Unicode Standard, Chapter 3.9 \unicode{fffd} Substi\-tution in Conversion. \item Otherwise, let \tcode{msg} be \tcode{ec.message()} transcoded to an implementation-defined encoding. \end{itemize} -\pnum +\item Otherwise, let \tcode{msg} be \tcode{std::format("{}:{}", ec.category().name(), ec.value())}. -\pnum -If the \tcode{?} option is used then \tcode{msg} is formatted as an escaped string(\iref{format.string.escaped}). +\item +If the \tcode{?} option is used +then \tcode{msg} is formatted as an escaped string(\iref{format.string.escaped}). Writes \tcode{msg} into \tcode{ctx.out()}, adjusted according to the \fmtgrammarterm{error-code-format-spec}. +\end{itemize} \pnum \returns From 9cadf69ffc02c40c4acfe1b8116137c4d899e339 Mon Sep 17 00:00:00 2001 From: Daniel Hannon Date: Tue, 23 Jun 2026 22:29:27 +0100 Subject: [PATCH 5/5] fixup: apply suggested changes --- source/diagnostics.tex | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/diagnostics.tex b/source/diagnostics.tex index e5c848e871..1ee40cad6d 100644 --- a/source/diagnostics.tex +++ b/source/diagnostics.tex @@ -883,8 +883,8 @@ \begin{itemdescr} \pnum \returns -A string of multibyte characters in the execution character set that describes the error condition -denoted by \tcode{ev}. +A string of multibyte characters in the execution character set +that describes the error condition denoted by \tcode{ev}. \end{itemdescr} \rSec3[syserr.errcat.nonvirtuals]{Non-virtual members} @@ -1264,7 +1264,7 @@ \pnum \effects Modifies the state of the \tcode{formatter} to be as if the -\fmtgrammarterm{error-code-format-spec} passed by the +\fmtgrammarterm{error-code-format-spec} parsed by the last call to \tcode{parse} contained the \tcode{?} option. \end{itemdescr} @@ -1277,7 +1277,7 @@ \begin{itemdescr} \pnum \effects -Parses the format specifier as a \fmtgrammarterm{error-code-format-spec} +Parses the format specifier as an \fmtgrammarterm{error-code-format-spec} and stores the parsed specifiers in \tcode{*this}. \begin{ncbnf} @@ -1285,7 +1285,7 @@ \opt{fill-and-align} \opt{width} \opt{\tcode{?}} \opt{\tcode{s}} \end{ncbnf} -where the productions and \fmtgrammarterm{fill-and-align} and \fmtgrammarterm{width} are +where the productions \fmtgrammarterm{fill-and-align} and \fmtgrammarterm{width} are described in \ref{format.string}. \pnum @@ -1322,7 +1322,7 @@ \item If the \tcode{?} option is used -then \tcode{msg} is formatted as an escaped string(\iref{format.string.escaped}). +then \tcode{msg} is formatted as an escaped string\iref{format.string.escaped}. Writes \tcode{msg} into \tcode{ctx.out()}, adjusted according to the \fmtgrammarterm{error-code-format-spec}. \end{itemize}