Branch data Line data Source code
1 : : // ostream classes -*- C++ -*-
2 : :
3 : : // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4 : : // 2006, 2007
5 : : // Free Software Foundation, Inc.
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
20 : : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
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 : :
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 : :
37 : : //
38 : : // ISO C++ 14882: 27.6.2 Output streams
39 : : //
40 : :
41 : : #ifndef _OSTREAM_TCC
42 : : #define _OSTREAM_TCC 1
43 : :
44 : : #pragma GCC system_header
45 : :
46 : : #include <cxxabi-forced.h>
47 : :
48 : : _GLIBCXX_BEGIN_NAMESPACE(std)
49 : :
50 : : template<typename _CharT, typename _Traits>
51 : : basic_ostream<_CharT, _Traits>::sentry::
52 : 0 : sentry(basic_ostream<_CharT, _Traits>& __os)
53 : 0 : : _M_ok(false), _M_os(__os)
54 : : {
55 : : // XXX MT
56 [ # # ][ # # ]: 0 : if (__os.tie() && __os.good())
[ # # ]
57 : 0 : __os.tie()->flush();
58 : :
59 [ # # ]: 0 : if (__os.good())
60 : 0 : _M_ok = true;
61 : : else
62 : 0 : __os.setstate(ios_base::failbit);
63 : 0 : }
64 : :
65 : : template<typename _CharT, typename _Traits>
66 : : template<typename _ValueT>
67 : : basic_ostream<_CharT, _Traits>&
68 : : basic_ostream<_CharT, _Traits>::
69 : 0 : _M_insert(_ValueT __v)
70 : : {
71 : 0 : sentry __cerb(*this);
72 [ # # # # : 0 : if (__cerb)
# # # # ]
73 : : {
74 : 0 : ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
75 : : try
76 : : {
77 : 0 : const __num_put_type& __np = __check_facet(this->_M_num_put);
78 [ # # ][ # # ]: 0 : if (__np.put(*this, *this, this->fill(), __v).failed())
[ # # ][ # # ]
79 : : __err |= ios_base::badbit;
80 : : }
81 : 0 : catch(__cxxabiv1::__forced_unwind&)
82 : : {
83 : 0 : this->_M_setstate(ios_base::badbit);
84 : 0 : __throw_exception_again;
85 : : }
86 : 0 : catch(...)
87 : 0 : { this->_M_setstate(ios_base::badbit); }
88 [ # # ][ # # ]: 0 : if (__err)
[ # # ][ # # ]
89 : 0 : this->setstate(__err);
90 : : }
91 : 0 : return *this;
92 : : }
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 : 884 : operator<<(int __n)
112 : : {
113 : : // _GLIBCXX_RESOLVE_LIB_DEFECTS
114 : : // 117. basic_ostream uses nonexistent num_put member functions.
115 : 1768 : const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
116 [ + - ][ - + ]: 884 : if (__fmt == ios_base::oct || __fmt == ios_base::hex)
117 : 0 : return _M_insert(static_cast<long>(static_cast<unsigned int>(__n)));
118 : : else
119 : 884 : return _M_insert(static_cast<long>(__n));
120 : : }
121 : :
122 : : template<typename _CharT, typename _Traits>
123 : : basic_ostream<_CharT, _Traits>&
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
132 : : {
133 : : if (!__copy_streambufs(__sbin, this->rdbuf()))
134 : : __err |= ios_base::failbit;
135 : : }
136 : : catch(__cxxabiv1::__forced_unwind&)
137 : : {
138 : : this->_M_setstate(ios_base::badbit);
139 : : __throw_exception_again;
140 : : }
141 : : catch(...)
142 : : { this->_M_setstate(ios_base::failbit); }
143 : : }
144 : : else if (!__sbin)
145 : : __err |= ios_base::badbit;
146 : : if (__err)
147 : : this->setstate(__err);
148 : : return *this;
149 : : }
150 : :
151 : : template<typename _CharT, typename _Traits>
152 : : basic_ostream<_CharT, _Traits>&
153 : : basic_ostream<_CharT, _Traits>::
154 : 0 : put(char_type __c)
155 : : {
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.
162 : 0 : sentry __cerb(*this);
163 [ # # ]: 0 : if (__cerb)
164 : : {
165 : 0 : ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
166 : : try
167 : : {
168 : 0 : const int_type __put = this->rdbuf()->sputc(__c);
169 [ # # ]: 0 : if (traits_type::eq_int_type(__put, traits_type::eof()))
170 : : __err |= ios_base::badbit;
171 : : }
172 : 0 : catch(__cxxabiv1::__forced_unwind&)
173 : : {
174 : 0 : this->_M_setstate(ios_base::badbit);
175 : 0 : __throw_exception_again;
176 : : }
177 : 0 : catch(...)
178 : 0 : { this->_M_setstate(ios_base::badbit); }
179 [ # # ]: 0 : if (__err)
180 : 0 : this->setstate(__err);
181 : : }
182 : 0 : return *this;
183 : : }
184 : :
185 : : template<typename _CharT, typename _Traits>
186 : : basic_ostream<_CharT, _Traits>&
187 : : basic_ostream<_CharT, _Traits>::
188 : : write(const _CharT* __s, streamsize __n)
189 : : {
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.
197 : : sentry __cerb(*this);
198 : : if (__cerb)
199 : : {
200 : : try
201 : : { _M_write(__s, __n); }
202 : : catch(__cxxabiv1::__forced_unwind&)
203 : : {
204 : : this->_M_setstate(ios_base::badbit);
205 : : __throw_exception_again;
206 : : }
207 : : catch(...)
208 : : { this->_M_setstate(ios_base::badbit); }
209 : : }
210 : : return *this;
211 : : }
212 : :
213 : : template<typename _CharT, typename _Traits>
214 : : basic_ostream<_CharT, _Traits>&
215 : : basic_ostream<_CharT, _Traits>::
216 : 0 : flush()
217 : : {
218 : : // _GLIBCXX_RESOLVE_LIB_DEFECTS
219 : : // DR 60. What is a formatted input function?
220 : : // basic_ostream::flush() is *not* an unformatted output function.
221 : 0 : ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
222 : : try
223 : : {
224 [ # # ][ # # ]: 0 : if (this->rdbuf() && this->rdbuf()->pubsync() == -1)
[ # # ]
225 : : __err |= ios_base::badbit;
226 : : }
227 : 0 : catch(__cxxabiv1::__forced_unwind&)
228 : : {
229 : 0 : this->_M_setstate(ios_base::badbit);
230 : 0 : __throw_exception_again;
231 : : }
232 : 0 : catch(...)
233 : 0 : { this->_M_setstate(ios_base::badbit); }
234 [ # # ]: 0 : if (__err)
235 : 0 : this->setstate(__err);
236 : 0 : return *this;
237 : : }
238 : :
239 : : template<typename _CharT, typename _Traits>
240 : : typename basic_ostream<_CharT, _Traits>::pos_type
241 : : basic_ostream<_CharT, _Traits>::
242 : 0 : tellp()
243 : : {
244 : : pos_type __ret = pos_type(-1);
245 : : try
246 : : {
247 [ # # ]: 0 : if (!this->fail())
248 : 0 : __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
249 : : }
250 : 0 : catch(__cxxabiv1::__forced_unwind&)
251 : : {
252 : 0 : this->_M_setstate(ios_base::badbit);
253 : 0 : __throw_exception_again;
254 : : }
255 : 0 : catch(...)
256 : 0 : { this->_M_setstate(ios_base::badbit); }
257 : : return __ret;
258 : : }
259 : :
260 : : template<typename _CharT, typename _Traits>
261 : : basic_ostream<_CharT, _Traits>&
262 : : basic_ostream<_CharT, _Traits>::
263 : : seekp(pos_type __pos)
264 : : {
265 : : ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
266 : : try
267 : : {
268 : : if (!this->fail())
269 : : {
270 : : // _GLIBCXX_RESOLVE_LIB_DEFECTS
271 : : // 136. seekp, seekg setting wrong streams?
272 : : const pos_type __p = this->rdbuf()->pubseekpos(__pos,
273 : : ios_base::out);
274 : :
275 : : // 129. Need error indication from seekp() and seekg()
276 : : if (__p == pos_type(off_type(-1)))
277 : : __err |= ios_base::failbit;
278 : : }
279 : : }
280 : : catch(__cxxabiv1::__forced_unwind&)
281 : : {
282 : : this->_M_setstate(ios_base::badbit);
283 : : __throw_exception_again;
284 : : }
285 : : catch(...)
286 : : { this->_M_setstate(ios_base::badbit); }
287 : : if (__err)
288 : : this->setstate(__err);
289 : : return *this;
290 : : }
291 : :
292 : : template<typename _CharT, typename _Traits>
293 : : basic_ostream<_CharT, _Traits>&
294 : : basic_ostream<_CharT, _Traits>::
295 : : seekp(off_type __off, ios_base::seekdir __dir)
296 : : {
297 : : ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
298 : : try
299 : : {
300 : : if (!this->fail())
301 : : {
302 : : // _GLIBCXX_RESOLVE_LIB_DEFECTS
303 : : // 136. seekp, seekg setting wrong streams?
304 : : const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
305 : : ios_base::out);
306 : :
307 : : // 129. Need error indication from seekp() and seekg()
308 : : if (__p == pos_type(off_type(-1)))
309 : : __err |= ios_base::failbit;
310 : : }
311 : : }
312 : : catch(__cxxabiv1::__forced_unwind&)
313 : : {
314 : : this->_M_setstate(ios_base::badbit);
315 : : __throw_exception_again;
316 : : }
317 : : catch(...)
318 : : { this->_M_setstate(ios_base::badbit); }
319 : : if (__err)
320 : : this->setstate(__err);
321 : : return *this;
322 : : }
323 : :
324 : : template<typename _CharT, typename _Traits>
325 : : basic_ostream<_CharT, _Traits>&
326 : : operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)
327 : : {
328 : : if (!__s)
329 : : __out.setstate(ios_base::badbit);
330 : : else
331 : : {
332 : : // _GLIBCXX_RESOLVE_LIB_DEFECTS
333 : : // 167. Improper use of traits_type::length()
334 : : const size_t __clen = char_traits<char>::length(__s);
335 : : try
336 : : {
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]);
344 : :
345 : : _CharT *__ws = __pg.__get();
346 : : for (size_t __i = 0; __i < __clen; ++__i)
347 : : __ws[__i] = __out.widen(__s[__i]);
348 : : __ostream_insert(__out, __ws, __clen);
349 : : }
350 : : catch(__cxxabiv1::__forced_unwind&)
351 : : {
352 : : __out._M_setstate(ios_base::badbit);
353 : : __throw_exception_again;
354 : : }
355 : : catch(...)
356 : : { __out._M_setstate(ios_base::badbit); }
357 : : }
358 : : return __out;
359 : : }
360 : :
361 : : // Inhibit implicit instantiations for required instantiations,
362 : : // which are defined via explicit instantiations elsewhere.
363 : : // NB: This syntax is a GNU extension.
364 : : #if _GLIBCXX_EXTERN_TEMPLATE
365 : : extern template class _GLIBCXX_IMPORT 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 : :
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 : :
387 : : #ifdef _GLIBCXX_USE_WCHAR_T
388 : : extern template class _GLIBCXX_IMPORT 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*);
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*);
407 : : #endif
408 : : #endif
409 : :
410 : : _GLIBCXX_END_NAMESPACE
411 : :
412 : : #endif
|