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>
44 #include <cstdio>
45 #include <cerrno>
46 #include <bits/functexcept.h>
47 
48 #ifdef _WIN32
49 # include <system_error>
50 #endif
51 
52 namespace std _GLIBCXX_VISIBILITY(default)
53 {
54 _GLIBCXX_BEGIN_NAMESPACE_VERSION
55 
56 namespace __format
57 {
58 #if _GLIBCXX_USE_STDIO_LOCKING && _GLIBCXX_USE_GLIBC_STDIO_EXT
59  // These are defined in <stdio_ext.h> but we don't want to include that.
60  extern "C" int __fwritable(FILE*) noexcept;
61  extern "C" int __flbf(FILE*) noexcept;
62  extern "C" size_t __fbufsize(FILE*) noexcept;
63 
64  // A format sink that writes directly to a Glibc FILE.
65  // The file is locked on construction and its buffer is accessed directly.
66  class _File_sink final : _Buf_sink<char>
67  {
68  struct _File
69  {
70  explicit
71  _File(FILE* __f) : _M_file(__f)
72  {
73  ::flockfile(__f);
74  // Ensure stream is in write mode
75  if (!__fwritable(__f))
76  {
77  ::funlockfile(__f);
78  __throw_system_error(EACCES);
79  }
80  // Allocate buffer if needed:
81  if (_M_write_buf().empty())
82  if (::__overflow(__f, EOF) == EOF)
83  {
84  const int __err = errno;
85  ::funlockfile(__f);
86  __throw_system_error(__err);
87  }
88  }
89 
90  ~_File() { ::funlockfile(_M_file); }
91 
92  _File(_File&&) = delete;
93 
94  // A span viewing the unused portion of the stream's output buffer.
95  std::span<char>
96  _M_write_buf() noexcept
97  {
98  return {_M_file->_IO_write_ptr,
99  size_t(_M_file->_IO_buf_end - _M_file->_IO_write_ptr)};
100  }
101 
102  // Flush the output buffer to the file so we can write to it again.
103  void
104  _M_flush()
105  {
106  if (::fflush_unlocked(_M_file))
107  __throw_system_error(errno);
108  }
109 
110  // Update the current position in the output buffer.
111  void
112  _M_bump(size_t __n) noexcept
113  { _M_file->_IO_write_ptr += __n; }
114 
115  bool
116  _M_line_buffered() const noexcept
117  { return __flbf(_M_file); } // Or: _M_file->_flags & 0x200
118 
119  bool
120  _M_unbuffered() const noexcept
121  { return __fbufsize(_M_file) == 1; } // Or: _M_file->_flags & 0x2
122 
123  FILE* _M_file;
124  } _M_file;
125 
126  bool _M_add_newline; // True for std::println, false for std::print.
127 
128  // Flush the stream's put area so it can be refilled.
129  void
130  _M_overflow() override
131  {
132  auto __s = this->_M_used();
133  if (__s.data() == this->_M_buf)
134  {
135  // Characters in internal buffer need to be transferred to the FILE.
136  auto __n = ::fwrite_unlocked(__s.data(), 1, __s.size(),
137  _M_file._M_file);
138  if (__n != __s.size())
139  __throw_system_error(errno);
140  this->_M_reset(this->_M_buf);
141  }
142  else
143  {
144  // Characters were written directly to the FILE's output buffer.
145  _M_file._M_bump(__s.size());
146  _M_file._M_flush();
147  this->_M_reset(_M_file._M_write_buf());
148  }
149  }
150 
151  public:
152  _File_sink(FILE* __f, bool __add_newline)
153  : _M_file(__f), _M_add_newline(__add_newline)
154  {
155  if (!_M_file._M_unbuffered())
156  // Write directly to the FILE's output buffer.
157  this->_M_reset(_M_file._M_write_buf());
158  }
159 
160  ~_File_sink() noexcept(false)
161  {
162  auto __s = this->_M_used();
163  if (__s.data() == this->_M_buf) // Unbuffered stream
164  {
165  _File_sink::_M_overflow();
166  if (_M_add_newline)
167  ::putc_unlocked('\n', _M_file._M_file);
168  }
169  else
170  {
171  _M_file._M_bump(__s.size());
172  if (_M_add_newline)
173  ::putc_unlocked('\n', _M_file._M_file);
174  else if (_M_file._M_line_buffered() && __s.size()
175  && (__s.back() == '\n'
176  || __builtin_memchr(__s.data(), '\n', __s.size())))
177  _M_file._M_flush();
178  }
179  }
180 
181  using _Sink<char>::out;
182  };
183 #elif _GLIBCXX_USE_STDIO_LOCKING
184  // A format sink that buffers output and then copies it to a stdio FILE.
185  // The file is locked on construction and written to using fwrite_unlocked.
186  class _File_sink final : _Buf_sink<char>
187  {
188  FILE* _M_file;
189  bool _M_add_newline;
190 
191  // Transfer buffer contents to the FILE, so buffer can be refilled.
192  void
193  _M_overflow() override
194  {
195  auto __s = this->_M_used();
196 #if _GLIBCXX_HAVE_FWRITE_UNLOCKED
197  auto __n = ::fwrite_unlocked(__s.data(), 1, __s.size(), _M_file);
198  if (__n != __s.size())
199  __throw_system_error(errno);
200 #else
201  for (char __c : __s)
202  ::putc_unlocked(__c, _M_file);
203  if (::ferror(_M_file))
204  __throw_system_error(errno);
205 #endif
206  this->_M_reset(this->_M_buf);
207  }
208 
209  public:
210  _File_sink(FILE* __f, bool __add_newline) noexcept
211  : _Buf_sink<char>(), _M_file(__f), _M_add_newline(__add_newline)
212  { ::flockfile(__f); }
213 
214  ~_File_sink() noexcept(false)
215  {
216  _File_sink::_M_overflow();
217  if (_M_add_newline)
218  ::putc_unlocked('\n', _M_file);
219  ::funlockfile(_M_file);
220  }
221 
222  using _Sink<char>::out;
223  };
224 #else
225  // A wrapper around a format sink that copies the output to a stdio FILE.
226  // This is not actually a _Sink itself, but it creates one to hold the
227  // formatted characters and then copies them to the file when finished.
228  class _File_sink final
229  {
230  FILE* _M_file;
231  _Str_sink<char> _M_sink;
232  bool _M_add_newline;
233 
234  public:
235  _File_sink(FILE* __f, bool __add_newline) noexcept
236  : _M_file(__f), _M_add_newline(__add_newline)
237  { }
238 
239  ~_File_sink() noexcept(false)
240  {
241  string __s = std::move(_M_sink).get();
242  if (_M_add_newline)
243  __s += '\n';
244  auto __n = std::fwrite(__s.data(), 1, __s.size(), _M_file);
245  if (__n < __s.size())
246  __throw_system_error(EIO);
247  }
248 
249  auto out() { return _M_sink.out(); }
250  };
251 #endif
252 } // namespace __format
253 
254  inline void
255  vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args)
256  {
257  std::vformat_to(__format::_File_sink(__stream, false).out(), __fmt, __args);
258  }
259 
260  inline void
261  vprint_nonunicode_buffered(FILE* __stream, string_view __fmt,
262  format_args __args)
263  {
264  __format::_Str_sink<char> __buf;
265  std::vformat_to(__buf.out(), __fmt, __args);
266  auto __out = __buf.view();
267  if (std::fwrite(__out.data(), 1, __out.size(), __stream) != __out.size())
268  __throw_system_error(EIO);
269  }
270 
271  inline void
272  vprint_unicode(FILE* __stream, string_view __fmt, format_args __args)
273  {
274 #if !defined(_WIN32) || defined(__CYGWIN__)
275  // For most targets we don't need to do anything special to write
276  // Unicode to a terminal.
277  std::vprint_nonunicode(__stream, __fmt, __args);
278 #else
279  __format::_Str_sink<char> __buf;
280  std::vformat_to(__buf.out(), __fmt, __args);
281  auto __out = __buf._M_span();
282 
283  void* __open_terminal(FILE*);
284  error_code __write_to_terminal(void*, span<char>);
285  // If stream refers to a terminal, write a native Unicode string to it.
286  if (auto __term = __open_terminal(__stream))
287  {
288  error_code __e;
289  if (!std::fflush(__stream))
290  {
291  __e = __write_to_terminal(__term, __out);
292  if (!__e)
293  return;
294  if (__e == std::make_error_code(errc::illegal_byte_sequence))
295  return;
296  }
297  else
298  __e = error_code(errno, generic_category());
299  _GLIBCXX_THROW_OR_ABORT(system_error(__e, "std::vprint_unicode"));
300  }
301 
302  // Otherwise just write the string to the file.
303  if (std::fwrite(__out.data(), 1, __out.size(), __stream) != __out.size())
304  __throw_system_error(EIO);
305 #endif
306  }
307 
308  inline void
309  vprint_unicode_buffered(FILE* __stream, string_view __fmt, format_args __args)
310  {
311 #if !defined(_WIN32) || defined(__CYGWIN__)
312  // For most targets we don't need to do anything special to write
313  // Unicode to a terminal. Just use the nonunicode function.
314  std::vprint_nonunicode_buffered(__stream, __fmt, __args);
315 #else
316  // For Windows the locking function formats everything first anyway,
317  // so no formatting happens while a lock is taken. Just use that.
318  std::vprint_unicode(__stream, __fmt, __args);
319 #endif
320  }
321 
322  template<typename... _Args>
323  inline void
324  print(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args)
325  {
326  constexpr bool __locksafe =
327  (enable_nonlocking_formatter_optimization<remove_cvref_t<_Args>> && ...);
328 
329  auto __fmtargs = std::make_format_args(__args...);
330 #if defined(_WIN32) && !defined(__CYGWIN__)
331  if constexpr (__unicode::__literal_encoding_is_utf8())
332  std::vprint_unicode_buffered(__stream, __fmt.get(), __fmtargs);
333  else
334 #endif
335 
336  if constexpr (__locksafe)
337  std::vprint_nonunicode(__stream, __fmt.get(), __fmtargs);
338  else
339  std::vprint_nonunicode_buffered(__stream, __fmt.get(), __fmtargs);
340  }
341 
342  template<typename... _Args>
343  inline void
344  print(format_string<_Args...> __fmt, _Args&&... __args)
345  { std::print(stdout, __fmt, std::forward<_Args>(__args)...); }
346 
347  template<typename... _Args>
348  inline void
349  println(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args)
350  {
351  constexpr bool __locksafe =
352  (enable_nonlocking_formatter_optimization<remove_cvref_t<_Args>> && ...);
353 
354  // The standard wants us to call
355  // print(stream, runtime_format(string(fmt.get()) + '\n'), args...)
356  // here, but we can avoid that string concatenation in most cases,
357  // and we know what that would call, so we can call that directly.
358 
359  auto __fmtargs = std::make_format_args(__args...);
360 #if defined(_WIN32) && !defined(__CYGWIN__)
361  if constexpr (__unicode::__literal_encoding_is_utf8())
362  {
363  // We can't avoid the string concatenation here, but we can call
364  // vprint_unicode_buffered directly, since that's what print would do.
365  string __fmtn;
366  __fmtn.reserve(__fmt.get().size() + 1);
367  __fmtn = __fmt.get();
368  __fmtn += '\n';
369  std::vprint_unicode_buffered(__stream, __fmtn, __fmtargs);
370  }
371  else
372 #endif
373 
374  // For non-Windows and for non-Unicode on Windows, we know that print
375  // would call vprint_nonunicode or vprint_nonunicode_buffered with a
376  // newline appended to the format-string. Use a _File_sink that adds
377  // the newline automatically and write to it directly.
378  if constexpr (__locksafe)
379  std::vformat_to(__format::_File_sink(__stream, true).out(),
380  __fmt.get(), __fmtargs);
381  else
382  {
383  // Format to a string buffer first, then write the result to a
384  // _File_sink that adds a newline.
385  __format::_Str_sink<char> __buf;
386  std::vformat_to(__buf.out(), __fmt.get(), __fmtargs);
387  string_view __s(__buf.view());
388  __format::_File_sink(__stream, true).out() = __s;
389  }
390  }
391 
392  template<typename... _Args>
393  inline void
394  println(format_string<_Args...> __fmt, _Args&&... __args)
395  { std::println(stdout, __fmt, std::forward<_Args>(__args)...); }
396 
397  inline void
398  vprint_unicode_buffered(string_view __fmt, format_args __args)
399  { std::vprint_unicode_buffered(stdout, __fmt, __args); }
400 
401  inline void
402  vprint_nonunicode_buffered(string_view __fmt, format_args __args)
403  { std::vprint_nonunicode_buffered(stdout, __fmt, __args); }
404 
405  // Defined for C++26, supported as an extension to C++23.
406  inline void println(FILE* __stream)
407  {
408 #if defined(_WIN32) && !defined(__CYGWIN__)
409  if constexpr (__unicode::__literal_encoding_is_utf8())
410  std::vprint_unicode_buffered(__stream, "\n", std::make_format_args());
411  else
412 #endif
413  if (std::putc('\n', __stream) == EOF)
414  __throw_system_error(EIO);
415  }
416 
417  inline void println() { std::println(stdout); }
418 
419 _GLIBCXX_END_NAMESPACE_VERSION
420 } // namespace std
421 #endif // __cpp_lib_print
422 #endif // _GLIBCXX_PRINT
requires_hosted.h
std::empty
constexpr auto empty(const _Container &__cont) noexcept(noexcept(__cont.empty())) -> decltype(__cont.empty())
Return whether a container is empty.
Definition: range_access.h:294
format
std::generic_category
const error_category & generic_category() noexcept
Error category for errno error codes.
std::move
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition: move.h:138
std
ISO C++ entities toplevel namespace is std.
std::make_error_code
error_code make_error_code(future_errc __errc) noexcept
Overload of make_error_code for future_errc.
Definition: future:97
cerrno
functexcept.h
version.h