]>
Commit | Line | Data |
---|---|---|
a32e3c09 BK |
1 | // ostream classes -*- C++ -*- |
2 | ||
99dee823 | 3 | // Copyright (C) 1997-2021 Free Software Foundation, Inc. |
725dc051 BK |
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 | |
748086b7 | 8 | // Free Software Foundation; either version 3, or (at your option) |
725dc051 BK |
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 | ||
748086b7 JJ |
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. | |
725dc051 | 19 | |
748086b7 JJ |
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/>. | |
725dc051 | 24 | |
f910786b | 25 | /** @file bits/ostream.tcc |
0aa06b18 | 26 | * This is an internal header file, included by other library headers. |
f910786b | 27 | * Do not attempt to use it directly. @headername{ostream} |
0aa06b18 BK |
28 | */ |
29 | ||
725dc051 BK |
30 | // |
31 | // ISO C++ 14882: 27.6.2 Output streams | |
32 | // | |
33 | ||
3d7c150e BK |
34 | #ifndef _OSTREAM_TCC |
35 | #define _OSTREAM_TCC 1 | |
36 | ||
3b794528 BK |
37 | #pragma GCC system_header |
38 | ||
7c3e9502 | 39 | #include <bits/cxxabi_forced.h> |
d05f74f1 | 40 | |
12ffa228 BK |
41 | namespace std _GLIBCXX_VISIBILITY(default) |
42 | { | |
43 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
3cbc7af0 | 44 | |
725dc051 BK |
45 | template<typename _CharT, typename _Traits> |
46 | basic_ostream<_CharT, _Traits>::sentry:: | |
12841eb3 | 47 | sentry(basic_ostream<_CharT, _Traits>& __os) |
26c691a8 | 48 | : _M_ok(false), _M_os(__os) |
725dc051 | 49 | { |
ff5d863f | 50 | // XXX MT |
b7bb6d4a | 51 | if (__os.tie() && __os.good()) |
ff5d863f PC |
52 | __os.tie()->flush(); |
53 | ||
54 | if (__os.good()) | |
55 | _M_ok = true; | |
56 | else | |
26c691a8 | 57 | __os.setstate(ios_base::failbit); |
725dc051 | 58 | } |
ed6814f7 | 59 | |
6cf5465d | 60 | template<typename _CharT, typename _Traits> |
49d5c016 PC |
61 | template<typename _ValueT> |
62 | basic_ostream<_CharT, _Traits>& | |
63 | basic_ostream<_CharT, _Traits>:: | |
64 | _M_insert(_ValueT __v) | |
65 | { | |
66 | sentry __cerb(*this); | |
880b527f | 67 | if (__cerb) |
49d5c016 | 68 | { |
6f0398bb | 69 | ios_base::iostate __err = ios_base::goodbit; |
bc2631e0 | 70 | __try |
49d5c016 PC |
71 | { |
72 | const __num_put_type& __np = __check_facet(this->_M_num_put); | |
73 | if (__np.put(*this, *this, this->fill(), __v).failed()) | |
74 | __err |= ios_base::badbit; | |
75 | } | |
bc2631e0 | 76 | __catch(__cxxabiv1::__forced_unwind&) |
d05f74f1 JM |
77 | { |
78 | this->_M_setstate(ios_base::badbit); | |
79 | __throw_exception_again; | |
80 | } | |
bc2631e0 | 81 | __catch(...) |
49d5c016 PC |
82 | { this->_M_setstate(ios_base::badbit); } |
83 | if (__err) | |
84 | this->setstate(__err); | |
85 | } | |
86 | return *this; | |
87 | } | |
e7968bd8 PC |
88 | |
89 | template<typename _CharT, typename _Traits> | |
90 | basic_ostream<_CharT, _Traits>& | |
91 | basic_ostream<_CharT, _Traits>:: | |
92 | operator<<(short __n) | |
93 | { | |
94 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
95 | // 117. basic_ostream uses nonexistent num_put member functions. | |
96 | const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; | |
97 | if (__fmt == ios_base::oct || __fmt == ios_base::hex) | |
98 | return _M_insert(static_cast<long>(static_cast<unsigned short>(__n))); | |
99 | else | |
100 | return _M_insert(static_cast<long>(__n)); | |
101 | } | |
102 | ||
103 | template<typename _CharT, typename _Traits> | |
104 | basic_ostream<_CharT, _Traits>& | |
105 | basic_ostream<_CharT, _Traits>:: | |
106 | operator<<(int __n) | |
107 | { | |
108 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
109 | // 117. basic_ostream uses nonexistent num_put member functions. | |
110 | const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; | |
111 | if (__fmt == ios_base::oct || __fmt == ios_base::hex) | |
112 | return _M_insert(static_cast<long>(static_cast<unsigned int>(__n))); | |
113 | else | |
114 | return _M_insert(static_cast<long>(__n)); | |
115 | } | |
49d5c016 | 116 | |
12841eb3 | 117 | template<typename _CharT, typename _Traits> |
ed6814f7 | 118 | basic_ostream<_CharT, _Traits>& |
12841eb3 BK |
119 | basic_ostream<_CharT, _Traits>:: |
120 | operator<<(__streambuf_type* __sbin) | |
121 | { | |
6f0398bb | 122 | ios_base::iostate __err = ios_base::goodbit; |
12841eb3 | 123 | sentry __cerb(*this); |
880b527f | 124 | if (__cerb && __sbin) |
12841eb3 | 125 | { |
bc2631e0 | 126 | __try |
a16ad779 | 127 | { |
fb8d4638 | 128 | if (!__copy_streambufs(__sbin, this->rdbuf())) |
12841eb3 | 129 | __err |= ios_base::failbit; |
a16ad779 | 130 | } |
bc2631e0 | 131 | __catch(__cxxabiv1::__forced_unwind&) |
d05f74f1 JM |
132 | { |
133 | this->_M_setstate(ios_base::badbit); | |
134 | __throw_exception_again; | |
135 | } | |
bc2631e0 | 136 | __catch(...) |
12841eb3 | 137 | { this->_M_setstate(ios_base::failbit); } |
725dc051 | 138 | } |
12841eb3 BK |
139 | else if (!__sbin) |
140 | __err |= ios_base::badbit; | |
6b98580b BK |
141 | if (__err) |
142 | this->setstate(__err); | |
725dc051 BK |
143 | return *this; |
144 | } | |
145 | ||
725dc051 BK |
146 | template<typename _CharT, typename _Traits> |
147 | basic_ostream<_CharT, _Traits>& | |
12841eb3 BK |
148 | basic_ostream<_CharT, _Traits>:: |
149 | put(char_type __c) | |
ed6814f7 | 150 | { |
5681c890 PR |
151 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
152 | // DR 60. What is a formatted input function? | |
153 | // basic_ostream::put(char_type) is an unformatted output function. | |
154 | // DR 63. Exception-handling policy for unformatted output. | |
155 | // Unformatted output functions should catch exceptions thrown | |
156 | // from streambuf members. | |
725dc051 | 157 | sentry __cerb(*this); |
880b527f | 158 | if (__cerb) |
725dc051 | 159 | { |
6f0398bb | 160 | ios_base::iostate __err = ios_base::goodbit; |
bc2631e0 | 161 | __try |
5681c890 | 162 | { |
3adf6cad | 163 | const int_type __put = this->rdbuf()->sputc(__c); |
5681c890 | 164 | if (traits_type::eq_int_type(__put, traits_type::eof())) |
12841eb3 | 165 | __err |= ios_base::badbit; |
5681c890 | 166 | } |
bc2631e0 | 167 | __catch(__cxxabiv1::__forced_unwind&) |
d05f74f1 JM |
168 | { |
169 | this->_M_setstate(ios_base::badbit); | |
170 | __throw_exception_again; | |
171 | } | |
bc2631e0 | 172 | __catch(...) |
12841eb3 | 173 | { this->_M_setstate(ios_base::badbit); } |
6b98580b BK |
174 | if (__err) |
175 | this->setstate(__err); | |
725dc051 | 176 | } |
ed6814f7 | 177 | return *this; |
725dc051 BK |
178 | } |
179 | ||
180 | template<typename _CharT, typename _Traits> | |
181 | basic_ostream<_CharT, _Traits>& | |
12841eb3 BK |
182 | basic_ostream<_CharT, _Traits>:: |
183 | write(const _CharT* __s, streamsize __n) | |
725dc051 | 184 | { |
5681c890 PR |
185 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
186 | // DR 60. What is a formatted input function? | |
187 | // basic_ostream::write(const char_type*, streamsize) is an | |
188 | // unformatted output function. | |
189 | // DR 63. Exception-handling policy for unformatted output. | |
190 | // Unformatted output functions should catch exceptions thrown | |
191 | // from streambuf members. | |
725dc051 | 192 | sentry __cerb(*this); |
880b527f | 193 | if (__cerb) |
5681c890 | 194 | { |
bc2631e0 | 195 | __try |
5681c890 | 196 | { _M_write(__s, __n); } |
bc2631e0 | 197 | __catch(__cxxabiv1::__forced_unwind&) |
d05f74f1 JM |
198 | { |
199 | this->_M_setstate(ios_base::badbit); | |
200 | __throw_exception_again; | |
201 | } | |
bc2631e0 | 202 | __catch(...) |
12841eb3 | 203 | { this->_M_setstate(ios_base::badbit); } |
5681c890 | 204 | } |
725dc051 BK |
205 | return *this; |
206 | } | |
207 | ||
208 | template<typename _CharT, typename _Traits> | |
209 | basic_ostream<_CharT, _Traits>& | |
12841eb3 BK |
210 | basic_ostream<_CharT, _Traits>:: |
211 | flush() | |
725dc051 | 212 | { |
5681c890 PR |
213 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
214 | // DR 60. What is a formatted input function? | |
215 | // basic_ostream::flush() is *not* an unformatted output function. | |
6f0398bb | 216 | ios_base::iostate __err = ios_base::goodbit; |
bc2631e0 | 217 | __try |
12841eb3 BK |
218 | { |
219 | if (this->rdbuf() && this->rdbuf()->pubsync() == -1) | |
220 | __err |= ios_base::badbit; | |
221 | } | |
bc2631e0 | 222 | __catch(__cxxabiv1::__forced_unwind&) |
d05f74f1 JM |
223 | { |
224 | this->_M_setstate(ios_base::badbit); | |
225 | __throw_exception_again; | |
226 | } | |
bc2631e0 | 227 | __catch(...) |
12841eb3 | 228 | { this->_M_setstate(ios_base::badbit); } |
6b98580b BK |
229 | if (__err) |
230 | this->setstate(__err); | |
725dc051 BK |
231 | return *this; |
232 | } | |
ed6814f7 | 233 | |
725dc051 BK |
234 | template<typename _CharT, typename _Traits> |
235 | typename basic_ostream<_CharT, _Traits>::pos_type | |
12841eb3 BK |
236 | basic_ostream<_CharT, _Traits>:: |
237 | tellp() | |
725dc051 BK |
238 | { |
239 | pos_type __ret = pos_type(-1); | |
bc2631e0 | 240 | __try |
12841eb3 BK |
241 | { |
242 | if (!this->fail()) | |
243 | __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out); | |
244 | } | |
bc2631e0 | 245 | __catch(__cxxabiv1::__forced_unwind&) |
d05f74f1 JM |
246 | { |
247 | this->_M_setstate(ios_base::badbit); | |
248 | __throw_exception_again; | |
249 | } | |
bc2631e0 | 250 | __catch(...) |
12841eb3 | 251 | { this->_M_setstate(ios_base::badbit); } |
725dc051 BK |
252 | return __ret; |
253 | } | |
254 | ||
725dc051 BK |
255 | template<typename _CharT, typename _Traits> |
256 | basic_ostream<_CharT, _Traits>& | |
12841eb3 BK |
257 | basic_ostream<_CharT, _Traits>:: |
258 | seekp(pos_type __pos) | |
725dc051 | 259 | { |
6f0398bb | 260 | ios_base::iostate __err = ios_base::goodbit; |
bc2631e0 | 261 | __try |
d52a9847 | 262 | { |
12841eb3 BK |
263 | if (!this->fail()) |
264 | { | |
265 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
266 | // 136. seekp, seekg setting wrong streams? | |
3adf6cad PC |
267 | const pos_type __p = this->rdbuf()->pubseekpos(__pos, |
268 | ios_base::out); | |
ed6814f7 | 269 | |
12841eb3 BK |
270 | // 129. Need error indication from seekp() and seekg() |
271 | if (__p == pos_type(off_type(-1))) | |
272 | __err |= ios_base::failbit; | |
273 | } | |
d52a9847 | 274 | } |
bc2631e0 | 275 | __catch(__cxxabiv1::__forced_unwind&) |
d05f74f1 JM |
276 | { |
277 | this->_M_setstate(ios_base::badbit); | |
278 | __throw_exception_again; | |
279 | } | |
bc2631e0 | 280 | __catch(...) |
12841eb3 | 281 | { this->_M_setstate(ios_base::badbit); } |
6b98580b BK |
282 | if (__err) |
283 | this->setstate(__err); | |
725dc051 BK |
284 | return *this; |
285 | } | |
286 | ||
287 | template<typename _CharT, typename _Traits> | |
288 | basic_ostream<_CharT, _Traits>& | |
289 | basic_ostream<_CharT, _Traits>:: | |
12841eb3 | 290 | seekp(off_type __off, ios_base::seekdir __dir) |
725dc051 | 291 | { |
6f0398bb | 292 | ios_base::iostate __err = ios_base::goodbit; |
bc2631e0 | 293 | __try |
d52a9847 | 294 | { |
12841eb3 BK |
295 | if (!this->fail()) |
296 | { | |
297 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
298 | // 136. seekp, seekg setting wrong streams? | |
3adf6cad PC |
299 | const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, |
300 | ios_base::out); | |
ed6814f7 | 301 | |
12841eb3 BK |
302 | // 129. Need error indication from seekp() and seekg() |
303 | if (__p == pos_type(off_type(-1))) | |
304 | __err |= ios_base::failbit; | |
305 | } | |
037cfe71 | 306 | } |
bc2631e0 | 307 | __catch(__cxxabiv1::__forced_unwind&) |
d05f74f1 JM |
308 | { |
309 | this->_M_setstate(ios_base::badbit); | |
310 | __throw_exception_again; | |
311 | } | |
bc2631e0 | 312 | __catch(...) |
12841eb3 | 313 | { this->_M_setstate(ios_base::badbit); } |
6b98580b BK |
314 | if (__err) |
315 | this->setstate(__err); | |
725dc051 BK |
316 | return *this; |
317 | } | |
318 | ||
725dc051 BK |
319 | template<typename _CharT, typename _Traits> |
320 | basic_ostream<_CharT, _Traits>& | |
321 | operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s) | |
322 | { | |
ec2061a9 PC |
323 | if (!__s) |
324 | __out.setstate(ios_base::badbit); | |
325 | else | |
725dc051 | 326 | { |
78a438f1 PC |
327 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
328 | // 167. Improper use of traits_type::length() | |
d05f74f1 | 329 | const size_t __clen = char_traits<char>::length(__s); |
bc2631e0 | 330 | __try |
78a438f1 | 331 | { |
d05f74f1 JM |
332 | struct __ptr_guard |
333 | { | |
04055200 JM |
334 | _CharT *__p; |
335 | __ptr_guard (_CharT *__ip): __p(__ip) { } | |
336 | ~__ptr_guard() { delete[] __p; } | |
337 | _CharT* __get() { return __p; } | |
d05f74f1 | 338 | } __pg (new _CharT[__clen]); |
78a438f1 | 339 | |
d05f74f1 JM |
340 | _CharT *__ws = __pg.__get(); |
341 | for (size_t __i = 0; __i < __clen; ++__i) | |
342 | __ws[__i] = __out.widen(__s[__i]); | |
11202768 | 343 | __ostream_insert(__out, __ws, __clen); |
a16ad779 | 344 | } |
bc2631e0 | 345 | __catch(__cxxabiv1::__forced_unwind&) |
78a438f1 | 346 | { |
d05f74f1 | 347 | __out._M_setstate(ios_base::badbit); |
78a438f1 PC |
348 | __throw_exception_again; |
349 | } | |
bc2631e0 | 350 | __catch(...) |
d05f74f1 | 351 | { __out._M_setstate(ios_base::badbit); } |
725dc051 | 352 | } |
a16ad779 BK |
353 | return __out; |
354 | } | |
a32e3c09 BK |
355 | |
356 | // Inhibit implicit instantiations for required instantiations, | |
ed6814f7 | 357 | // which are defined via explicit instantiations elsewhere. |
3d7c150e | 358 | #if _GLIBCXX_EXTERN_TEMPLATE |
a32e3c09 BK |
359 | extern template class basic_ostream<char>; |
360 | extern template ostream& endl(ostream&); | |
361 | extern template ostream& ends(ostream&); | |
362 | extern template ostream& flush(ostream&); | |
363 | extern template ostream& operator<<(ostream&, char); | |
364 | extern template ostream& operator<<(ostream&, unsigned char); | |
365 | extern template ostream& operator<<(ostream&, signed char); | |
366 | extern template ostream& operator<<(ostream&, const char*); | |
367 | extern template ostream& operator<<(ostream&, const unsigned char*); | |
368 | extern template ostream& operator<<(ostream&, const signed char*); | |
369 | ||
f12409e6 PC |
370 | extern template ostream& ostream::_M_insert(long); |
371 | extern template ostream& ostream::_M_insert(unsigned long); | |
372 | extern template ostream& ostream::_M_insert(bool); | |
373 | #ifdef _GLIBCXX_USE_LONG_LONG | |
374 | extern template ostream& ostream::_M_insert(long long); | |
375 | extern template ostream& ostream::_M_insert(unsigned long long); | |
376 | #endif | |
377 | extern template ostream& ostream::_M_insert(double); | |
378 | extern template ostream& ostream::_M_insert(long double); | |
379 | extern template ostream& ostream::_M_insert(const void*); | |
380 | ||
3d7c150e | 381 | #ifdef _GLIBCXX_USE_WCHAR_T |
a32e3c09 BK |
382 | extern template class basic_ostream<wchar_t>; |
383 | extern template wostream& endl(wostream&); | |
384 | extern template wostream& ends(wostream&); | |
385 | extern template wostream& flush(wostream&); | |
386 | extern template wostream& operator<<(wostream&, wchar_t); | |
387 | extern template wostream& operator<<(wostream&, char); | |
388 | extern template wostream& operator<<(wostream&, const wchar_t*); | |
389 | extern template wostream& operator<<(wostream&, const char*); | |
f12409e6 PC |
390 | |
391 | extern template wostream& wostream::_M_insert(long); | |
392 | extern template wostream& wostream::_M_insert(unsigned long); | |
393 | extern template wostream& wostream::_M_insert(bool); | |
394 | #ifdef _GLIBCXX_USE_LONG_LONG | |
395 | extern template wostream& wostream::_M_insert(long long); | |
396 | extern template wostream& wostream::_M_insert(unsigned long long); | |
397 | #endif | |
398 | extern template wostream& wostream::_M_insert(double); | |
399 | extern template wostream& wostream::_M_insert(long double); | |
400 | extern template wostream& wostream::_M_insert(const void*); | |
3522a91b | 401 | #endif |
1bc8b0ad | 402 | #endif |
3cbc7af0 | 403 | |
12ffa228 | 404 | _GLIBCXX_END_NAMESPACE_VERSION |
ed4f96af | 405 | } // namespace std |
3d7c150e BK |
406 | |
407 | #endif |