]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/bits/ostream.tcc
include: New directory.
[thirdparty/gcc.git] / libstdc++-v3 / include / bits / ostream.tcc
CommitLineData
725dc051
BK
1// Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc.
2//
3// This file is part of the GNU ISO C++ Library. This library is free
4// software; you can redistribute it and/or modify it under the
5// terms of the GNU General Public License as published by the
6// Free Software Foundation; either version 2, or (at your option)
7// any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License along
15// with this library; see the file COPYING. If not, write to the Free
16// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17// USA.
18
19// As a special exception, you may use this file as part of a free software
20// library without restriction. Specifically, if other files instantiate
21// templates or use macros or inline functions from this file, or you compile
22// this file and link it with other files to produce an executable, this
23// file does not by itself cause the resulting executable to be covered by
24// the GNU General Public License. This exception does not however
25// invalidate any other reasons why the executable file might be covered by
26// the GNU General Public License.
27
28//
29// ISO C++ 14882: 27.6.2 Output streams
30//
31
32#include <bits/std_locale.h>
33
34namespace std {
35
36 template<typename _CharT, typename _Traits>
37 basic_ostream<_CharT, _Traits>::sentry::
38 sentry(basic_ostream<_CharT,_Traits>& __os)
39 : _M_ok(__os.good()), _M_os(__os)
40 {
41 // XXX MT
42 if (_M_ok && __os.tie())
43 __os.tie()->flush();
44 }
45
46 template<typename _CharT, typename _Traits>
47 basic_ostream<_CharT, _Traits>&
48 basic_ostream<_CharT, _Traits>::
49 operator<<(__ostream_type& (*__pf)(__ostream_type&))
50 {
51 sentry __cerb(*this);
52 if (__cerb)
53 {
54 try {
55 __pf(*this);
56 }
57 catch(exception& __fail){
58 // 27.6.2.5.1 Common requirements.
59 // Turn this on without causing an ios::failure to be thrown.
60 this->setstate(ios_base::badbit);
61 if ((this->exceptions() & ios_base::badbit) != 0)
62 throw;
63 }
64 }
65 return *this;
66 }
67
68 template<typename _CharT, typename _Traits>
69 basic_ostream<_CharT, _Traits>&
70 basic_ostream<_CharT, _Traits>::
71 operator<<(__ios_type& (*__pf)(__ios_type&))
72 {
73 sentry __cerb(*this);
74 if (__cerb)
75 {
76 try {
77 __pf(*this);
78 }
79 catch(exception& __fail){
80 // 27.6.2.5.1 Common requirements.
81 // Turn this on without causing an ios::failure to be thrown.
82 this->setstate(ios_base::badbit);
83 if ((this->exceptions() & ios_base::badbit) != 0)
84 throw;
85 }
86 }
87 return *this;
88 }
89
90 template<typename _CharT, typename _Traits>
91 basic_ostream<_CharT, _Traits>&
92 basic_ostream<_CharT, _Traits>::
93 operator<<(ios_base& (*__pf)(ios_base&))
94 {
95 sentry __cerb(*this);
96 if (__cerb)
97 {
98 try {
99 __pf(*this);
100 }
101 catch(exception& __fail){
102 // 27.6.2.5.1 Common requirements.
103 // Turn this on without causing an ios::failure to be thrown.
104 this->setstate(ios_base::badbit);
105 if ((this->exceptions() & ios_base::badbit) != 0)
106 throw;
107 }
108 }
109 return *this;
110 }
111
112 template<typename _CharT, typename _Traits>
113 basic_ostream<_CharT, _Traits>&
114 basic_ostream<_CharT, _Traits>::operator<<(bool __n)
115 {
116 sentry __cerb(*this);
117 if (__cerb)
118 {
119 try {
120 if (_M_fnumput->put(*this, *this, this->fill(), __n).failed())
121 this->setstate(ios_base::badbit);
122 }
123 catch(exception& __fail){
124 // 27.6.1.2.1 Common requirements.
125 // Turn this on without causing an ios::failure to be thrown.
126 this->setstate(ios_base::badbit);
127 if ((this->exceptions() & ios_base::badbit) != 0)
128 throw;
129 }
130 }
131 return *this;
132 }
133
134 template<typename _CharT, typename _Traits>
135 basic_ostream<_CharT, _Traits>&
136 basic_ostream<_CharT, _Traits>::operator<<(long __n)
137 {
138 sentry __cerb(*this);
139 if (__cerb)
140 {
141 try {
142 bool __f;
143 ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
144 if (__fmt & ios_base::oct || __fmt & ios_base::hex)
145 __f = _M_fnumput->put(*this, *this, this->fill(),
146 static_cast<unsigned long>(__n)).failed();
147 else
148 __f = _M_fnumput->put(*this, *this, this->fill(), __n).failed();
149
150 if (__f)
151 this->setstate(ios_base::badbit);
152 }
153 catch(exception& __fail){
154 // 27.6.1.2.1 Common requirements.
155 // Turn this on without causing an ios::failure to be thrown.
156 this->setstate(ios_base::badbit);
157 if ((this->exceptions() & ios_base::badbit) != 0)
158 throw;
159 }
160 }
161 return *this;
162 }
163
164 template<typename _CharT, typename _Traits>
165 basic_ostream<_CharT, _Traits>&
166 basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n)
167 {
168 sentry __cerb(*this);
169 if (__cerb)
170 {
171 try {
172 if (_M_fnumput->put(*this, *this, this->fill(), __n).failed())
173 this->setstate(ios_base::badbit);
174 }
175 catch(exception& __fail){
176 // 27.6.1.2.1 Common requirements.
177 // Turn this on without causing an ios::failure to be thrown.
178 this->setstate(ios_base::badbit);
179 if ((this->exceptions() & ios_base::badbit) != 0)
180 throw;
181 }
182 }
183 return *this;
184 }
185
186#ifdef _GLIBCPP_USE_LONG_LONG
187 template<typename _CharT, typename _Traits>
188 basic_ostream<_CharT, _Traits>&
189 basic_ostream<_CharT, _Traits>::operator<<(long long __n)
190 {
191 sentry __cerb(*this);
192 if (__cerb)
193 {
194 try {
195 bool __f;
196 ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
197 if (__fmt & ios_base::oct || __fmt & ios_base::hex)
198 __f = _M_fnumput->put(*this, *this, this->fill(),
199 static_cast<unsigned long long>(__n)).failed();
200 else
201 __f = _M_fnumput->put(*this, *this, this->fill(), __n).failed();
202
203 }
204 catch(exception& __fail){
205 // 27.6.1.2.1 Common requirements.
206 // Turn this on without causing an ios::failure to be thrown.
207 this->setstate(ios_base::badbit);
208 if ((this->exceptions() & ios_base::badbit) != 0)
209 throw;
210 }
211 }
212 return *this;
213 }
214
215 template<typename _CharT, typename _Traits>
216 basic_ostream<_CharT, _Traits>&
217 basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n)
218 {
219 sentry __cerb(*this);
220 if (__cerb)
221 {
222 try {
223 if (_M_fnumput->put(*this, *this, this->fill(), __n).failed())
224 this->setstate(ios_base::badbit);
225 }
226 catch(exception& __fail){
227 // 27.6.1.2.1 Common requirements.
228 // Turn this on without causing an ios::failure to be thrown.
229 this->setstate(ios_base::badbit);
230 if ((this->exceptions() & ios_base::badbit) != 0)
231 throw;
232 }
233 }
234 return *this;
235 }
236#endif
237
238 template<typename _CharT, typename _Traits>
239 basic_ostream<_CharT, _Traits>&
240 basic_ostream<_CharT, _Traits>::operator<<(double __n)
241 {
242 sentry __cerb(*this);
243 if (__cerb)
244 {
245 try {
246 if (_M_fnumput->put(*this, *this, this->fill(), __n).failed())
247 this->setstate(ios_base::badbit);
248 }
249 catch(exception& __fail){
250 // 27.6.1.2.1 Common requirements.
251 // Turn this on without causing an ios::failure to be thrown.
252 this->setstate(ios_base::badbit);
253 if ((this->exceptions() & ios_base::badbit) != 0)
254 throw;
255 }
256 }
257 return *this;
258 }
259
260 template<typename _CharT, typename _Traits>
261 basic_ostream<_CharT, _Traits>&
262 basic_ostream<_CharT, _Traits>::operator<<(long double __n)
263 {
264 sentry __cerb(*this);
265 if (__cerb)
266 {
267 try {
268 if (_M_fnumput->put(*this, *this, this->fill(), __n).failed())
269 this->setstate(ios_base::badbit);
270 }
271 catch(exception& __fail){
272 // 27.6.1.2.1 Common requirements.
273 // Turn this on without causing an ios::failure to be thrown.
274 this->setstate(ios_base::badbit);
275 if ((this->exceptions() & ios_base::badbit) != 0)
276 throw;
277 }
278 }
279 return *this;
280 }
281
282 template<typename _CharT, typename _Traits>
283 basic_ostream<_CharT, _Traits>&
284 basic_ostream<_CharT, _Traits>::operator<<(const void* __n)
285 {
286 sentry __cerb(*this);
287 if (__cerb)
288 {
289 try {
290 if (_M_fnumput->put(*this, *this, this->fill(), __n).failed())
291 this->setstate(ios_base::badbit);
292 }
293 catch(exception& __fail){
294 // 27.6.1.2.1 Common requirements.
295 // Turn this on without causing an ios::failure to be thrown.
296 this->setstate(ios_base::badbit);
297 if ((this->exceptions() & ios_base::badbit) != 0)
298 throw;
299 }
300 }
301 return *this;
302 }
303
304 template<typename _CharT, typename _Traits>
305 basic_ostream<_CharT, _Traits>&
306 basic_ostream<_CharT, _Traits>::operator<<(__streambuf_type* __sbin)
307 {
308 streamsize __xtrct = 0;
309 __streambuf_type* __sbout = this->rdbuf();
310 sentry __cerb(*this);
311 if (__sbin && __cerb)
312 __xtrct = _S_copy_streambufs(*this, __sbin, __sbout);
313 if (!__sbin || !__xtrct)
314 this->setstate(ios_base::failbit);
315 return *this;
316 }
317
318 template<typename _CharT, typename _Traits>
319 basic_ostream<_CharT, _Traits>&
320 basic_ostream<_CharT, _Traits>::put(char_type __c)
321 {
322 sentry __cerb(*this);
323 if (__cerb)
324 {
325 int_type __put = rdbuf()->sputc(__c);
326 if (__put != traits_type::to_int_type(__c))
327 this->setstate(ios_base::badbit);
328 }
329 return *this;
330 }
331
332 template<typename _CharT, typename _Traits>
333 basic_ostream<_CharT, _Traits>&
334 basic_ostream<_CharT, _Traits>::write(const _CharT* __s, streamsize __n)
335 {
336 sentry __cerb(*this);
337 if (__cerb)
338 {
339 streamsize __put = this->rdbuf()->sputn(__s, __n);
340 if ( __put != __n)
341 this->setstate(ios_base::badbit);
342 }
343 return *this;
344 }
345
346 template<typename _CharT, typename _Traits>
347 basic_ostream<_CharT, _Traits>&
348 basic_ostream<_CharT, _Traits>::flush()
349 {
350 sentry __cerb(*this);
351 if (__cerb)
352 {
353 if (this->rdbuf() && this->rdbuf()->pubsync() == -1)
354 this->setstate(ios_base::badbit);
355 }
356 return *this;
357 }
358
359 template<typename _CharT, typename _Traits>
360 typename basic_ostream<_CharT, _Traits>::pos_type
361 basic_ostream<_CharT, _Traits>::tellp()
362 {
363 pos_type __ret = pos_type(-1);
364 bool __testok = this->fail() != true;
365
366 if (__testok)
367 __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
368 return __ret;
369 }
370
371
372 template<typename _CharT, typename _Traits>
373 basic_ostream<_CharT, _Traits>&
374 basic_ostream<_CharT, _Traits>::seekp(pos_type __pos)
375 {
376 bool __testok = this->fail() != true;
377
378 if (__testok)
379#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
380// 136. seekp, seekg setting wrong streams?
381 this->rdbuf()->pubseekpos(__pos, ios_base::out);
382#endif
383 return *this;
384 }
385
386 template<typename _CharT, typename _Traits>
387 basic_ostream<_CharT, _Traits>&
388 basic_ostream<_CharT, _Traits>::
389 seekp(off_type __off, ios_base::seekdir __d)
390 {
391 bool __testok = this->fail() != true;
392
393 if (__testok)
394#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
395// 136. seekp, seekg setting wrong streams?
396 rdbuf()->pubseekoff(__off, __d, ios_base::out);
397#endif
398 return *this;
399 }
400
401 // 27.6.2.5.4 Character inserters
402
403 // Construct correctly padded string, as per 22.2.2.2.2
404 // Similar in theory to _S_pad_numeric, from num_put, but it doesn't
405 // use _S_fill: perhaps it should.
406 // Assumes
407 // __newlen > __oldlen
408 // __news is allocated for __newlen size
409 template<typename _CharT, typename _Traits>
410 void
411 _S_pad_char(basic_ios<_CharT, _Traits>& __ios,
412 _CharT* __news, const _CharT* __olds,
413 const streamsize __newlen, const streamsize __oldlen)
414 {
415 typedef _CharT char_type;
416 typedef _Traits traits_type;
417 typedef typename traits_type::int_type int_type;
418
419 int_type __plen = static_cast<size_t>(__newlen - __oldlen);
420 char_type __pads[__plen];
421 traits_type::assign(__pads, __plen, __ios.fill());
422
423 char_type* __beg;
424 char_type* __end;
425 size_t __mod = 0;
426 size_t __beglen; //either __plen or __oldlen
427 ios_base::fmtflags __fmt = __ios.flags() & ios_base::adjustfield;
428
429 if (__fmt == ios_base::left)
430 {
431 // Padding last.
432 __beg = const_cast<char_type*>(__olds);
433 __beglen = __oldlen;
434 __end = __pads;
435 }
436 else if (__fmt == ios_base::internal)
437 {
438 // Pad after the sign, if there is one.
439 // Pad after 0[xX], if there is one.
440 // Who came up with these rules, anyway? Jeeze.
441 typedef _Format_cache<_CharT> __cache_type;
442 __cache_type const* __fmt = __cache_type::_S_get(__ios);
443 const char_type* __minus = traits_type::find(__olds, __oldlen,
444 __fmt->_S_minus);
445 const char_type* __plus = traits_type::find(__olds, __oldlen,
446 __fmt->_S_plus);
447 bool __testsign = __minus || __plus;
448 bool __testhex = __olds[0] == '0'
449 && (__olds[1] == 'x' || __olds[1] == 'X');
450
451 if (__testhex)
452 {
453 __news[0] = __olds[0];
454 __news[1] = __olds[1];
455 __mod += 2;
456 __beg = const_cast<char_type*>(__olds + __mod);
457 __beglen = __oldlen - __mod;
458 __end = __pads;
459 }
460 else if (__testsign)
461 {
462 __mod += __plen;
463 const char_type* __sign = __minus ? __minus + 1: __plus + 1;
464 __beg = const_cast<char_type*>(__olds);
465 __beglen = __sign - __olds;
466 __end = const_cast<char_type*>(__sign + __plen);
467 traits_type::copy(__news + __beglen, __pads, __plen);
468 }
469 else
470 {
471 // Padding first.
472 __beg = __pads;
473 __beglen = __plen;
474 __end = const_cast<char_type*>(__olds);
475 }
476 }
477 else
478 {
479 // Padding first.
480 __beg = __pads;
481 __beglen = __plen;
482 __end = const_cast<char_type*>(__olds);
483 }
484
485 traits_type::copy(__news, __beg, __beglen);
486 traits_type::copy(__news + __beglen, __end, __newlen - __beglen - __mod);
487 }
488
489 template<typename _CharT, typename _Traits>
490 basic_ostream<_CharT, _Traits>&
491 operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)
492 {
493 typedef basic_ostream<_CharT, _Traits> __ostream_type;
494 __ostream_type::sentry __cerb(__out);
495 if (__cerb)
496 {
497 try {
498 streamsize __w = __out.width();
499 _CharT __pads[__w];
500 __pads[0] = __c;
501 streamsize __len = 1;
502 if (__w > __len)
503 {
504 _S_pad_char(__out, __pads, &__c, __w, __len);
505 __len = __w;
506 }
507 __out.write(__pads, __len);
508 __out.width(0);
509 }
510 catch(exception& __fail){
511 // 27.6.1.2.1 Common requirements.
512 // Turn this on without causing an ios::failure to be thrown.
513 __out.setstate(ios_base::badbit);
514 if ((__out.exceptions() & ios_base::badbit) != 0)
515 throw;
516 }
517 }
518 return __out;
519 }
520
521 // Specialization
522 template <class _Traits>
523 basic_ostream<char, _Traits>&
524 operator<<(basic_ostream<char, _Traits>& __out, char __c)
525 {
526 typedef basic_ostream<char, _Traits> __ostream_type;
527 __ostream_type::sentry __cerb(__out);
528 if (__cerb)
529 {
530 try {
531 streamsize __w = __out.width();
532 char __pads[__w + 1];
533 __pads[0] = __c;
534 streamsize __len = 1;
535 if (__w > __len)
536 {
537 _S_pad_char(__out, __pads, &__c, __w, __len);
538 __len = __w;
539 }
540 __out.write(__pads, __len);
541 __out.width(0);
542 }
543 catch(exception& __fail){
544 // 27.6.1.2.1 Common requirements.
545 // Turn this on without causing an ios::failure to be thrown.
546 __out.setstate(ios_base::badbit);
547 if ((__out.exceptions() & ios_base::badbit) != 0)
548 throw;
549 }
550 }
551 return __out;
552 }
553
554 template<typename _CharT, typename _Traits>
555 basic_ostream<_CharT, _Traits>&
556 operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)
557 {
558 typedef basic_ostream<_CharT, _Traits> __ostream_type;
559 __ostream_type::sentry __cerb(__out);
560 if (__cerb)
561 {
562 try {
563 streamsize __w = __out.width();
564 _CharT __pads[__w];
565 streamsize __len = static_cast<streamsize>(_Traits::length(__s));
566 if (__w > __len)
567 {
568 _S_pad_char(__out, __pads, __s, __w, __len);
569 __s = __pads;
570 __len = __w;
571 }
572 __out.write(__s, __len);
573 __out.width(0);
574 }
575 catch(exception& __fail){
576 // 27.6.1.2.1 Common requirements.
577 // Turn this on without causing an ios::failure to be thrown.
578 __out.setstate(ios_base::badbit);
579 if ((__out.exceptions() & ios_base::badbit) != 0)
580 throw;
581 }
582 }
583 return __out;
584 }
585
586 template<typename _CharT, typename _Traits>
587 basic_ostream<_CharT, _Traits>&
588 operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)
589 {
590 typedef basic_ostream<_CharT, _Traits> __ostream_type;
591#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
592// 167. Improper use of traits_type::length()
593 typedef char_traits<char> __ctraits_type;
594#endif
595 __ostream_type::sentry __cerb(__out);
596 if (__cerb)
597 {
598 size_t __clen = __ctraits_type::length(__s);
599 _CharT __ws[__clen + 1];
600 for (size_t __i = 0; __i <= __clen; ++__i)
601 __ws[__i] = __out.widen(__s[__i]);
602 _CharT* __str = __ws;
603
604 try {
605 streamsize __len = static_cast<streamsize>(__clen);
606 streamsize __w = __out.width();
607 _CharT __pads[__w];
608
609 if (__w > __len)
610 {
611 _S_pad_char(__out, __pads, __ws, __w, __len);
612 __str = __pads;
613 __len = __w;
614 }
615 __out.write(__str, __len);
616 __out.width(0);
617 }
618 catch(exception& __fail){
619 // 27.6.1.2.1 Common requirements.
620 // Turn this on without causing an ios::failure to be thrown.
621 __out.setstate(ios_base::badbit);
622 if ((__out.exceptions() & ios_base::badbit) != 0)
623 throw;
624 }
625 }
626 return __out;
627 }
628
629 // Partial specializationss
630 template<class _Traits>
631 basic_ostream<char, _Traits>&
632 operator<<(basic_ostream<char, _Traits>& __out, const char* __s)
633 {
634 typedef basic_ostream<char, _Traits> __ostream_type;
635 __ostream_type::sentry __cerb(__out);
636 if (__cerb)
637 {
638 try {
639 streamsize __w = __out.width();
640 char __pads[__w];
641 streamsize __len = static_cast<streamsize>(_Traits::length(__s));
642 if (__w > __len)
643 {
644 _S_pad_char(__out, __pads, __s, __w, __len);
645 __s = __pads;
646 __len = __w;
647 }
648 __out.write(__s, __len);
649 __out.width(0);
650 }
651 catch(exception& __fail){
652 // 27.6.1.2.1 Common requirements.
653 // Turn this on without causing an ios::failure to be thrown.
654 __out.setstate(ios_base::badbit);
655 if ((__out.exceptions() & ios_base::badbit) != 0)
656 throw;
657 }
658 }
659 return __out;
660 }
661
662 // 21.3.7.8 basic_string::operator<<
663 template<typename _CharT, typename _Traits, typename _Alloc>
664 basic_ostream<_CharT, _Traits>&
665 operator<<(basic_ostream<_CharT, _Traits>& __out,
666 const basic_string<_CharT, _Traits, _Alloc>& __s)
667 { return (__out << __s.c_str()); }
668
669} // namespace std
670
671// Local Variables:
672// mode:C++
673// End:
674
675
676
677
678
679
680
681
682
683