Merge from mainline
[official-gcc.git] / libstdc++-v3 / include / bits / ostream.tcc
blob7f9fbcfb077459e4f5219e72125bba8cc657c6a6
1 // ostream classes -*- C++ -*-
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
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.
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  */
37 // ISO C++ 14882: 27.6.2  Output streams
40 #ifndef _OSTREAM_TCC
41 #define _OSTREAM_TCC 1
43 #pragma GCC system_header
45 #include <locale>
47 _GLIBCXX_BEGIN_NAMESPACE(std)
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();
58       if (__os.good())
59         _M_ok = true;
60       else
61         __os.setstate(ios_base::failbit);
62     }
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     }
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     }
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     }
99   template<typename _CharT, typename _Traits>
100     template<typename _ValueT>
101       basic_ostream<_CharT, _Traits>&
102       basic_ostream<_CharT, _Traits>::
103       _M_insert(_ValueT __v)
104       {
105         sentry __cerb(*this);
106         if (__cerb)
107           {
108             ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
109             try
110               {
111                 const __num_put_type& __np = __check_facet(this->_M_num_put);
112                 if (__np.put(*this, *this, this->fill(), __v).failed())
113                   __err |= ios_base::badbit;
114               }
115             catch(...)
116               { this->_M_setstate(ios_base::badbit); }
117             if (__err)
118               this->setstate(__err);
119           }
120         return *this;
121       }
123   template<typename _CharT, typename _Traits>
124     basic_ostream<_CharT, _Traits>&
125     basic_ostream<_CharT, _Traits>::
126     operator<<(short __n)
127     {
128       // _GLIBCXX_RESOLVE_LIB_DEFECTS
129       // 117. basic_ostream uses nonexistent num_put member functions.
130       const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
131       if (__fmt == ios_base::oct || __fmt == ios_base::hex)
132         return _M_insert(static_cast<long>(static_cast<unsigned short>(__n)));
133       else
134         return _M_insert(static_cast<long>(__n));
135     }
137   template<typename _CharT, typename _Traits>
138     basic_ostream<_CharT, _Traits>&
139     basic_ostream<_CharT, _Traits>::
140     operator<<(int __n)
141     {
142       // _GLIBCXX_RESOLVE_LIB_DEFECTS
143       // 117. basic_ostream uses nonexistent num_put member functions.
144       const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
145       if (__fmt == ios_base::oct || __fmt == ios_base::hex)
146         return _M_insert(static_cast<long>(static_cast<unsigned int>(__n)));
147       else
148         return _M_insert(static_cast<long>(__n));
149     }
150   
151   template<typename _CharT, typename _Traits>
152     basic_ostream<_CharT, _Traits>&
153     basic_ostream<_CharT, _Traits>::
154     operator<<(__streambuf_type* __sbin)
155     {
156       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
157       sentry __cerb(*this);
158       if (__cerb && __sbin)
159         {
160           try
161             {
162               if (!__copy_streambufs(__sbin, this->rdbuf()))
163                 __err |= ios_base::failbit;
164             }
165           catch(...)
166             { this->_M_setstate(ios_base::failbit); }
167         }
168       else if (!__sbin)
169         __err |= ios_base::badbit;
170       if (__err)
171         this->setstate(__err);
172       return *this;
173     }
175   template<typename _CharT, typename _Traits>
176     basic_ostream<_CharT, _Traits>&
177     basic_ostream<_CharT, _Traits>::
178     put(char_type __c)
179     {
180       // _GLIBCXX_RESOLVE_LIB_DEFECTS
181       // DR 60. What is a formatted input function?
182       // basic_ostream::put(char_type) is an unformatted output function.
183       // DR 63. Exception-handling policy for unformatted output.
184       // Unformatted output functions should catch exceptions thrown
185       // from streambuf members.
186       sentry __cerb(*this);
187       if (__cerb)
188         {
189           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
190           try
191             {
192               const int_type __put = this->rdbuf()->sputc(__c);
193               if (traits_type::eq_int_type(__put, traits_type::eof()))
194                 __err |= ios_base::badbit;
195             }
196           catch (...)
197             { this->_M_setstate(ios_base::badbit); }
198           if (__err)
199             this->setstate(__err);
200         }
201       return *this;
202     }
204   template<typename _CharT, typename _Traits>
205     basic_ostream<_CharT, _Traits>&
206     basic_ostream<_CharT, _Traits>::
207     write(const _CharT* __s, streamsize __n)
208     {
209       // _GLIBCXX_RESOLVE_LIB_DEFECTS
210       // DR 60. What is a formatted input function?
211       // basic_ostream::write(const char_type*, streamsize) is an
212       // unformatted output function.
213       // DR 63. Exception-handling policy for unformatted output.
214       // Unformatted output functions should catch exceptions thrown
215       // from streambuf members.
216       sentry __cerb(*this);
217       if (__cerb)
218         {
219           try
220             { _M_write(__s, __n); }
221           catch (...)
222             { this->_M_setstate(ios_base::badbit); }
223         }
224       return *this;
225     }
227   template<typename _CharT, typename _Traits>
228     basic_ostream<_CharT, _Traits>&
229     basic_ostream<_CharT, _Traits>::
230     flush()
231     {
232       // _GLIBCXX_RESOLVE_LIB_DEFECTS
233       // DR 60. What is a formatted input function?
234       // basic_ostream::flush() is *not* an unformatted output function.
235       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
236       try
237         {
238           if (this->rdbuf() && this->rdbuf()->pubsync() == -1)
239             __err |= ios_base::badbit;
240         }
241       catch(...)
242         { this->_M_setstate(ios_base::badbit); }
243       if (__err)
244         this->setstate(__err);
245       return *this;
246     }
248   template<typename _CharT, typename _Traits>
249     typename basic_ostream<_CharT, _Traits>::pos_type
250     basic_ostream<_CharT, _Traits>::
251     tellp()
252     {
253       pos_type __ret = pos_type(-1);
254       try
255         {
256           if (!this->fail())
257             __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
258         }
259       catch(...)
260         { this->_M_setstate(ios_base::badbit); }
261       return __ret;
262     }
264   template<typename _CharT, typename _Traits>
265     basic_ostream<_CharT, _Traits>&
266     basic_ostream<_CharT, _Traits>::
267     seekp(pos_type __pos)
268     {
269       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
270       try
271         {
272           if (!this->fail())
273             {
274               // _GLIBCXX_RESOLVE_LIB_DEFECTS
275               // 136.  seekp, seekg setting wrong streams?
276               const pos_type __p = this->rdbuf()->pubseekpos(__pos,
277                                                              ios_base::out);
279               // 129. Need error indication from seekp() and seekg()
280               if (__p == pos_type(off_type(-1)))
281                 __err |= ios_base::failbit;
282             }
283         }
284       catch(...)
285         { this->_M_setstate(ios_base::badbit); }
286       if (__err)
287         this->setstate(__err);
288       return *this;
289     }
291   template<typename _CharT, typename _Traits>
292     basic_ostream<_CharT, _Traits>&
293     basic_ostream<_CharT, _Traits>::
294     seekp(off_type __off, ios_base::seekdir __dir)
295     {
296       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
297       try
298         {
299           if (!this->fail())
300             {
301               // _GLIBCXX_RESOLVE_LIB_DEFECTS
302               // 136.  seekp, seekg setting wrong streams?
303               const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
304                                                              ios_base::out);
306               // 129. Need error indication from seekp() and seekg()
307               if (__p == pos_type(off_type(-1)))
308                 __err |= ios_base::failbit;
309             }
310         }
311       catch(...)
312         { this->_M_setstate(ios_base::badbit); }
313       if (__err)
314         this->setstate(__err);
315       return *this;
316     }
318   // 27.6.2.5.4 Character inserters.
319   template<typename _CharT, typename _Traits>
320     basic_ostream<_CharT, _Traits>&
321     operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)
322     {
323       typedef basic_ostream<_CharT, _Traits> __ostream_type;
324       typename __ostream_type::sentry __cerb(__out);
325       if (__cerb)
326         {
327           try
328             {
329               const streamsize __w = __out.width();
330               streamsize __len = 1;
331               _CharT* __cs = &__c;
332               if (__w > __len)
333                 {
334                   __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
335                                                                * __w));
336                   __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs,
337                                                  &__c, __w, __len, false);
338                   __len = __w;
339                 }
340               __out._M_write(__cs, __len);
341               __out.width(0);
342             }
343           catch(...)
344             { __out._M_setstate(ios_base::badbit); }
345         }
346       return __out;
347     }
349   // Specializations.
350   template <class _Traits>
351     basic_ostream<char, _Traits>&
352     operator<<(basic_ostream<char, _Traits>& __out, char __c)
353     {
354       typedef basic_ostream<char, _Traits> __ostream_type;
355       typename __ostream_type::sentry __cerb(__out);
356       if (__cerb)
357         {
358           try
359             {
360               const streamsize __w = __out.width();
361               streamsize __len = 1;
362               char* __cs = &__c;
363               if (__w > __len)
364                 {
365                   __cs = static_cast<char*>(__builtin_alloca(__w));
366                   __pad<char, _Traits>::_S_pad(__out, __out.fill(), __cs,
367                                                &__c, __w, __len, false);
368                   __len = __w;
369                 }
370               __out._M_write(__cs, __len);
371               __out.width(0);
372             }
373           catch(...)
374             { __out._M_setstate(ios_base::badbit); }
375         }
376       return __out;
377      }
379   template<typename _CharT, typename _Traits>
380     basic_ostream<_CharT, _Traits>&
381     operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)
382     {
383       typedef basic_ostream<_CharT, _Traits> __ostream_type;
384       typename __ostream_type::sentry __cerb(__out);
385       if (__cerb && __s)
386         {
387           try
388             {
389               const streamsize __w = __out.width();
390               streamsize __len = static_cast<streamsize>(_Traits::length(__s));
391               if (__w > __len)
392                 {
393                   _CharT* __cs = (static_cast<
394                                   _CharT*>(__builtin_alloca(sizeof(_CharT)
395                                                             * __w)));
396                   __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs,
397                                                  __s, __w, __len, false);
398                   __s = __cs;
399                   __len = __w;
400                 }
401               __out._M_write(__s, __len);
402               __out.width(0);
403             }
404           catch(...)
405             { __out._M_setstate(ios_base::badbit); }
406         }
407       else if (!__s)
408         __out.setstate(ios_base::badbit);
409       return __out;
410     }
412   template<typename _CharT, typename _Traits>
413     basic_ostream<_CharT, _Traits>&
414     operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)
415     {
416       typedef basic_ostream<_CharT, _Traits> __ostream_type;
417       // _GLIBCXX_RESOLVE_LIB_DEFECTS
418       // 167.  Improper use of traits_type::length()
419       // Note that this is only in 'Review' status.
420       typedef char_traits<char>              __traits_type;
421       typename __ostream_type::sentry __cerb(__out);
422       if (__cerb && __s)
423         {
424           size_t __clen = __traits_type::length(__s);
425           _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
426                                                                * __clen));
427           for (size_t  __i = 0; __i < __clen; ++__i)
428             __ws[__i] = __out.widen(__s[__i]);
429           _CharT* __str = __ws;
431           try
432             {
433               const streamsize __w = __out.width();
434               streamsize __len = static_cast<streamsize>(__clen);
435               if (__w > __len)
436                 {
437                   _CharT* __cs = (static_cast<
438                                   _CharT*>(__builtin_alloca(sizeof(_CharT)
439                                                             * __w)));
440                   __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs,
441                                                  __ws, __w, __len, false);
442                   __str = __cs;
443                   __len = __w;
444                 }
445               __out._M_write(__str, __len);
446               __out.width(0);
447             }
448           catch(...)
449             { __out._M_setstate(ios_base::badbit); }
450         }
451       else if (!__s)
452         __out.setstate(ios_base::badbit);
453       return __out;
454     }
456   // Partial specializations.
457   template<class _Traits>
458     basic_ostream<char, _Traits>&
459     operator<<(basic_ostream<char, _Traits>& __out, const char* __s)
460     {
461       typedef basic_ostream<char, _Traits> __ostream_type;
462       typename __ostream_type::sentry __cerb(__out);
463       if (__cerb && __s)
464         {
465           try
466             {
467               const streamsize __w = __out.width();
468               streamsize __len = static_cast<streamsize>(_Traits::length(__s));
469               if (__w > __len)
470                 {
471                   char* __cs = static_cast<char*>(__builtin_alloca(__w));
472                   __pad<char, _Traits>::_S_pad(__out, __out.fill(), __cs,
473                                                  __s, __w, __len, false);
474                   __s = __cs;
475                   __len = __w;
476                 }
477               __out._M_write(__s, __len);
478               __out.width(0);
479             }
480           catch(...)
481             { __out._M_setstate(ios_base::badbit); }
482         }
483       else if (!__s)
484         __out.setstate(ios_base::badbit);
485       return __out;
486     }
488   // 21.3.7.9 basic_string::operator<<
489   template<typename _CharT, typename _Traits, typename _Alloc>
490     basic_ostream<_CharT, _Traits>&
491     operator<<(basic_ostream<_CharT, _Traits>& __out,
492                const basic_string<_CharT, _Traits, _Alloc>& __str)
493     {
494       typedef basic_ostream<_CharT, _Traits> __ostream_type;
495       typename __ostream_type::sentry __cerb(__out);
496       if (__cerb)
497         {
498           const streamsize __w = __out.width();
499           streamsize __len = static_cast<streamsize>(__str.size());
500           const _CharT* __s = __str.data();
502           // _GLIBCXX_RESOLVE_LIB_DEFECTS
503           // 25. String operator<< uses width() value wrong
504           if (__w > __len)
505             {
506               _CharT* __cs = (static_cast<
507                               _CharT*>(__builtin_alloca(sizeof(_CharT) * __w)));
508               __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs, __s,
509                                              __w, __len, false);
510               __s = __cs;
511               __len = __w;
512             }
513           __out._M_write(__s, __len);
514           __out.width(0);
515         }
516       return __out;
517     }
519   // Inhibit implicit instantiations for required instantiations,
520   // which are defined via explicit instantiations elsewhere.
521   // NB:  This syntax is a GNU extension.
522 #if _GLIBCXX_EXTERN_TEMPLATE
523   extern template class basic_ostream<char>;
524   extern template ostream& endl(ostream&);
525   extern template ostream& ends(ostream&);
526   extern template ostream& flush(ostream&);
527   extern template ostream& operator<<(ostream&, char);
528   extern template ostream& operator<<(ostream&, unsigned char);
529   extern template ostream& operator<<(ostream&, signed char);
530   extern template ostream& operator<<(ostream&, const char*);
531   extern template ostream& operator<<(ostream&, const unsigned char*);
532   extern template ostream& operator<<(ostream&, const signed char*);
534 #ifdef _GLIBCXX_USE_WCHAR_T
535   extern template class basic_ostream<wchar_t>;
536   extern template wostream& endl(wostream&);
537   extern template wostream& ends(wostream&);
538   extern template wostream& flush(wostream&);
539   extern template wostream& operator<<(wostream&, wchar_t);
540   extern template wostream& operator<<(wostream&, char);
541   extern template wostream& operator<<(wostream&, const wchar_t*);
542   extern template wostream& operator<<(wostream&, const char*);
543 #endif
544 #endif
546 _GLIBCXX_END_NAMESPACE
548 #endif