OSDN Git Service

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