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