libstdc++: ostream_print.h Source File

libstdc++

ostream_print.h
Go to the documentation of this file.
1// Inline implementation details for std::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/bits/ostream_print.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{ostream}
28 *
29 * This file contains the parts of `<ostream>` which are currently defined
30 * inline, but should be moved into the library eventually.
31 */
32
33#ifndef _GLIBCXX_OSTREAM_PRINT_H
34#define _GLIBCXX_OSTREAM_PRINT_H 1
35
36#ifdef _GLIBCXX_SYSHDR
37#pragma GCC system_header
38#endif
39
40#include <bits/requires_hosted.h> // for std::format
41
42#include <bits/version.h>
43
44#ifdef __glibcxx_print // C++ >= 23
45#include <format>
46
47namespace std _GLIBCXX_VISIBILITY(default)
48{
49_GLIBCXX_BEGIN_NAMESPACE_VERSION
50
51#ifdef _GLIBCXX_NO_INLINE_PRINT
52# define _GLIBCXX_PRINT_INLINE_USED [[__gnu__::__used__]]
53#else
54# define _GLIBCXX_PRINT_INLINE_USED
55#endif
56
57 _GLIBCXX_PRINT_INLINE_USED
58 inline void
59 vprint_nonunicode(ostream& __os, string_view __fmt, format_args __args)
60 {
61 ostream::sentry __cerb(__os);
62 if (__cerb)
63 {
64 __format::_Str_sink<char> __buf;
65 std::vformat_to(__buf.out(), __os.getloc(), __fmt, __args);
66 auto __out = __buf.view();
67
68 __try
69 {
70 std::__ostream_write(__os, __out.data(), __out.size());
71 }
72 __catch(const __cxxabiv1::__forced_unwind&)
73 {
74 __os._M_setstate(ios_base::badbit);
75 __throw_exception_again;
76 }
77 __catch(...)
78 { __os._M_setstate(ios_base::badbit); }
79 }
80 }
81
82 _GLIBCXX_PRINT_INLINE_USED
83 inline void
84 vprint_unicode(ostream& __os, string_view __fmt, format_args __args)
85 {
86#if !defined(_WIN32) || defined(__CYGWIN__)
87 // For most targets we don't need to do anything special to write
88 // Unicode to a terminal.
89 std::vprint_nonunicode(__os, __fmt, __args);
90#else
91 ostream::sentry __cerb(__os);
92 if (__cerb)
93 {
94 __format::_Str_sink<char> __buf;
95 std::vformat_to(__buf.out(), __os.getloc(), __fmt, __args);
96 auto __out = __buf._M_span();
97
98 void* __open_terminal(streambuf*);
99 error_code __write_to_terminal(void*, span<char>);
100 // If stream refers to a terminal, write a Unicode string to it.
101 if (auto __term = __open_terminal(__os.rdbuf()))
102 {
103#if !defined(_WIN32) || defined(__CYGWIN__)
104 // For POSIX, __open_terminal(streambuf*) uses fdopen to open a
105 // new file, so we would need to close it here. This code is not
106 // actually compiled because it's inside an #ifdef _WIN32 group,
107 // but just in case that changes in future ...
108 struct _Guard
109 {
110 _Guard(void* __p) : _M_f((FILE*)__p) { }
111 ~_Guard() { std::fclose(_M_f); }
112 _Guard(_Guard&&) = delete;
113 _Guard& operator=(_Guard&&) = delete;
114 FILE* _M_f;
115 };
116 _Guard __g(__term);
117#endif
118
119 ios_base::iostate __err = ios_base::goodbit;
120 __try
121 {
122 if (__os.rdbuf()->pubsync() == -1)
123 __err = ios::badbit;
124 else if (auto __e = __write_to_terminal(__term, __out))
125 if (__e != std::make_error_code(errc::illegal_byte_sequence))
126 __err = ios::badbit;
127 }
128 __catch(const __cxxabiv1::__forced_unwind&)
129 {
130 __os._M_setstate(ios_base::badbit);
131 __throw_exception_again;
132 }
133 __catch(...)
134 { __os._M_setstate(ios_base::badbit); }
135
136 if (__err)
137 __os.setstate(__err);
138 return;
139 }
140
141 // Otherwise just insert the string as vprint_nonunicode does.
142 __try
143 {
144 std::__ostream_write(__os, __out.data(), __out.size());
145 }
146 __catch(const __cxxabiv1::__forced_unwind&)
147 {
148 __os._M_setstate(ios_base::badbit);
149 __throw_exception_again;
150 }
151 __catch(...)
152 { __os._M_setstate(ios_base::badbit); }
153 }
154#endif // _WIN32
155 }
156#undef _GLIBCXX_PRINT_INLINE_USED
157
158_GLIBCXX_END_NAMESPACE_VERSION
159} // namespace std
160#endif // __glibcxx_print
161#endif // _GLIBCXX_OSTREAM_PRINT_H
format
version.h
requires_hosted.h
std::make_error_code
error_code make_error_code(future_errc __errc) noexcept
Overload of make_error_code for future_errc.
Definition future:96
std::streambuf
basic_streambuf< char > streambuf
Base class for char buffers.
Definition iosfwd.h:78
std::ostream
basic_ostream< char > ostream
Base class for char output streams.
Definition iosfwd.h:84
std
ISO C++ entities toplevel namespace is std.
std::error_code
Definition system_error:226
std::ios_base::iostate
_Ios_Iostate iostate
This is a bitmask type.
Definition ios_base.h:453
std::ios_base::goodbit
static const iostate goodbit
Indicates all is well.
Definition ios_base.h:468
std::ios_base::badbit
static const iostate badbit
Indicates a loss of integrity in an input or output sequence (such as an irrecoverable read error fro...
Definition ios_base.h:457