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