2017-10-17 Paolo Carlini <paolo.carlini@oracle.com>
[official-gcc.git] / libstdc++-v3 / include / bits / ostream.tcc
blobe96bad8121000470fd6dcfc77c946d1d1ec08bd5
1 // ostream classes -*- C++ -*-
3 // Copyright (C) 1997-2017 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
25 /** @file bits/ostream.tcc
26  *  This is an internal header file, included by other library headers.
27  *  Do not attempt to use it directly. @headername{ostream}
28  */
31 // ISO C++ 14882: 27.6.2  Output streams
34 #ifndef _OSTREAM_TCC
35 #define _OSTREAM_TCC 1
37 #pragma GCC system_header
39 #include <bits/cxxabi_forced.h>
41 namespace std _GLIBCXX_VISIBILITY(default)
43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
45   template<typename _CharT, typename _Traits>
46     basic_ostream<_CharT, _Traits>::sentry::
47     sentry(basic_ostream<_CharT, _Traits>& __os)
48     : _M_ok(false), _M_os(__os)
49     {
50       // XXX MT
51       if (__os.tie() && __os.good())
52         __os.tie()->flush();
54       if (__os.good())
55         _M_ok = true;
56       else
57         __os.setstate(ios_base::failbit);
58     }
60   template<typename _CharT, typename _Traits>
61     template<typename _ValueT>
62       basic_ostream<_CharT, _Traits>&
63       basic_ostream<_CharT, _Traits>::
64       _M_insert(_ValueT __v)
65       {
66         sentry __cerb(*this);
67         if (__cerb)
68           {
69             ios_base::iostate __err = ios_base::goodbit;
70             __try
71               {
72                 const __num_put_type& __np = __check_facet(this->_M_num_put);
73                 if (__np.put(*this, *this, this->fill(), __v).failed())
74                   __err |= ios_base::badbit;
75               }
76             __catch(__cxxabiv1::__forced_unwind&)
77               {
78                 this->_M_setstate(ios_base::badbit);            
79                 __throw_exception_again;
80               }
81             __catch(...)
82               { this->_M_setstate(ios_base::badbit); }
83             if (__err)
84               this->setstate(__err);
85           }
86         return *this;
87       }
89   template<typename _CharT, typename _Traits>
90     basic_ostream<_CharT, _Traits>&
91     basic_ostream<_CharT, _Traits>::
92     operator<<(short __n)
93     {
94       // _GLIBCXX_RESOLVE_LIB_DEFECTS
95       // 117. basic_ostream uses nonexistent num_put member functions.
96       const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
97       if (__fmt == ios_base::oct || __fmt == ios_base::hex)
98         return _M_insert(static_cast<long>(static_cast<unsigned short>(__n)));
99       else
100         return _M_insert(static_cast<long>(__n));
101     }
103   template<typename _CharT, typename _Traits>
104     basic_ostream<_CharT, _Traits>&
105     basic_ostream<_CharT, _Traits>::
106     operator<<(int __n)
107     {
108       // _GLIBCXX_RESOLVE_LIB_DEFECTS
109       // 117. basic_ostream uses nonexistent num_put member functions.
110       const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
111       if (__fmt == ios_base::oct || __fmt == ios_base::hex)
112         return _M_insert(static_cast<long>(static_cast<unsigned int>(__n)));
113       else
114         return _M_insert(static_cast<long>(__n));
115     }
116   
117   template<typename _CharT, typename _Traits>
118     basic_ostream<_CharT, _Traits>&
119     basic_ostream<_CharT, _Traits>::
120     operator<<(__streambuf_type* __sbin)
121     {
122       ios_base::iostate __err = ios_base::goodbit;
123       sentry __cerb(*this);
124       if (__cerb && __sbin)
125         {
126           __try
127             {
128               if (!__copy_streambufs(__sbin, this->rdbuf()))
129                 __err |= ios_base::failbit;
130             }
131           __catch(__cxxabiv1::__forced_unwind&)
132             {
133               this->_M_setstate(ios_base::badbit);              
134               __throw_exception_again;
135             }
136           __catch(...)
137             { this->_M_setstate(ios_base::failbit); }
138         }
139       else if (!__sbin)
140         __err |= ios_base::badbit;
141       if (__err)
142         this->setstate(__err);
143       return *this;
144     }
146   template<typename _CharT, typename _Traits>
147     basic_ostream<_CharT, _Traits>&
148     basic_ostream<_CharT, _Traits>::
149     put(char_type __c)
150     {
151       // _GLIBCXX_RESOLVE_LIB_DEFECTS
152       // DR 60. What is a formatted input function?
153       // basic_ostream::put(char_type) is an unformatted output function.
154       // DR 63. Exception-handling policy for unformatted output.
155       // Unformatted output functions should catch exceptions thrown
156       // from streambuf members.
157       sentry __cerb(*this);
158       if (__cerb)
159         {
160           ios_base::iostate __err = ios_base::goodbit;
161           __try
162             {
163               const int_type __put = this->rdbuf()->sputc(__c);
164               if (traits_type::eq_int_type(__put, traits_type::eof()))
165                 __err |= ios_base::badbit;
166             }
167           __catch(__cxxabiv1::__forced_unwind&)
168             {
169               this->_M_setstate(ios_base::badbit);              
170               __throw_exception_again;
171             }
172           __catch(...)
173             { this->_M_setstate(ios_base::badbit); }
174           if (__err)
175             this->setstate(__err);
176         }
177       return *this;
178     }
180   template<typename _CharT, typename _Traits>
181     basic_ostream<_CharT, _Traits>&
182     basic_ostream<_CharT, _Traits>::
183     write(const _CharT* __s, streamsize __n)
184     {
185       // _GLIBCXX_RESOLVE_LIB_DEFECTS
186       // DR 60. What is a formatted input function?
187       // basic_ostream::write(const char_type*, streamsize) is an
188       // unformatted output function.
189       // DR 63. Exception-handling policy for unformatted output.
190       // Unformatted output functions should catch exceptions thrown
191       // from streambuf members.
192       sentry __cerb(*this);
193       if (__cerb)
194         {
195           __try
196             { _M_write(__s, __n); }
197           __catch(__cxxabiv1::__forced_unwind&)
198             {
199               this->_M_setstate(ios_base::badbit);              
200               __throw_exception_again;
201             }
202           __catch(...)
203             { this->_M_setstate(ios_base::badbit); }
204         }
205       return *this;
206     }
208   template<typename _CharT, typename _Traits>
209     basic_ostream<_CharT, _Traits>&
210     basic_ostream<_CharT, _Traits>::
211     flush()
212     {
213       // _GLIBCXX_RESOLVE_LIB_DEFECTS
214       // DR 60. What is a formatted input function?
215       // basic_ostream::flush() is *not* an unformatted output function.
216       ios_base::iostate __err = ios_base::goodbit;
217       __try
218         {
219           if (this->rdbuf() && this->rdbuf()->pubsync() == -1)
220             __err |= ios_base::badbit;
221         }
222       __catch(__cxxabiv1::__forced_unwind&)
223         {
224           this->_M_setstate(ios_base::badbit);          
225           __throw_exception_again;
226         }
227       __catch(...)
228         { this->_M_setstate(ios_base::badbit); }
229       if (__err)
230         this->setstate(__err);
231       return *this;
232     }
234   template<typename _CharT, typename _Traits>
235     typename basic_ostream<_CharT, _Traits>::pos_type
236     basic_ostream<_CharT, _Traits>::
237     tellp()
238     {
239       pos_type __ret = pos_type(-1);
240       __try
241         {
242           if (!this->fail())
243             __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
244         }
245       __catch(__cxxabiv1::__forced_unwind&)
246         {
247           this->_M_setstate(ios_base::badbit);          
248           __throw_exception_again;
249         }
250       __catch(...)
251         { this->_M_setstate(ios_base::badbit); }
252       return __ret;
253     }
255   template<typename _CharT, typename _Traits>
256     basic_ostream<_CharT, _Traits>&
257     basic_ostream<_CharT, _Traits>::
258     seekp(pos_type __pos)
259     {
260       ios_base::iostate __err = ios_base::goodbit;
261       __try
262         {
263           if (!this->fail())
264             {
265               // _GLIBCXX_RESOLVE_LIB_DEFECTS
266               // 136.  seekp, seekg setting wrong streams?
267               const pos_type __p = this->rdbuf()->pubseekpos(__pos,
268                                                              ios_base::out);
270               // 129. Need error indication from seekp() and seekg()
271               if (__p == pos_type(off_type(-1)))
272                 __err |= ios_base::failbit;
273             }
274         }
275       __catch(__cxxabiv1::__forced_unwind&)
276         {
277           this->_M_setstate(ios_base::badbit);          
278           __throw_exception_again;
279         }
280       __catch(...)
281         { this->_M_setstate(ios_base::badbit); }
282       if (__err)
283         this->setstate(__err);
284       return *this;
285     }
287   template<typename _CharT, typename _Traits>
288     basic_ostream<_CharT, _Traits>&
289     basic_ostream<_CharT, _Traits>::
290     seekp(off_type __off, ios_base::seekdir __dir)
291     {
292       ios_base::iostate __err = ios_base::goodbit;
293       __try
294         {
295           if (!this->fail())
296             {
297               // _GLIBCXX_RESOLVE_LIB_DEFECTS
298               // 136.  seekp, seekg setting wrong streams?
299               const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
300                                                              ios_base::out);
302               // 129. Need error indication from seekp() and seekg()
303               if (__p == pos_type(off_type(-1)))
304                 __err |= ios_base::failbit;
305             }
306         }
307       __catch(__cxxabiv1::__forced_unwind&)
308         {
309           this->_M_setstate(ios_base::badbit);          
310           __throw_exception_again;
311         }
312       __catch(...)
313         { this->_M_setstate(ios_base::badbit); }
314       if (__err)
315         this->setstate(__err);
316       return *this;
317     }
319   template<typename _CharT, typename _Traits>
320     basic_ostream<_CharT, _Traits>&
321     operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)
322     {
323       if (!__s)
324         __out.setstate(ios_base::badbit);
325       else
326         {
327           // _GLIBCXX_RESOLVE_LIB_DEFECTS
328           // 167.  Improper use of traits_type::length()
329           const size_t __clen = char_traits<char>::length(__s);
330           __try
331             {
332               struct __ptr_guard
333               {
334                 _CharT *__p;
335                 __ptr_guard (_CharT *__ip): __p(__ip) { }
336                 ~__ptr_guard() { delete[] __p; }
337                 _CharT* __get() { return __p; }
338               } __pg (new _CharT[__clen]);
340               _CharT *__ws = __pg.__get();
341               for (size_t  __i = 0; __i < __clen; ++__i)
342                 __ws[__i] = __out.widen(__s[__i]);
343               __ostream_insert(__out, __ws, __clen);
344             }
345           __catch(__cxxabiv1::__forced_unwind&)
346             {
347               __out._M_setstate(ios_base::badbit);
348               __throw_exception_again;
349             }
350           __catch(...)
351             { __out._M_setstate(ios_base::badbit); }
352         }
353       return __out;
354     }
356   // Inhibit implicit instantiations for required instantiations,
357   // which are defined via explicit instantiations elsewhere.
358 #if _GLIBCXX_EXTERN_TEMPLATE
359   extern template class basic_ostream<char>;
360   extern template ostream& endl(ostream&);
361   extern template ostream& ends(ostream&);
362   extern template ostream& flush(ostream&);
363   extern template ostream& operator<<(ostream&, char);
364   extern template ostream& operator<<(ostream&, unsigned char);
365   extern template ostream& operator<<(ostream&, signed char);
366   extern template ostream& operator<<(ostream&, const char*);
367   extern template ostream& operator<<(ostream&, const unsigned char*);
368   extern template ostream& operator<<(ostream&, const signed char*);
370   extern template ostream& ostream::_M_insert(long);
371   extern template ostream& ostream::_M_insert(unsigned long);
372   extern template ostream& ostream::_M_insert(bool);
373 #ifdef _GLIBCXX_USE_LONG_LONG
374   extern template ostream& ostream::_M_insert(long long);
375   extern template ostream& ostream::_M_insert(unsigned long long);
376 #endif
377   extern template ostream& ostream::_M_insert(double);
378   extern template ostream& ostream::_M_insert(long double);
379   extern template ostream& ostream::_M_insert(const void*);
381 #ifdef _GLIBCXX_USE_WCHAR_T
382   extern template class basic_ostream<wchar_t>;
383   extern template wostream& endl(wostream&);
384   extern template wostream& ends(wostream&);
385   extern template wostream& flush(wostream&);
386   extern template wostream& operator<<(wostream&, wchar_t);
387   extern template wostream& operator<<(wostream&, char);
388   extern template wostream& operator<<(wostream&, const wchar_t*);
389   extern template wostream& operator<<(wostream&, const char*);
391   extern template wostream& wostream::_M_insert(long);
392   extern template wostream& wostream::_M_insert(unsigned long);
393   extern template wostream& wostream::_M_insert(bool);
394 #ifdef _GLIBCXX_USE_LONG_LONG
395   extern template wostream& wostream::_M_insert(long long);
396   extern template wostream& wostream::_M_insert(unsigned long long);
397 #endif
398   extern template wostream& wostream::_M_insert(double);
399   extern template wostream& wostream::_M_insert(long double);
400   extern template wostream& wostream::_M_insert(const void*);
401 #endif
402 #endif
404 _GLIBCXX_END_NAMESPACE_VERSION
405 } // namespace std
407 #endif