From 72a78d91d5bd859f3e9a2e207c4ee482fa8d76f2 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Fri, 29 Jul 2022 14:22:47 -0700 Subject: [PATCH] P2093R14 Formatted output --- source/back.tex | 5 + source/iostreams.tex | 282 +++++++++++++++++++++++++++++++++++++++++++ source/lib-intro.tex | 1 + source/support.tex | 1 + 4 files changed, 289 insertions(+) diff --git a/source/back.tex b/source/back.tex index 60a20e7d51..dda5569dc8 100644 --- a/source/back.tex +++ b/source/back.tex @@ -31,6 +31,11 @@ \chapter{Bibliography} Edited by Mark Davis. Revision 33; issued for Unicode 13.0.0. 2020-02-13 [viewed 2021-06-08]. Available from: \url{https://www.unicode.org/reports/tr31/tr31-33.html} +\item + The Unicode Standard Version 14.0, + \doccite{Core Specification}. + Unicode Consortium, ISBN 978-1-936213-29-0, copyright \copyright 2021 Unicode, Inc. + Available from: \url{https://www.unicode.org/versions/Unicode14.0.0/UnicodeStandard-14.0.pdf} \item IANA Time Zone Database. Available from: \url{https://www.iana.org/time-zones} diff --git a/source/iostreams.tex b/source/iostreams.tex index 51e6fb05af..7425917019 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -4162,6 +4162,15 @@ template Ostream&& operator<<(Ostream&& os, const T& x); + + // \ref{ostream.formatted.print}, print functions + template + void print(ostream& os, @\exposid{format-string}@ fmt, Args&&... args); + template + void println(ostream& os, @\exposid{format-string}@ fmt, Args&&... args); + + void vprint_unicode(ostream& os, string_view fmt, format_args args); + void vprint_nonunicode(ostream& os, string_view fmt, format_args args); } \end{codeblock} @@ -4203,6 +4212,30 @@ } \end{codeblock} +\rSec2[print.syn]{Header \tcode{} synopsis} + +\indexheader{print}% +\begin{codeblock} +namespace std { + // \ref{print.fun}, print functions + template + void print(@\exposid{format-string}@ fmt, Args&&... args); + template + void print(FILE* stream, @\exposid{format-string}@ fmt, Args&&... args); + + template + void println(@\exposid{format-string}@ fmt, Args&&... args); + template + void println(FILE* stream, @\exposid{format-string}@ fmt, Args&&... args); + + void vprint_unicode(string_view fmt, format_args args); + void vprint_unicode(FILE* stream, string_view fmt, format_args args); + + void vprint_nonunicode(string_view fmt, format_args args); + void vprint_nonunicode(FILE* stream, string_view fmt, format_args args); +} +\end{codeblock} + \rSec2[input.streams]{Input streams} \rSec3[input.streams.general]{General} @@ -6767,6 +6800,92 @@ \tcode{out}. \end{itemdescr} +\rSec4[ostream.formatted.print]{Print} + +\indexlibraryglobal{print}% +\begin{itemdecl} +template + void print(ostream& os, @\exposid{format-string}@ fmt, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If the ordinary literal encoding\iref{lex.charset} is UTF-8, equivalent to: +\begin{codeblock} +vprint_unicode(os, fmt.@\exposid{str}@, make_format_args(std::forward(args)...)); +\end{codeblock} +Otherwise, equivalent to: +\begin{codeblock} +vprint_nonunicode(os, fmt.@\exposid{str}@, make_format_args(std::forward(args)...)); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{println}% +\begin{itemdecl} +template + void println(ostream& os, @\exposid{format-string}@ fmt, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +print(os, "{}\n", format(fmt, std::forward(args)...)); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{vprint_unicode}% +\indexlibraryglobal{vprint_nonunicode}% +\begin{itemdecl} +void vprint_unicode(ostream& os, string_view fmt, format_args args); +void vprint_nonunicode(ostream& os, string_view fmt, format_args args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Behaves as a formatted output function\iref{ostream.formatted.reqmts} +of \tcode{os}, except that: +\begin{itemize} +\item +failure to generate output is reported as specified below, and +\item +any exception thrown by the call to \tcode{vformat} is propagated +without regard to the value of \tcode{os.exceptions()} and +without turning on \tcode{ios_base::badbit} in the error state of \tcode{os}. +\end{itemize} +After constructing a \tcode{sentry} object, +the function initializes an automatic variable via +\begin{codeblock} +string out = vformat(os.getloc(), fmt, args); +\end{codeblock} +If the function is \tcode{vprint_unicode} and +\tcode{os} is a stream that refers to a terminal capable of displaying Unicode +which is determined in an implementation-defined manner, +writes \tcode{out} to the terminal using the native Unicode API; +if \tcode{out} contains invalid code units, +\indextext{undefined}% +the behavior is undefined and +implementations are encouraged to diagnose it. +Otherwise (if \tcode{os} is not such a stream or +the function is \tcode{vprint_nonunicode}), +inserts the character sequence +\range{out.begin()}{out.end()} into \tcode{os}. +If writing to the terminal or inserting into \tcode{os} fails, +calls \tcode{os.setstate(ios_base::badbit)} +(which may throw \tcode{ios_base::failure}). + +\pnum +\recommended +For \tcode{vprint_unicode}, +if invoking the native Unicode API requires transcoding, +implementations should substitute invalid code units +with \unicode{fffd}{replacement character} per +The Unicode Standard Version 14.0 - Core Specification, Chapter 3.9. +\end{itemdescr} + \rSec3[ostream.unformatted]{Unformatted output functions} \pnum @@ -7573,6 +7692,169 @@ \end{itemize} \end{itemdescr} +\rSec2[print.fun]{Print functions} + +\indexlibraryglobal{print}% +\begin{itemdecl} +template + void print(@\exposid{format-string}@ fmt, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +print(stdout, fmt, std::forward(args)...); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{print}% +\begin{itemdecl} +template + void print(FILE* stream, @\exposid{format-string}@ fmt, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +If the ordinary literal encoding\iref{lex.charset} is UTF-8, equivalent to: +\begin{codeblock} +vprint_unicode(stream, fmt.@\exposid{str}@, make_format_args(std::forward(args)...)); +\end{codeblock} +Otherwise, equivalent to: +\begin{codeblock} +vprint_nonunicode(stream, fmt.@\exposid{str}@, make_format_args(std::forward(args)...)); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{println}% +\begin{itemdecl} +template + void println(@\exposid{format-string}@ fmt, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +println(stdout, fmt, std::forward(args)...); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{println}% +\begin{itemdecl} +template + void println(FILE* stream, @\exposid{format-string}@ fmt, Args&&... args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +print(stream, "{}\n", format(fmt, std::forward(args)...)); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{vprint_unicode}% +\begin{itemdecl} +void vprint_unicode(string_view fmt, format_args args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +vprint_unicode(stdout, fmt, args); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{vprint_unicode}% +\begin{itemdecl} +void vprint_unicode(FILE* stream, string_view fmt, format_args args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{stream} is a valid pointer to an output C stream. + +\pnum +\effects +The function initializes an automatic variable via +\begin{codeblock} +string out = vformat(fmt, args); +\end{codeblock} +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, +\indextext{undefined}% +the behavior is undefined and +implementations are encouraged to diagnose it. +Otherwise writes \tcode{out} to \tcode{stream} unchanged. +\begin{note} +On POSIX and Windows, \tcode{stream} referring to a terminal means that, +respectively, +\tcode{isatty(fileno(\linebreak{}stream))} and +\tcode{GetConsoleMode(_get_osfhandle(_fileno(stream)), ...)} +return nonzero. +\end{note} +\begin{note} +On Windows, the native Unicode API is \tcode{WriteConsoleW}. +\end{note} + +\pnum +\throws +Any exception thrown by the call to \tcode{vformat}\iref{format.err.report}. +\tcode{system_error} if writing to the terminal or \tcode{stream} fails. +May throw \tcode{bad_alloc}. + +\pnum +\recommended +If invoking the native Unicode API requires transcoding, +implementations should substitute invalid code units +with \unicode{fffd}{replacement character} per +The Unicode Standard Version 14.0 - Core Specification, Chapter 3.9. +\end{itemdescr} + +\indexlibraryglobal{vprint_nonunicode}% +\begin{itemdecl} +void vprint_nonunicode(string_view fmt, format_args args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to: +\begin{codeblock} +vprint_nonunicode(stdout, fmt, args); +\end{codeblock} +\end{itemdescr} + +\indexlibraryglobal{vprint_nonunicode}% +\begin{itemdecl} +void vprint_nonunicode(FILE* stream, string_view fmt, format_args args); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\expects +\tcode{stream} is a valid pointer to an output C stream. + +\pnum +\effects +Writes the result of \tcode{vformat(fmt, args)} to \tcode{stream}. + +\pnum +\throws +Any exception thrown by the call to \tcode{vformat}\iref{format.err.report}. +\tcode{system_error} if writing to \tcode{stream} fails. +May throw \tcode{bad_alloc}. +\end{itemdescr} + \rSec1[string.streams]{String-based streams} \rSec2[sstream.syn]{Header \tcode{} synopsis} diff --git a/source/lib-intro.tex b/source/lib-intro.tex index d42071dc91..39dd9e1a7d 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -1109,6 +1109,7 @@ \tcode{} \\ \tcode{} \\ \tcode{} \\ +\tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ diff --git a/source/support.tex b/source/support.tex index 6cd1d6d08b..63e9abda05 100644 --- a/source/support.tex +++ b/source/support.tex @@ -672,6 +672,7 @@ #define @\defnlibxname{cpp_lib_out_ptr}@ 202106L // 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_quoted_string_io}@ 201304L // also in \libheader{iomanip} #define @\defnlibxname{cpp_lib_ranges}@ 202202L // also in \libheader{algorithm}, \libheader{functional}, \libheader{iterator}, \libheader{memory}, \libheader{ranges}