Skip to content

Commit 4f020f6

Browse files
burblebeetkoeppe
authored andcommitted
P3107R5 Permit an efficient implementation of std::print
Editorial note: * [print.fun] Moved the "See also" to the end of the paragraph.
1 parent d789e95 commit 4f020f6

File tree

3 files changed

+81
-9
lines changed

3 files changed

+81
-9
lines changed

source/iostreams.tex

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7706,13 +7706,19 @@
77067706
\begin{itemdescr}
77077707
\pnum
77087708
\effects
7709+
Let \tcode{locksafe} be
7710+
\tcode{(enable_nonlocking_formatter_optimization<remove_cvref_t<Args>> \&\& ...)}.
77097711
If the ordinary literal encoding\iref{lex.charset} is UTF-8, equivalent to:
77107712
\begin{codeblock}
7711-
vprint_unicode(stream, fmt.@\exposid{str}@, make_format_args(args...));
7713+
locksafe
7714+
? vprint_unicode_locking(stream, fmt.str, make_format_args(args...))
7715+
: vprint_unicode(stream, fmt.str, make_format_args(args...));
77127716
\end{codeblock}
77137717
Otherwise, equivalent to:
77147718
\begin{codeblock}
7715-
vprint_nonunicode(stream, fmt.@\exposid{str}@, make_format_args(args...));
7719+
locksafe
7720+
? vprint_nonunicode_locking(stream, fmt.str, make_format_args(args...))
7721+
: vprint_nonunicode(stream, fmt.str, make_format_args(args...));
77167722
\end{codeblock}
77177723
\end{itemdescr}
77187724

@@ -7742,7 +7748,7 @@
77427748
\effects
77437749
Equivalent to:
77447750
\begin{codeblock}
7745-
print(stream, "{}\n", format(fmt, std::forward<Args>(args)...));
7751+
print(stream, runtime_format(string(fmt.get()) + '\n'), std::forward<Args>(args)...);
77467752
\end{codeblock}
77477753
\end{itemdescr}
77487754

@@ -7765,17 +7771,32 @@
77657771
void vprint_unicode(FILE* stream, string_view fmt, format_args args);
77667772
\end{itemdecl}
77677773

7774+
\begin{itemdescr}
7775+
\pnum
7776+
\effects
7777+
Equivalent to:
7778+
\begin{codeblock}
7779+
string out = vformat(fmt, args);
7780+
vprint_unicode_locking(stream, "{}", make_format_args(out));
7781+
\end{codeblock}
7782+
\end{itemdescr}
7783+
7784+
\indexlibraryglobal{vprint_unicode_locking}%
7785+
\begin{itemdecl}
7786+
void vprint_unicode_locking(FILE* stream, string_view fmt, format_args args);
7787+
\end{itemdecl}
7788+
77687789
\begin{itemdescr}
77697790
\pnum
77707791
\expects
77717792
\tcode{stream} is a valid pointer to an output C stream.
77727793

77737794
\pnum
77747795
\effects
7775-
The function initializes an automatic variable via
7776-
\begin{codeblock}
7777-
string out = vformat(fmt, args);
7778-
\end{codeblock}
7796+
Locks \tcode{stream}.
7797+
Let \tcode{out} denote the character representation of
7798+
formatting arguments provided by \tcode{args}
7799+
formatted according to specifications given in \tcode{fmt}.
77797800
If \tcode{stream} refers to a terminal capable of displaying Unicode,
77807801
writes \tcode{out} to the terminal using the native Unicode API;
77817802
if \tcode{out} contains invalid code units,
@@ -7785,6 +7806,10 @@
77857806
Otherwise writes \tcode{out} to \tcode{stream} unchanged.
77867807
If the native Unicode API is used,
77877808
the function flushes \tcode{stream} before writing \tcode{out}.
7809+
Unconditionally unlocks \tcode{stream} on function exit.
7810+
7811+
\xrefc{7.21.2}.
7812+
77887813
\begin{note}
77897814
On POSIX and Windows, \tcode{stream} referring to a terminal means that,
77907815
respectively,
@@ -7829,14 +7854,32 @@
78297854
void vprint_nonunicode(FILE* stream, string_view fmt, format_args args);
78307855
\end{itemdecl}
78317856

7857+
\begin{itemdescr}
7858+
\pnum
7859+
\effects
7860+
Equivalent to:
7861+
\begin{codeblock}
7862+
string out = vformat(fmt, args);
7863+
vprint_nonunicode_locking("{}", make_format_args(out));
7864+
\end{codeblock}
7865+
\end{itemdescr}
7866+
7867+
\indexlibraryglobal{vprint_nonunicode_locking}%
7868+
\begin{itemdecl}
7869+
void vprint_nonunicode_locking(FILE* stream, string_view fmt, format_args args);
7870+
\end{itemdecl}
7871+
78327872
\begin{itemdescr}
78337873
\pnum
78347874
\expects
78357875
\tcode{stream} is a valid pointer to an output C stream.
78367876

78377877
\pnum
78387878
\effects
7839-
Writes the result of \tcode{vformat(fmt, args)} to \tcode{stream}.
7879+
While holding the lock on \tcode{stream},
7880+
writes the character representation of
7881+
formatting arguments provided by \tcode{args}
7882+
formatted according to specifications given in \tcode{fmt} to \tcode{stream}.
78407883

78417884
\pnum
78427885
\throws

source/support.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,7 @@
722722
#define @\defnlibxname{cpp_lib_out_ptr}@ 202311L // freestanding, also in \libheader{memory}
723723
#define @\defnlibxname{cpp_lib_parallel_algorithm}@ 201603L // also in \libheader{algorithm}, \libheader{numeric}
724724
#define @\defnlibxname{cpp_lib_polymorphic_allocator}@ 201902L // also in \libheader{memory_resource}
725-
#define @\defnlibxname{cpp_lib_print}@ 202207L // also in \libheader{print}, \libheader{ostream}
725+
#define @\defnlibxname{cpp_lib_print}@ 202403L // also in \libheader{print}, \libheader{ostream}
726726
#define @\defnlibxname{cpp_lib_quoted_string_io}@ 201304L // also in \libheader{iomanip}
727727
#define @\defnlibxname{cpp_lib_ranges}@ 202302L
728728
// also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges}

source/utilities.tex

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15670,6 +15670,10 @@
1567015670
// \ref{format.formatter}, formatter
1567115671
template<class T, class charT = char> struct formatter;
1567215672

15673+
// \ref{format.formatter.locking}, formatter locking
15674+
template<class T>
15675+
constexpr bool enable_nonlocking_formatter_optimization = false;
15676+
1567315677
// \ref{format.formattable}, concept \libconcept{formattable}
1567415678
template<class T, class charT>
1567515679
concept formattable = @\seebelow@;
@@ -16913,6 +16917,24 @@
1691316917
\\
1691416918
\end{concepttable}
1691516919

16920+
\rSec3[format.formatter.locking]{Formatter locking}
16921+
16922+
\indexlibraryglobal{enable_nonlocking_formatter_optimization}%
16923+
\begin{itemdecl}
16924+
template<class T>
16925+
constexpr bool enable_nonlocking_formatter_optimization = false;
16926+
\end{itemdecl}
16927+
16928+
\begin{itemdescr}
16929+
\pnum
16930+
\remarks
16931+
Pursuant to \ref{namespace.std},
16932+
users may specialize \tcode{enable_nonlocking_formatter_optimization} for
16933+
cv-unqualified program-defined types.
16934+
Such specializations shall be usable in constant expressions\iref{expr.const}
16935+
and have type \tcode{const bool}.
16936+
\end{itemdescr}
16937+
1691616938
\rSec3[format.formattable]{Concept \cname{formattable}}
1691716939

1691816940
\pnum
@@ -17021,6 +17043,13 @@
1702117043
interpret the format specification
1702217044
as a \fmtgrammarterm{std-format-spec}
1702317045
as described in \ref{format.string.std}.
17046+
In addition,
17047+
for each type \tcode{T} for which
17048+
a \tcode{formatter} specialization is provided above,
17049+
each of the headers provides the following specialization:
17050+
\begin{codeblock}
17051+
template<> inline constexpr bool enable_nonlocking_formatter_optimization<T> = true;
17052+
\end{codeblock}
1702417053
\begin{note}
1702517054
Specializations such as \tcode{formatter<wchar_t, char>}
1702617055
and \tcode{formatter<const char*, wchar_t>}

0 commit comments

Comments
 (0)