From 4f020f60b89d2033b8b8b11995b9aa18931ec8da Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 09:10:33 -0700 Subject: [PATCH] P3107R5 Permit an efficient implementation of std::print Editorial note: * [print.fun] Moved the "See also" to the end of the paragraph. --- source/iostreams.tex | 59 ++++++++++++++++++++++++++++++++++++++------ source/support.tex | 2 +- source/utilities.tex | 29 ++++++++++++++++++++++ 3 files changed, 81 insertions(+), 9 deletions(-) diff --git a/source/iostreams.tex b/source/iostreams.tex index a435d3fc30..cec7c2ebb5 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -7706,13 +7706,19 @@ \begin{itemdescr} \pnum \effects +Let \tcode{locksafe} be +\tcode{(enable_nonlocking_formatter_optimization> \&\& ...)}. If the ordinary literal encoding\iref{lex.charset} is UTF-8, equivalent to: \begin{codeblock} -vprint_unicode(stream, fmt.@\exposid{str}@, make_format_args(args...)); +locksafe + ? vprint_unicode_locking(stream, fmt.str, make_format_args(args...)) + : vprint_unicode(stream, fmt.str, make_format_args(args...)); \end{codeblock} Otherwise, equivalent to: \begin{codeblock} -vprint_nonunicode(stream, fmt.@\exposid{str}@, make_format_args(args...)); +locksafe + ? vprint_nonunicode_locking(stream, fmt.str, make_format_args(args...)) + : vprint_nonunicode(stream, fmt.str, make_format_args(args...)); \end{codeblock} \end{itemdescr} @@ -7742,7 +7748,7 @@ \effects Equivalent to: \begin{codeblock} -print(stream, "{}\n", format(fmt, std::forward(args)...)); +print(stream, runtime_format(string(fmt.get()) + '\n'), std::forward(args)...); \end{codeblock} \end{itemdescr} @@ -7765,6 +7771,21 @@ void vprint_unicode(FILE* stream, string_view fmt, format_args args); \end{itemdecl} +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +string out = vformat(fmt, args); +vprint_unicode_locking(stream, "{}", make_format_args(out)); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{vprint_unicode_locking}% +\begin{itemdecl} +void vprint_unicode_locking(FILE* stream, string_view fmt, format_args args); +\end{itemdecl} + \begin{itemdescr} \pnum \expects @@ -7772,10 +7793,10 @@ \pnum \effects -The function initializes an automatic variable via -\begin{codeblock} -string out = vformat(fmt, args); -\end{codeblock} +Locks \tcode{stream}. +Let \tcode{out} denote the character representation of +formatting arguments provided by \tcode{args} +formatted according to specifications given in \tcode{fmt}. If \tcode{stream} refers to a terminal capable of displaying Unicode, writes \tcode{out} to the terminal using the native Unicode API; if \tcode{out} contains invalid code units, @@ -7785,6 +7806,10 @@ Otherwise writes \tcode{out} to \tcode{stream} unchanged. If the native Unicode API is used, the function flushes \tcode{stream} before writing \tcode{out}. +Unconditionally unlocks \tcode{stream} on function exit. + +\xrefc{7.21.2}. + \begin{note} On POSIX and Windows, \tcode{stream} referring to a terminal means that, respectively, @@ -7829,6 +7854,21 @@ void vprint_nonunicode(FILE* stream, string_view fmt, format_args args); \end{itemdecl} +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +string out = vformat(fmt, args); +vprint_nonunicode_locking("{}", make_format_args(out)); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{vprint_nonunicode_locking}% +\begin{itemdecl} +void vprint_nonunicode_locking(FILE* stream, string_view fmt, format_args args); +\end{itemdecl} + \begin{itemdescr} \pnum \expects @@ -7836,7 +7876,10 @@ \pnum \effects -Writes the result of \tcode{vformat(fmt, args)} to \tcode{stream}. +While holding the lock on \tcode{stream}, +writes the character representation of +formatting arguments provided by \tcode{args} +formatted according to specifications given in \tcode{fmt} to \tcode{stream}. \pnum \throws diff --git a/source/support.tex b/source/support.tex index 8ddffc6635..3e88feb346 100644 --- a/source/support.tex +++ b/source/support.tex @@ -722,7 +722,7 @@ #define @\defnlibxname{cpp_lib_out_ptr}@ 202311L // freestanding, also in \libheader{memory} #define @\defnlibxname{cpp_lib_parallel_algorithm}@ 201603L // also in \libheader{algorithm}, \libheader{numeric} #define @\defnlibxname{cpp_lib_polymorphic_allocator}@ 201902L // also in \libheader{memory_resource} -#define @\defnlibxname{cpp_lib_print}@ 202207L // also in \libheader{print}, \libheader{ostream} +#define @\defnlibxname{cpp_lib_print}@ 202403L // also in \libheader{print}, \libheader{ostream} #define @\defnlibxname{cpp_lib_quoted_string_io}@ 201304L // also in \libheader{iomanip} #define @\defnlibxname{cpp_lib_ranges}@ 202302L // also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges} diff --git a/source/utilities.tex b/source/utilities.tex index 5c3845bb42..e5f8d8a4b7 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -15670,6 +15670,10 @@ // \ref{format.formatter}, formatter template struct formatter; + // \ref{format.formatter.locking}, formatter locking + template + constexpr bool enable_nonlocking_formatter_optimization = false; + // \ref{format.formattable}, concept \libconcept{formattable} template concept formattable = @\seebelow@; @@ -16913,6 +16917,24 @@ \\ \end{concepttable} +\rSec3[format.formatter.locking]{Formatter locking} + +\indexlibraryglobal{enable_nonlocking_formatter_optimization}% +\begin{itemdecl} +template + constexpr bool enable_nonlocking_formatter_optimization = false; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +Pursuant to \ref{namespace.std}, +users may specialize \tcode{enable_nonlocking_formatter_optimization} for +cv-unqualified program-defined types. +Such specializations shall be usable in constant expressions\iref{expr.const} +and have type \tcode{const bool}. +\end{itemdescr} + \rSec3[format.formattable]{Concept \cname{formattable}} \pnum @@ -17021,6 +17043,13 @@ interpret the format specification as a \fmtgrammarterm{std-format-spec} as described in \ref{format.string.std}. +In addition, +for each type \tcode{T} for which +a \tcode{formatter} specialization is provided above, +each of the headers provides the following specialization: +\begin{codeblock} +template<> inline constexpr bool enable_nonlocking_formatter_optimization = true; +\end{codeblock} \begin{note} Specializations such as \tcode{formatter} and \tcode{formatter}