3 * Silicon Graphics Computer Systems, Inc.
8 * This material is provided "as is", with absolutely no warranty expressed
9 * or implied. Any use is at your own risk.
11 * Permission to use or copy this software for any purpose is hereby granted
12 * without fee, provided the above notices are retained on all copies.
13 * Permission to modify the code and to distribute modified code is granted,
14 * provided the above notices are retained, and a notice that the code was
15 * modified is included with the above copyright notice.
18 #ifndef _STLP_OSTREAM_C
19 #define _STLP_OSTREAM_C
21 #ifndef _STLP_INTERNAL_OSTREAM_H
22 # include <stl/_ostream.h>
25 #if !defined (_STLP_INTERNAL_NUM_PUT_H)
26 # include <stl/_num_put.h> // For basic_streambuf and iterators
31 //----------------------------------------------------------------------
32 // Definitions of non-inline member functions.
34 // Constructor, destructor
36 template <class _CharT
, class _Traits
>
37 basic_ostream
<_CharT
, _Traits
>::basic_ostream(basic_streambuf
<_CharT
, _Traits
>* __buf
)
38 : basic_ios
<_CharT
, _Traits
>() {
42 template <class _CharT
, class _Traits
>
43 basic_ostream
<_CharT
, _Traits
>::~basic_ostream()
46 // Output directly from a streambuf.
47 template <class _CharT
, class _Traits
>
48 basic_ostream
<_CharT
, _Traits
>&
49 basic_ostream
<_CharT
, _Traits
>::operator<<(basic_streambuf
<_CharT
, _Traits
>* __from
) {
50 sentry
__sentry(*this);
53 bool __any_inserted
= __from
->gptr() != __from
->egptr()
54 ? this->_M_copy_buffered(__from
, this->rdbuf())
55 : this->_M_copy_unbuffered(__from
, this->rdbuf());
57 this->setstate(ios_base::failbit
);
60 this->setstate(ios_base::badbit
);
66 // Helper functions for the streambuf version of operator<<. The
67 // exception-handling code is complicated because exceptions thrown
68 // while extracting characters are treated differently than exceptions
69 // thrown while inserting characters.
71 template <class _CharT
, class _Traits
>
72 bool basic_ostream
<_CharT
, _Traits
>
73 ::_M_copy_buffered(basic_streambuf
<_CharT
, _Traits
>* __from
,
74 basic_streambuf
<_CharT
, _Traits
>* __to
) {
75 bool __any_inserted
= false;
77 while (__from
->egptr() != __from
->gptr()) {
78 const ptrdiff_t __avail
= __from
->egptr() - __from
->gptr();
80 streamsize __nwritten
;
82 __nwritten
= __to
->sputn(__from
->gptr(), __avail
);
83 __from
->gbump((int)__nwritten
);
86 this->_M_handle_exception(ios_base::badbit
);
87 return __any_inserted
;
90 if (__nwritten
== __avail
) {
92 if (this->_S_eof(__from
->sgetc()))
95 __any_inserted
= true;
98 this->_M_handle_exception(ios_base::failbit
);
102 else if (__nwritten
!= 0)
105 return __any_inserted
;
108 // No characters are in the buffer, but we aren't at EOF. Switch to
110 return __any_inserted
|| this->_M_copy_unbuffered(__from
, __to
);
114 * Helper struct (guard) to put back a character in a streambuf
115 * whenever an exception or an eof occur.
117 template <class _CharT
, class _Traits
>
119 typedef basic_streambuf
<_CharT
, _Traits
> _StreamBuf
;
120 typedef typename
_StreamBuf::int_type int_type
;
121 _SPutBackC(_StreamBuf
*pfrom
)
122 : __pfrom(pfrom
), __c(0), __do_guard(false) {}
125 __pfrom
->sputbackc(_Traits::to_char_type(__c
));
129 void guard(int_type c
) {
143 template <class _CharT
, class _Traits
>
144 bool basic_ostream
<_CharT
, _Traits
>
145 ::_M_copy_unbuffered(basic_streambuf
<_CharT
, _Traits
>* __from
,
146 basic_streambuf
<_CharT
, _Traits
>* __to
) {
147 typedef _SPutBackC
<_CharT
, _Traits
> _SPutBackCGuard
;
148 bool __any_inserted
= false;
152 _SPutBackCGuard
__cguard(__from
);
155 __c
= __from
->sbumpc();
158 this->_M_handle_exception(ios_base::failbit
);
162 if (this->_S_eof(__c
))
166 #if defined (__DMC__)
169 if (this->_S_eof(__to
->sputc(_Traits::to_char_type(__c
))))
172 #if defined (__DMC__)
175 this->_M_handle_exception(ios_base::badbit
);
180 __any_inserted
= true;
184 this->_M_handle_exception(ios_base::badbit
);
186 return __any_inserted
;
189 _STLP_MOVE_TO_PRIV_NAMESPACE
191 // Helper function for numeric output.
192 template <class _CharT
, class _Traits
, class _Number
>
193 basic_ostream
<_CharT
, _Traits
>& _STLP_CALL
194 __put_num(basic_ostream
<_CharT
, _Traits
>& __os
, _Number __x
) {
195 typedef typename basic_ostream
<_CharT
, _Traits
>::sentry _Sentry
;
196 _Sentry
__sentry(__os
);
197 bool __failed
= true;
201 typedef num_put
<_CharT
, ostreambuf_iterator
<_CharT
, _Traits
> > _NumPut
;
202 __failed
= (use_facet
<_NumPut
>(__os
.getloc())).put(ostreambuf_iterator
<_CharT
, _Traits
>(__os
.rdbuf()),
207 __os
._M_handle_exception(ios_base::badbit
);
211 __os
.setstate(ios_base::badbit
);
215 _STLP_MOVE_TO_STD_NAMESPACE
218 * In the following operators we try to limit code bloat by limiting the
219 * number of __put_num instanciations.
221 template <class _CharT
, class _Traits
>
222 basic_ostream
<_CharT
, _Traits
>& basic_ostream
<_CharT
, _Traits
>::operator<<(short __x
) {
223 _STLP_STATIC_ASSERT( sizeof(short) <= sizeof(long) )
224 long __tmp
= ((this->flags() & _Basic_ios::basefield
) != ios_base::dec
) ?
225 __STATIC_CAST(long, __STATIC_CAST(unsigned short, __x
)): __x
;
226 return _STLP_PRIV
__put_num(*this, __tmp
);
229 template <class _CharT
, class _Traits
>
230 basic_ostream
<_CharT
, _Traits
>& basic_ostream
<_CharT
, _Traits
>::operator<<(unsigned short __x
) {
231 _STLP_STATIC_ASSERT( sizeof(unsigned short) <= sizeof(unsigned long) )
232 return _STLP_PRIV
__put_num(*this, __STATIC_CAST(unsigned long,__x
));
235 template <class _CharT
, class _Traits
>
236 basic_ostream
<_CharT
, _Traits
>& basic_ostream
<_CharT
, _Traits
>::operator<<(int __x
) {
237 _STLP_STATIC_ASSERT( sizeof(int) <= sizeof(long) )
238 long __tmp
= ((this->flags() & _Basic_ios::basefield
) != ios_base::dec
) ?
239 __STATIC_CAST(long, __STATIC_CAST(unsigned int, __x
)): __x
;
240 return _STLP_PRIV
__put_num(*this, __tmp
);
243 template <class _CharT
, class _Traits
>
244 #if defined (_WIN64) || !defined (_STLP_MSVC) || (_STLP_MSVC < 1300)
245 basic_ostream
<_CharT
, _Traits
>& basic_ostream
<_CharT
, _Traits
>::operator<<(unsigned int __x
) {
246 _STLP_STATIC_ASSERT( sizeof(unsigned int) <= sizeof(unsigned long) )
248 /* We define this operator with size_t rather than unsigned int to avoid
251 basic_ostream
<_CharT
, _Traits
>& basic_ostream
<_CharT
, _Traits
>::operator<<(size_t __x
) {
252 _STLP_STATIC_ASSERT( sizeof(size_t) <= sizeof(unsigned long) )
254 return _STLP_PRIV
__put_num(*this, __STATIC_CAST(unsigned long,__x
));
257 template <class _CharT
, class _Traits
>
258 basic_ostream
<_CharT
, _Traits
>& basic_ostream
<_CharT
, _Traits
>::operator<<(long __x
)
259 { return _STLP_PRIV
__put_num(*this, __x
); }
261 template <class _CharT
, class _Traits
>
262 basic_ostream
<_CharT
, _Traits
>& basic_ostream
<_CharT
, _Traits
>::operator<<(unsigned long __x
)
263 { return _STLP_PRIV
__put_num(*this, __x
); }
265 #ifdef _STLP_LONG_LONG
266 template <class _CharT
, class _Traits
>
267 basic_ostream
<_CharT
, _Traits
>& basic_ostream
<_CharT
, _Traits
>::operator<< (_STLP_LONG_LONG __x
)
268 { return _STLP_PRIV
__put_num(*this, __x
); }
270 template <class _CharT
, class _Traits
>
271 basic_ostream
<_CharT
, _Traits
>& basic_ostream
<_CharT
, _Traits
>::operator<< (unsigned _STLP_LONG_LONG __x
)
272 { return _STLP_PRIV
__put_num(*this, __x
); }
275 template <class _CharT
, class _Traits
>
276 basic_ostream
<_CharT
, _Traits
>& basic_ostream
<_CharT
, _Traits
>::operator<<(float __x
)
277 { return _STLP_PRIV
__put_num(*this, __STATIC_CAST(double,__x
)); }
279 template <class _CharT
, class _Traits
>
280 basic_ostream
<_CharT
, _Traits
>& basic_ostream
<_CharT
, _Traits
>::operator<<(double __x
)
281 { return _STLP_PRIV
__put_num(*this, __x
); }
283 #ifndef _STLP_NO_LONG_DOUBLE
284 template <class _CharT
, class _Traits
>
285 basic_ostream
<_CharT
, _Traits
>& basic_ostream
<_CharT
, _Traits
>::operator<<(long double __x
)
286 { return _STLP_PRIV
__put_num(*this, __x
); }
289 template <class _CharT
, class _Traits
>
290 basic_ostream
<_CharT
, _Traits
>& basic_ostream
<_CharT
, _Traits
>::operator<<(const void* __x
)
291 { return _STLP_PRIV
__put_num(*this, __x
); }
293 #ifndef _STLP_NO_BOOL
294 template <class _CharT
, class _Traits
>
295 basic_ostream
<_CharT
, _Traits
>& basic_ostream
<_CharT
, _Traits
>::operator<<(bool __x
)
296 { return _STLP_PRIV
__put_num(*this, __x
); }
299 template <class _CharT
, class _Traits
>
300 void basic_ostream
<_CharT
, _Traits
>::_M_put_char(_CharT __c
) {
301 sentry
__sentry(*this);
303 bool __failed
= true;
305 streamsize __npad
= this->width() > 0 ? this->width() - 1 : 0;
308 __failed
= this->_S_eof(this->rdbuf()->sputc(__c
));
309 else if ((this->flags() & ios_base::adjustfield
) == ios_base::left
) {
310 __failed
= this->_S_eof(this->rdbuf()->sputc(__c
));
311 __failed
= __failed
||
312 this->rdbuf()->_M_sputnc(this->fill(), __npad
) != __npad
;
315 __failed
= this->rdbuf()->_M_sputnc(this->fill(), __npad
) != __npad
;
316 __failed
= __failed
|| this->_S_eof(this->rdbuf()->sputc(__c
));
322 this->_M_handle_exception(ios_base::badbit
);
326 this->setstate(ios_base::badbit
);
330 template <class _CharT
, class _Traits
>
331 void basic_ostream
<_CharT
, _Traits
>::_M_put_nowiden(const _CharT
* __s
) {
332 sentry
__sentry(*this);
334 bool __failed
= true;
335 streamsize __n
= _Traits::length(__s
);
336 streamsize __npad
= this->width() > __n
? this->width() - __n
: 0;
340 __failed
= this->rdbuf()->sputn(__s
, __n
) != __n
;
341 else if ((this->flags() & ios_base::adjustfield
) == ios_base::left
) {
342 __failed
= this->rdbuf()->sputn(__s
, __n
) != __n
;
343 __failed
= __failed
||
344 this->rdbuf()->_M_sputnc(this->fill(), __npad
) != __npad
;
347 __failed
= this->rdbuf()->_M_sputnc(this->fill(), __npad
) != __npad
;
348 __failed
= __failed
|| this->rdbuf()->sputn(__s
, __n
) != __n
;
354 this->_M_handle_exception(ios_base::badbit
);
358 this->setstate(ios_base::failbit
);
362 template <class _CharT
, class _Traits
>
363 void basic_ostream
<_CharT
, _Traits
>::_M_put_widen(const char* __s
) {
364 sentry
__sentry(*this);
366 bool __failed
= true;
367 streamsize __n
= char_traits
<char>::length(__s
);
368 streamsize __npad
= this->width() > __n
? this->width() - __n
: 0;
372 __failed
= !this->_M_put_widen_aux(__s
, __n
);
373 else if ((this->flags() & ios_base::adjustfield
) == ios_base::left
) {
374 __failed
= !this->_M_put_widen_aux(__s
, __n
);
375 __failed
= __failed
||
376 this->rdbuf()->_M_sputnc(this->fill(), __npad
) != __npad
;
379 __failed
= this->rdbuf()->_M_sputnc(this->fill(), __npad
) != __npad
;
380 __failed
= __failed
|| !this->_M_put_widen_aux(__s
, __n
);
386 this->_M_handle_exception(ios_base::badbit
);
390 this->setstate(ios_base::failbit
);
394 template <class _CharT
, class _Traits
>
395 bool basic_ostream
<_CharT
, _Traits
>::_M_put_widen_aux(const char* __s
,
397 basic_streambuf
<_CharT
, _Traits
>* __buf
= this->rdbuf();
399 for ( ; __n
> 0 ; --__n
)
400 if (this->_S_eof(__buf
->sputc(this->widen(*__s
++))))
405 // Unformatted output of a single character.
406 template <class _CharT
, class _Traits
>
407 basic_ostream
<_CharT
, _Traits
>&
408 basic_ostream
<_CharT
, _Traits
>::put(char_type __c
) {
409 sentry
__sentry(*this);
410 bool __failed
= true;
414 __failed
= this->_S_eof(this->rdbuf()->sputc(__c
));
417 this->_M_handle_exception(ios_base::badbit
);
422 this->setstate(ios_base::badbit
);
427 // Unformatted output of a single character.
428 template <class _CharT
, class _Traits
>
429 basic_ostream
<_CharT
, _Traits
>&
430 basic_ostream
<_CharT
, _Traits
>::write(const char_type
* __s
, streamsize __n
) {
431 sentry
__sentry(*this);
432 bool __failed
= true;
436 __failed
= this->rdbuf()->sputn(__s
, __n
) != __n
;
439 this->_M_handle_exception(ios_base::badbit
);
444 this->setstate(ios_base::badbit
);
451 #endif /* _STLP_OSTREAM_C */