libstdc++
print
Go to the documentation of this file.
1// <print> Print functions -*- C++ -*-
2
3// Copyright The GNU Toolchain Authors.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file include/print
26 * This is a Standard C++ Library header.
27 */
28
29#ifndef _GLIBCXX_PRINT
30#define _GLIBCXX_PRINT 1
31
32#ifdef _GLIBCXX_SYSHDR
33#pragma GCC system_header
34#endif
35
36#include <bits/requires_hosted.h> // for std::format
37
38#define __glibcxx_want_print
39#include <bits/version.h>
40
41#ifdef __cpp_lib_print // C++ >= 23
42
43#include <format> // format_args (TODO: move to bits/formatfwd.h?)
44#include <cstdio> // FILE, EOF, putc
45#include <cerrno> // EACCES, EIO
46#include <bits/functexcept.h> // __throw_system_error
47
48#ifdef _WIN32
49# include <system_error>
50#endif
51
52#ifndef _GLIBCXX_NO_INLINE_PRINT
53# include <bits/print.h>
54#endif
55
56namespace std _GLIBCXX_VISIBILITY(default)
57{
58_GLIBCXX_BEGIN_NAMESPACE_VERSION
59
60 void
61 vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args);
62
63 void
64 vprint_nonunicode_buffered(FILE* __stream, string_view __fmt,
65 format_args __args);
66
67 void
68 vprint_unicode(FILE* __stream, string_view __fmt, format_args __args);
69
70 void
71 vprint_unicode_buffered(FILE* __stream, string_view __fmt,
72 format_args __args);
73
74 void
75 vprint_unicode_buffered(string_view __fmt, format_args __args);
76
77 void
78 vprint_nonunicode_buffered(string_view __fmt, format_args __args);
79
80 template<typename... _Args>
81 inline void
82 print(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args)
83 {
84 constexpr bool __locksafe =
85 (enable_nonlocking_formatter_optimization<remove_cvref_t<_Args>> && ...);
86
87 auto __fmtargs = std::make_format_args(__args...);
88#if defined(_WIN32) && !defined(__CYGWIN__)
89 if constexpr (__unicode::__literal_encoding_is_utf8())
90 std::vprint_unicode_buffered(__stream, __fmt.get(), __fmtargs);
91 else
92#endif
93
94 if constexpr (__locksafe)
95 std::vprint_nonunicode(__stream, __fmt.get(), __fmtargs);
96 else
97 std::vprint_nonunicode_buffered(__stream, __fmt.get(), __fmtargs);
98 }
99
100 template<typename... _Args>
101 inline void
102 print(format_string<_Args...> __fmt, _Args&&... __args)
103 { std::print(stdout, __fmt, std::forward<_Args>(__args)...); }
104
105 template<typename... _Args>
106 inline void
107 println(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args)
108 {
109 constexpr bool __locksafe =
110 (enable_nonlocking_formatter_optimization<remove_cvref_t<_Args>> && ...);
111
112 // The standard wants us to call
113 // print(stream, dynamic_format(string(fmt.get()) + '\n'), args...)
114 // here, but we can avoid that string concatenation in most cases,
115 // and we know what that would call, so we can call that directly.
116
117 auto __fmtargs = std::make_format_args(__args...);
118
119#if defined(_WIN32) && !defined(__CYGWIN__)
120 if constexpr (__unicode::__literal_encoding_is_utf8())
121 {
122 // We can't avoid the string concatenation here, but we can call
123 // vprint_unicode_buffered directly, since that's what print would do.
124 string __fmtn;
125 __fmtn.reserve(__fmt.get().size() + 1);
126 __fmtn = __fmt.get();
127 __fmtn += '\n';
128 std::vprint_unicode_buffered(__stream, __fmtn, __fmtargs);
129 }
130 else
131#endif
132
133#ifdef _GLIBCXX_NO_INLINE_PRINT
134 {
135 string __fmtn;
136 __fmtn.reserve(__fmt.get().size() + 1);
137 __fmtn = __fmt.get();
138 __fmtn += '\n';
139 std::vprint_nonunicode(__stream, __fmtn, __fmtargs);
140 }
141#else
142 // For non-Windows and for non-Unicode on Windows, we know that print
143 // would call vprint_nonunicode or vprint_nonunicode_buffered with a
144 // newline appended to the format-string. Use a _File_sink that adds
145 // the newline automatically and write to it directly.
146 if constexpr (__locksafe)
147 std::vformat_to(__format::_File_sink(__stream, true).out(),
148 __fmt.get(), __fmtargs);
149 else
150 {
151 // Format to a string buffer first, then write the result to a
152 // _File_sink that adds a newline.
153 __format::_Str_sink<char> __buf;
154 std::vformat_to(__buf.out(), __fmt.get(), __fmtargs);
155 string_view __s(__buf.view());
156 __format::_File_sink(__stream, true).out() = __s;
157 }
158#endif
159 }
160
161 template<typename... _Args>
162 inline void
163 println(format_string<_Args...> __fmt, _Args&&... __args)
164 { std::println(stdout, __fmt, std::forward<_Args>(__args)...); }
165
166 inline void
167 vprint_unicode_buffered(string_view __fmt, format_args __args)
168 { std::vprint_unicode_buffered(stdout, __fmt, __args); }
169
170 inline void
171 vprint_nonunicode_buffered(string_view __fmt, format_args __args)
172 { std::vprint_nonunicode_buffered(stdout, __fmt, __args); }
173
174 // Defined for C++26, supported as an extension to C++23.
175 inline void println(FILE* __stream)
176 {
177#if defined(_WIN32) && !defined(__CYGWIN__)
178 if constexpr (__unicode::__literal_encoding_is_utf8())
179 std::vprint_unicode_buffered(__stream, "\n", std::make_format_args());
180 else
181#endif
182 if (std::putc('\n', __stream) == EOF)
183 __throw_system_error(EIO);
184 }
185
186 inline void println() { std::println(stdout); }
187
188_GLIBCXX_END_NAMESPACE_VERSION
189} // namespace std
190#endif // __cpp_lib_print
191#endif // _GLIBCXX_PRINT
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition move.h:72
ISO C++ entities toplevel namespace is std.