This commit was manufactured by cvs2svn to create branch
[official-gcc.git] / libstdc++-v3 / include / bits / ostream.tcc
blob1ff14a66ae341739775e5b34004affc23ac9f149
1 // ostream classes -*- C++ -*-
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
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.
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.
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.
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.
32 // ISO C++ 14882: 27.6.2  Output streams
35 #ifndef _OSTREAM_TCC
36 #define _OSTREAM_TCC 1
38 #pragma GCC system_header
40 #include <locale>
42 namespace std
44   template<typename _CharT, typename _Traits>
45     basic_ostream<_CharT, _Traits>::sentry::
46     sentry(basic_ostream<_CharT, _Traits>& __os)
47     : _M_os(__os)
48     {
49       // XXX MT
50       if (__os.tie() && __os.good())
51         __os.tie()->flush();
53       if (__os.good())
54         _M_ok = true;
55       else
56         {
57           _M_ok = false;
58           __os.setstate(ios_base::failbit);
59         }
60     }
62   template<typename _CharT, typename _Traits>
63     basic_ostream<_CharT, _Traits>&
64     basic_ostream<_CharT, _Traits>::
65     operator<<(__ostream_type& (*__pf)(__ostream_type&))
66     {
67       // _GLIBCXX_RESOLVE_LIB_DEFECTS
68       // DR 60. What is a formatted input function?
69       // The inserters for manipulators are *not* formatted output functions.
70       return __pf(*this);
71     }
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       // _GLIBCXX_RESOLVE_LIB_DEFECTS
79       // DR 60. What is a formatted input function?
80       // The inserters for manipulators are *not* formatted output functions.
81       __pf(*this);
82       return *this;
83     }
85   template<typename _CharT, typename _Traits>
86     basic_ostream<_CharT, _Traits>&
87     basic_ostream<_CharT, _Traits>::
88     operator<<(ios_base& (*__pf)(ios_base&))
89     {
90       // _GLIBCXX_RESOLVE_LIB_DEFECTS
91       // DR 60. What is a formatted input function?
92       // The inserters for manipulators are *not* formatted output functions.
93       __pf(*this);
94       return *this;
95     }
97   template<typename _CharT, typename _Traits>
98     basic_ostream<_CharT, _Traits>&
99     basic_ostream<_CharT, _Traits>::
100     operator<<(bool __n)
101     {
102       sentry __cerb(*this);
103       if (__cerb)
104         {
105           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
106           try
107             {
108               const __num_put_type& __np = __check_facet(this->_M_num_put);
109               if (__np.put(*this, *this, this->fill(), __n).failed())
110                 __err |= ios_base::badbit;
111             }
112           catch(...)
113             { this->_M_setstate(ios_base::badbit); }
114           if (__err)
115             this->setstate(__err);
116         }
117       return *this;
118     }
120   template<typename _CharT, typename _Traits>
121     basic_ostream<_CharT, _Traits>&
122     basic_ostream<_CharT, _Traits>::
123     operator<<(long __n)
124     {
125       sentry __cerb(*this);
126       if (__cerb)
127         {
128           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
129           try
130             {
131               bool __b = false;
132               char_type __c = this->fill();
133               ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
134               const __num_put_type& __np = __check_facet(this->_M_num_put);
135               if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex))
136                 {
137                   unsigned long __l = static_cast<unsigned long>(__n);
138                   __b = __np.put(*this, *this, __c, __l).failed();
139                 }
140               else
141                 __b = __np.put(*this, *this, __c, __n).failed();
142               if (__b)
143                 __err |= ios_base::badbit;
144             }
145           catch(...)
146             { this->_M_setstate(ios_base::badbit); }
147           if (__err)
148             this->setstate(__err);
149         }
150       return *this;
151     }
153   template<typename _CharT, typename _Traits>
154     basic_ostream<_CharT, _Traits>&
155     basic_ostream<_CharT, _Traits>::
156     operator<<(unsigned long __n)
157     {
158       sentry __cerb(*this);
159       if (__cerb)
160         {
161           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
162           try
163             {
164               const __num_put_type& __np = __check_facet(this->_M_num_put);
165               if (__np.put(*this, *this, this->fill(), __n).failed())
166                 __err |= ios_base::badbit;
167             }
168           catch(...)
169             { this->_M_setstate(ios_base::badbit); }
170           if (__err)
171             this->setstate(__err);
172         }
173       return *this;
174     }
176 #ifdef _GLIBCXX_USE_LONG_LONG
177   template<typename _CharT, typename _Traits>
178     basic_ostream<_CharT, _Traits>&
179     basic_ostream<_CharT, _Traits>::
180     operator<<(long long __n)
181     {
182       sentry __cerb(*this);
183       if (__cerb)
184         {
185           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
186           try
187             {
188               bool __b = false;
189               char_type __c = this->fill();
190               ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
191               const __num_put_type& __np = __check_facet(this->_M_num_put);
192               if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex))
193                 {
194                   unsigned long long __l;
195                   __l = static_cast<unsigned long long>(__n);
196                   __b = __np.put(*this, *this, __c, __l).failed();
197                 }
198               else
199                 __b = __np.put(*this, *this, __c, __n).failed();
200               if (__b)
201                 __err |= ios_base::badbit;
202             }
203           catch(...)
204             { this->_M_setstate(ios_base::badbit); }
205           if (__err)
206             this->setstate(__err);
207         }
208       return *this;
209     }
211   template<typename _CharT, typename _Traits>
212     basic_ostream<_CharT, _Traits>&
213     basic_ostream<_CharT, _Traits>::
214     operator<<(unsigned long long __n)
215     {
216       sentry __cerb(*this);
217       if (__cerb)
218         {
219           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
220           try
221             {
222               const __num_put_type& __np = __check_facet(this->_M_num_put);
223               if (__np.put(*this, *this, this->fill(), __n).failed())
224                 __err |= ios_base::badbit;
225             }
226           catch(...)
227             { this->_M_setstate(ios_base::badbit); }
228           if (__err)
229             this->setstate(__err);
230         }
231       return *this;
232     }
233 #endif
235   template<typename _CharT, typename _Traits>
236     basic_ostream<_CharT, _Traits>&
237     basic_ostream<_CharT, _Traits>::
238     operator<<(double __n)
239     {
240       sentry __cerb(*this);
241       if (__cerb)
242         {
243           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
244           try
245             {
246               const __num_put_type& __np = __check_facet(this->_M_num_put);
247               if (__np.put(*this, *this, this->fill(), __n).failed())
248                 __err |= ios_base::badbit;
249             }
250           catch(...)
251             { this->_M_setstate(ios_base::badbit); }
252           if (__err)
253             this->setstate(__err);
254         }
255       return *this;
256     }
258   template<typename _CharT, typename _Traits>
259     basic_ostream<_CharT, _Traits>&
260     basic_ostream<_CharT, _Traits>::
261     operator<<(long double __n)
262     {
263       sentry __cerb(*this);
264       if (__cerb)
265         {
266           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
267           try
268             {
269               const __num_put_type& __np = __check_facet(this->_M_num_put);
270               if (__np.put(*this, *this, this->fill(), __n).failed())
271                 __err |= ios_base::badbit;
272             }
273           catch(...)
274             { this->_M_setstate(ios_base::badbit); }
275           if (__err)
276             this->setstate(__err);
277         }
278       return *this;
279     }
281   template<typename _CharT, typename _Traits>
282     basic_ostream<_CharT, _Traits>&
283     basic_ostream<_CharT, _Traits>::
284     operator<<(const void* __n)
285     {
286       sentry __cerb(*this);
287       if (__cerb)
288         {
289           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
290           try
291             {
292               const __num_put_type& __np = __check_facet(this->_M_num_put);
293               if (__np.put(*this, *this, this->fill(), __n).failed())
294                 __err |= ios_base::badbit;
295             }
296           catch(...)
297             { this->_M_setstate(ios_base::badbit); }
298           if (__err)
299             this->setstate(__err);
300         }
301       return *this;
302     }
304   template<typename _CharT, typename _Traits>
305     basic_ostream<_CharT, _Traits>&
306     basic_ostream<_CharT, _Traits>::
307     operator<<(__streambuf_type* __sbin)
308     {
309       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
310       sentry __cerb(*this);
311       if (__cerb && __sbin)
312         {
313           try
314             {
315               if (!__copy_streambufs(__sbin, this->rdbuf()))
316                 __err |= ios_base::failbit;
317             }
318           catch(...)
319             { this->_M_setstate(ios_base::failbit); }
320         }
321       else if (!__sbin)
322         __err |= ios_base::badbit;
323       if (__err)
324         this->setstate(__err);
325       return *this;
326     }
328   template<typename _CharT, typename _Traits>
329     basic_ostream<_CharT, _Traits>&
330     basic_ostream<_CharT, _Traits>::
331     put(char_type __c)
332     {
333       // _GLIBCXX_RESOLVE_LIB_DEFECTS
334       // DR 60. What is a formatted input function?
335       // basic_ostream::put(char_type) is an unformatted output function.
336       // DR 63. Exception-handling policy for unformatted output.
337       // Unformatted output functions should catch exceptions thrown
338       // from streambuf members.
339       sentry __cerb(*this);
340       if (__cerb)
341         {
342           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
343           try
344             {
345               int_type __put = this->rdbuf()->sputc(__c);
346               if (traits_type::eq_int_type(__put, traits_type::eof()))
347                 __err |= ios_base::badbit;
348             }
349           catch (...)
350             { this->_M_setstate(ios_base::badbit); }
351           if (__err)
352             this->setstate(__err);
353         }
354       return *this;
355     }
357   template<typename _CharT, typename _Traits>
358     basic_ostream<_CharT, _Traits>&
359     basic_ostream<_CharT, _Traits>::
360     write(const _CharT* __s, streamsize __n)
361     {
362       // _GLIBCXX_RESOLVE_LIB_DEFECTS
363       // DR 60. What is a formatted input function?
364       // basic_ostream::write(const char_type*, streamsize) is an
365       // unformatted output function.
366       // DR 63. Exception-handling policy for unformatted output.
367       // Unformatted output functions should catch exceptions thrown
368       // from streambuf members.
369       sentry __cerb(*this);
370       if (__cerb)
371         {
372           try
373             { _M_write(__s, __n); }
374           catch (...)
375             { this->_M_setstate(ios_base::badbit); }
376         }
377       return *this;
378     }
380   template<typename _CharT, typename _Traits>
381     basic_ostream<_CharT, _Traits>&
382     basic_ostream<_CharT, _Traits>::
383     flush()
384     {
385       // _GLIBCXX_RESOLVE_LIB_DEFECTS
386       // DR 60. What is a formatted input function?
387       // basic_ostream::flush() is *not* an unformatted output function.
388       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
389       try
390         {
391           if (this->rdbuf() && this->rdbuf()->pubsync() == -1)
392             __err |= ios_base::badbit;
393         }
394       catch(...)
395         { this->_M_setstate(ios_base::badbit); }
396       if (__err)
397         this->setstate(__err);
398       return *this;
399     }
401   template<typename _CharT, typename _Traits>
402     typename basic_ostream<_CharT, _Traits>::pos_type
403     basic_ostream<_CharT, _Traits>::
404     tellp()
405     {
406       pos_type __ret = pos_type(-1);
407       try
408         {
409           if (!this->fail())
410             __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
411         }
412       catch(...)
413         { this->_M_setstate(ios_base::badbit); }
414       return __ret;
415     }
417   template<typename _CharT, typename _Traits>
418     basic_ostream<_CharT, _Traits>&
419     basic_ostream<_CharT, _Traits>::
420     seekp(pos_type __pos)
421     {
422       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
423       try
424         {
425           if (!this->fail())
426             {
427               // _GLIBCXX_RESOLVE_LIB_DEFECTS
428               // 136.  seekp, seekg setting wrong streams?
429               pos_type __p = this->rdbuf()->pubseekpos(__pos, ios_base::out);
431               // 129. Need error indication from seekp() and seekg()
432               if (__p == pos_type(off_type(-1)))
433                 __err |= ios_base::failbit;
434             }
435         }
436       catch(...)
437         { this->_M_setstate(ios_base::badbit); }
438       if (__err)
439         this->setstate(__err);
440       return *this;
441     }
443   template<typename _CharT, typename _Traits>
444     basic_ostream<_CharT, _Traits>&
445     basic_ostream<_CharT, _Traits>::
446     seekp(off_type __off, ios_base::seekdir __dir)
447     {
448       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
449       try
450         {
451           if (!this->fail())
452             {
453               // _GLIBCXX_RESOLVE_LIB_DEFECTS
454               // 136.  seekp, seekg setting wrong streams?
455               pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
456                                                        ios_base::out);
458               // 129. Need error indication from seekp() and seekg()
459               if (__p == pos_type(off_type(-1)))
460                 __err |= ios_base::failbit;
461             }
462         }
463       catch(...)
464         { this->_M_setstate(ios_base::badbit); }
465       if (__err)
466         this->setstate(__err);
467       return *this;
468     }
470   // 27.6.2.5.4 Character inserters.
471   template<typename _CharT, typename _Traits>
472     basic_ostream<_CharT, _Traits>&
473     operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)
474     {
475       typedef basic_ostream<_CharT, _Traits> __ostream_type;
476       typename __ostream_type::sentry __cerb(__out);
477       if (__cerb)
478         {
479           try
480             {
481               const streamsize __w = __out.width();
482               streamsize __len = 1;
483               _CharT* __cs = &__c;
484               if (__w > __len)
485                 {
486                   __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
487                                                                * __w));
488                   __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs,
489                                                  &__c, __w, __len, false);
490                   __len = __w;
491                 }
492               __out._M_write(__cs, __len);
493               __out.width(0);
494             }
495           catch(...)
496             { __out._M_setstate(ios_base::badbit); }
497         }
498       return __out;
499     }
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               const streamsize __w = __out.width();
513               streamsize __len = 1;
514               char* __cs = &__c;
515               if (__w > __len)
516                 {
517                   __cs = static_cast<char*>(__builtin_alloca(__w));
518                   __pad<char, _Traits>::_S_pad(__out, __out.fill(), __cs,
519                                                &__c, __w, __len, false);
520                   __len = __w;
521                 }
522               __out._M_write(__cs, __len);
523               __out.width(0);
524             }
525           catch(...)
526             { __out._M_setstate(ios_base::badbit); }
527         }
528       return __out;
529      }
531   template<typename _CharT, typename _Traits>
532     basic_ostream<_CharT, _Traits>&
533     operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)
534     {
535       typedef basic_ostream<_CharT, _Traits> __ostream_type;
536       typename __ostream_type::sentry __cerb(__out);
537       if (__cerb && __s)
538         {
539           try
540             {
541               const streamsize __w = __out.width();
542               streamsize __len = static_cast<streamsize>(_Traits::length(__s));
543               if (__w > __len)
544                 {
545                   _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
546                                                                        * __w));
547                   __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs,
548                                                  __s, __w, __len, false);
549                   __s = __cs;
550                   __len = __w;
551                 }
552               __out._M_write(__s, __len);
553               __out.width(0);
554             }
555           catch(...)
556             { __out._M_setstate(ios_base::badbit); }
557         }
558       else if (!__s)
559         __out.setstate(ios_base::badbit);
560       return __out;
561     }
563   template<typename _CharT, typename _Traits>
564     basic_ostream<_CharT, _Traits>&
565     operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)
566     {
567       typedef basic_ostream<_CharT, _Traits> __ostream_type;
568       // _GLIBCXX_RESOLVE_LIB_DEFECTS
569       // 167.  Improper use of traits_type::length()
570       // Note that this is only in 'Review' status.
571       typedef char_traits<char>              __traits_type;
572       typename __ostream_type::sentry __cerb(__out);
573       if (__cerb && __s)
574         {
575           size_t __clen = __traits_type::length(__s);
576           _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
577                                                                * __clen));
578           for (size_t  __i = 0; __i < __clen; ++__i)
579             __ws[__i] = __out.widen(__s[__i]);
580           _CharT* __str = __ws;
582           try
583             {
584               const streamsize __w = __out.width();
585               streamsize __len = static_cast<streamsize>(__clen);
586               if (__w > __len)
587                 {
588                   _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
589                                                                        * __w));
590                   __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs,
591                                                  __ws, __w, __len, false);
592                   __str = __cs;
593                   __len = __w;
594                 }
595               __out._M_write(__str, __len);
596               __out.width(0);
597             }
598           catch(...)
599             { __out._M_setstate(ios_base::badbit); }
600         }
601       else if (!__s)
602         __out.setstate(ios_base::badbit);
603       return __out;
604     }
606   // Partial specializations.
607   template<class _Traits>
608     basic_ostream<char, _Traits>&
609     operator<<(basic_ostream<char, _Traits>& __out, const char* __s)
610     {
611       typedef basic_ostream<char, _Traits> __ostream_type;
612       typename __ostream_type::sentry __cerb(__out);
613       if (__cerb && __s)
614         {
615           try
616             {
617               const streamsize __w = __out.width();
618               streamsize __len = static_cast<streamsize>(_Traits::length(__s));
619               if (__w > __len)
620                 {
621                   char* __cs = static_cast<char*>(__builtin_alloca(__w));
622                   __pad<char, _Traits>::_S_pad(__out, __out.fill(), __cs,
623                                                  __s, __w, __len, false);
624                   __s = __cs;
625                   __len = __w;
626                 }
627               __out._M_write(__s, __len);
628               __out.width(0);
629             }
630           catch(...)
631             { __out._M_setstate(ios_base::badbit); }
632         }
633       else if (!__s)
634         __out.setstate(ios_base::badbit);
635       return __out;
636     }
638   // 21.3.7.9 basic_string::operator<<
639   template<typename _CharT, typename _Traits, typename _Alloc>
640     basic_ostream<_CharT, _Traits>&
641     operator<<(basic_ostream<_CharT, _Traits>& __out,
642                const basic_string<_CharT, _Traits, _Alloc>& __str)
643     {
644       typedef basic_ostream<_CharT, _Traits> __ostream_type;
645       typename __ostream_type::sentry __cerb(__out);
646       if (__cerb)
647         {
648           const streamsize __w = __out.width();
649           streamsize __len = static_cast<streamsize>(__str.size());
650           const _CharT* __s = __str.data();
652           // _GLIBCXX_RESOLVE_LIB_DEFECTS
653           // 25. String operator<< uses width() value wrong
654           if (__w > __len)
655             {
656               _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w));
657               __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs, __s,
658                                              __w, __len, false);
659               __s = __cs;
660               __len = __w;
661             }
662           __out._M_write(__s, __len);
663           __out.width(0);
664         }
665       return __out;
666     }
668   // Inhibit implicit instantiations for required instantiations,
669   // which are defined via explicit instantiations elsewhere.
670   // NB:  This syntax is a GNU extension.
671 #if _GLIBCXX_EXTERN_TEMPLATE
672   extern template class basic_ostream<char>;
673   extern template ostream& endl(ostream&);
674   extern template ostream& ends(ostream&);
675   extern template ostream& flush(ostream&);
676   extern template ostream& operator<<(ostream&, char);
677   extern template ostream& operator<<(ostream&, unsigned char);
678   extern template ostream& operator<<(ostream&, signed char);
679   extern template ostream& operator<<(ostream&, const char*);
680   extern template ostream& operator<<(ostream&, const unsigned char*);
681   extern template ostream& operator<<(ostream&, const signed char*);
683 #ifdef _GLIBCXX_USE_WCHAR_T
684   extern template class basic_ostream<wchar_t>;
685   extern template wostream& endl(wostream&);
686   extern template wostream& ends(wostream&);
687   extern template wostream& flush(wostream&);
688   extern template wostream& operator<<(wostream&, wchar_t);
689   extern template wostream& operator<<(wostream&, char);
690   extern template wostream& operator<<(wostream&, const wchar_t*);
691   extern template wostream& operator<<(wostream&, const char*);
692 #endif
693 #endif
694 } // namespace std
696 #endif