|
|
|
1 |
|
// ostream standard header |
2 |
|
#pragma once |
3 |
|
#ifndef _OSTREAM_ |
4 |
|
#define _OSTREAM_ |
5 |
|
#ifndef RC_INVOKED |
6 |
|
#include <ios> |
7 |
|
|
8 |
|
#ifdef _MSC_VER |
9 |
|
#pragma pack(push,_CRT_PACKING) |
10 |
|
#pragma warning(push,3) |
11 |
|
#pragma warning(disable: 4390) |
12 |
|
#endif /* _MSC_VER */ |
13 |
|
|
14 |
|
_STD_BEGIN |
15 |
|
|
16 |
|
// I/O EXCEPTION MACROS |
17 |
|
|
18 |
|
#if _HAS_EXCEPTIONS |
19 |
|
#define _TRY_IO_BEGIN _TRY_BEGIN /* begin try block */ |
20 |
|
|
21 |
|
#define _CATCH_IO_END _CATCH_ALL /* catch block for _Myios */ \ |
22 |
|
_Myios::setstate(ios_base::badbit, true); /* set badbit and rethrow */ \ |
23 |
|
_CATCH_END |
24 |
|
|
25 |
|
#define _CATCH_IO_(x) _CATCH_ALL /* catch block for basic_ios x */ \ |
26 |
|
(x).setstate(ios_base::badbit, true); /* set badbit and rethrow */ \ |
27 |
|
_CATCH_END |
28 |
|
|
29 |
|
#else /* _HAS_EXCEPTIONS */ |
30 |
|
#define _TRY_IO_BEGIN { /* begin try block */ |
31 |
|
|
32 |
|
#define _CATCH_IO_END } /* catch block for _Myios */ |
33 |
|
|
34 |
|
#define _CATCH_IO_(x) } /* catch block for basic_ios x */ |
35 |
|
#endif /* _HAS_EXCEPTIONS */ |
36 |
|
|
37 |
|
// TEMPLATE CLASS basic_ostream |
38 |
|
template<class _Elem, |
39 |
|
class _Traits> |
40 |
|
class basic_ostream |
41 |
|
: virtual public basic_ios<_Elem, _Traits> |
42 |
|
{ // control insertions into a stream buffer |
43 |
|
public: |
44 |
|
typedef basic_ostream<_Elem, _Traits> _Myt; |
45 |
|
typedef basic_ios<_Elem, _Traits> _Myios; |
46 |
|
typedef basic_streambuf<_Elem, _Traits> _Mysb; |
47 |
|
typedef ostreambuf_iterator<_Elem, _Traits> _Iter; |
48 |
|
typedef num_put<_Elem, _Iter> _Nput; |
49 |
|
|
50 |
|
explicit __CLR_OR_THIS_CALL basic_ostream(basic_streambuf<_Elem, _Traits> *_Strbuf, |
51 |
|
bool _Isstd = false) |
52 |
|
{ // construct from a stream buffer pointer |
53 |
|
_Myios::init(_Strbuf, _Isstd); |
54 |
|
} |
55 |
|
|
56 |
|
__CLR_OR_THIS_CALL basic_ostream(_Uninitialized, bool _Addit = true) |
57 |
|
{ // construct uninitialized |
58 |
|
if (_Addit) |
59 |
|
ios_base::_Addstd(this); // suppress for basic_iostream |
60 |
|
} |
61 |
|
|
62 |
|
virtual __CLR_OR_THIS_CALL ~basic_ostream() |
63 |
|
{ // destroy the object |
64 |
|
} |
65 |
|
|
66 |
|
typedef typename _Traits::int_type int_type; |
67 |
|
typedef typename _Traits::pos_type pos_type; |
68 |
|
typedef typename _Traits::off_type off_type; |
69 |
|
|
70 |
|
class _Sentry_base |
71 |
|
{ // stores thread lock and reference to output stream |
72 |
|
public: |
73 |
|
__CLR_OR_THIS_CALL _Sentry_base(_Myt& _Ostr) |
74 |
|
: _Myostr(_Ostr) |
75 |
|
{ // lock the stream buffer, if there |
76 |
|
if (_Myostr.rdbuf() != 0) |
77 |
|
_Myostr.rdbuf()->_Lock(); |
78 |
|
} |
79 |
|
|
80 |
|
__CLR_OR_THIS_CALL ~_Sentry_base() |
81 |
|
{ // destroy after unlocking |
82 |
|
if (_Myostr.rdbuf() != 0) |
83 |
|
_Myostr.rdbuf()->_Unlock(); |
84 |
|
} |
85 |
|
|
86 |
|
_Myt& _Myostr; // the output stream, for _Unlock call at destruction |
87 |
|
}; |
88 |
|
|
89 |
|
class sentry |
90 |
|
: public _Sentry_base |
91 |
|
{ // stores thread lock and state of stream |
92 |
|
public: |
93 |
|
explicit __CLR_OR_THIS_CALL sentry(_Myt& _Ostr) |
94 |
|
: _Sentry_base(_Ostr) |
95 |
|
{ // construct locking and testing stream |
96 |
|
if (_Ostr.good() && _Ostr.tie() != 0) |
97 |
|
_Ostr.tie()->flush(); |
98 |
|
_Ok = _Ostr.good(); // store test only after flushing tie |
99 |
|
} |
100 |
|
|
101 |
|
__CLR_OR_THIS_CALL ~sentry() |
102 |
|
{ // destroy the object |
103 |
|
|
104 |
|
#if _HAS_EXCEPTIONS |
105 |
|
if (!_XSTD uncaught_exception()) |
106 |
|
this->_Myostr._Osfx(); |
107 |
|
} |
108 |
|
|
109 |
|
#else /* _HAS_EXCEPTIONS */ |
110 |
|
this->_Myostr._Osfx(); |
111 |
|
} |
112 |
|
#endif /* _HAS_EXCEPTIONS */ |
113 |
|
|
114 |
|
__CLR_OR_THIS_CALL operator bool() const |
115 |
|
{ // test if stream state okay |
116 |
|
return (_Ok); |
117 |
|
} |
118 |
|
|
119 |
|
private: |
120 |
|
__CLR_OR_THIS_CALL sentry(const sentry&); // not defined |
121 |
|
sentry& __CLR_OR_THIS_CALL operator=(const sentry&); // not defined |
122 |
|
|
123 |
|
bool _Ok; // true if stream state okay at construction |
124 |
|
}; |
125 |
|
|
126 |
|
bool __CLR_OR_THIS_CALL opfx() |
127 |
|
{ // test stream state and flush tie stream as needed (retained) |
128 |
|
if (ios_base::good() && _Myios::tie() != 0) |
129 |
|
_Myios::tie()->flush(); |
130 |
|
return (ios_base::good()); |
131 |
|
} |
132 |
|
|
133 |
|
void __CLR_OR_THIS_CALL osfx() |
134 |
|
{ // perform any wrapup (retained) |
135 |
|
_Osfx(); |
136 |
|
} |
137 |
|
|
138 |
|
void __CLR_OR_THIS_CALL _Osfx() |
139 |
|
{ // perform any wrapup |
140 |
|
_TRY_BEGIN |
141 |
|
if (ios_base::flags() & ios_base::unitbuf) |
142 |
|
flush(); // flush stream as needed |
143 |
|
_CATCH_ALL |
144 |
|
_CATCH_END |
145 |
|
} |
146 |
|
|
147 |
|
#ifdef _M_CEE_PURE |
148 |
|
_Myt& __CLR_OR_THIS_CALL operator<<(_Myt& (__clrcall *_Pfn)(_Myt&)) |
149 |
|
{ // call basic_ostream manipulator |
150 |
|
_DEBUG_POINTER(_Pfn); |
151 |
|
return ((*_Pfn)(*this)); |
152 |
|
} |
153 |
|
|
154 |
|
_Myt& __CLR_OR_THIS_CALL operator<<(_Myios& (__clrcall *_Pfn)(_Myios&)) |
155 |
|
{ // call basic_ios manipulator |
156 |
|
_DEBUG_POINTER(_Pfn); |
157 |
|
(*_Pfn)(*(_Myios *)this); |
158 |
|
return (*this); |
159 |
|
} |
160 |
|
|
161 |
|
_Myt& __CLR_OR_THIS_CALL operator<<(ios_base& (__clrcall *_Pfn)(ios_base&)) |
162 |
|
{ // call ios_base manipulator |
163 |
|
_DEBUG_POINTER(_Pfn); |
164 |
|
(*_Pfn)(*(ios_base *)this); |
165 |
|
return (*this); |
166 |
|
} |
167 |
|
|
168 |
|
#endif |
169 |
|
|
170 |
|
_Myt& __CLR_OR_THIS_CALL operator<<(_Myt& (__cdecl *_Pfn)(_Myt&)) |
171 |
|
{ // call basic_ostream manipulator |
172 |
|
_DEBUG_POINTER(_Pfn); |
173 |
|
return ((*_Pfn)(*this)); |
174 |
|
} |
175 |
|
|
176 |
|
_Myt& __CLR_OR_THIS_CALL operator<<(_Myios& (__cdecl *_Pfn)(_Myios&)) |
177 |
|
{ // call basic_ios manipulator |
178 |
|
_DEBUG_POINTER(_Pfn); |
179 |
|
(*_Pfn)(*(_Myios *)this); |
180 |
|
return (*this); |
181 |
|
} |
182 |
|
|
183 |
|
_Myt& __CLR_OR_THIS_CALL operator<<(ios_base& (__cdecl *_Pfn)(ios_base&)) |
184 |
|
{ // call ios_base manipulator |
185 |
|
_DEBUG_POINTER(_Pfn); |
186 |
|
(*_Pfn)(*(ios_base *)this); |
187 |
|
return (*this); |
188 |
|
} |
189 |
|
|
190 |
|
_Myt& __CLR_OR_THIS_CALL operator<<(_Bool _Val) |
191 |
|
{ // insert a boolean |
192 |
|
ios_base::iostate _State = ios_base::goodbit; |
193 |
|
const sentry _Ok(*this); |
194 |
|
|
195 |
|
if (_Ok) |
196 |
|
{ // state okay, use facet to insert |
197 |
|
const _Nput& _Nput_fac = _USE(ios_base::getloc(), _Nput); |
198 |
|
|
199 |
|
_TRY_IO_BEGIN |
200 |
|
if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, |
201 |
|
_Myios::fill(), _Val).failed()) |
202 |
|
_State |= ios_base::badbit; |
203 |
|
_CATCH_IO_END |
204 |
|
} |
205 |
|
|
206 |
|
_Myios::setstate(_State); |
207 |
|
return (*this); |
208 |
|
} |
209 |
|
|
210 |
|
_Myt& __CLR_OR_THIS_CALL operator<<(short _Val) |
211 |
|
{ // insert a short |
212 |
|
ios_base::iostate _State = ios_base::goodbit; |
213 |
|
const sentry _Ok(*this); |
214 |
|
|
215 |
|
if (_Ok) |
216 |
|
{ // state okay, use facet to insert |
217 |
|
const _Nput& _Nput_fac = _USE(ios_base::getloc(), _Nput); |
218 |
|
ios_base::fmtflags _Bfl = |
219 |
|
ios_base::flags() & ios_base::basefield; |
220 |
|
long _Tmp = (_Bfl == ios_base::oct |
221 |
|
|| _Bfl == ios_base::hex) |
222 |
|
? (long)(unsigned short)_Val : (long)_Val; |
223 |
|
|
224 |
|
_TRY_IO_BEGIN |
225 |
|
if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, |
226 |
|
_Myios::fill(), _Tmp).failed()) |
227 |
|
_State |= ios_base::badbit; |
228 |
|
_CATCH_IO_END |
229 |
|
} |
230 |
|
|
231 |
|
_Myios::setstate(_State); |
232 |
|
return (*this); |
233 |
|
} |
234 |
|
|
235 |
|
/* Note that if your stream is wchar_t, and you are not using native wchar_t |
236 |
|
Then this operation will be unavailable as there is an explicit |
237 |
|
specialisation further down this file that is designed to treat an |
238 |
|
unsigned short as a character. |
239 |
|
|
240 |
|
If you wish to read or write unsigned shorts to wchar_t streams, you should |
241 |
|
consider making wchar_t a native type by turning on /Zc:wchar_t |
242 |
|
*/ |
243 |
|
_Myt& __CLR_OR_THIS_CALL operator<<(unsigned short _Val) |
244 |
|
{ // insert an unsigned short |
245 |
|
ios_base::iostate _State = ios_base::goodbit; |
246 |
|
const sentry _Ok(*this); |
247 |
|
|
248 |
|
if (_Ok) |
249 |
|
{ // state okay, use facet to insert |
250 |
|
const _Nput& _Nput_fac = _USE(ios_base::getloc(), _Nput); |
251 |
|
|
252 |
|
_TRY_IO_BEGIN |
253 |
|
if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, |
254 |
|
_Myios::fill(), (unsigned long)_Val).failed()) |
255 |
|
_State |= ios_base::badbit; |
256 |
|
_CATCH_IO_END |
257 |
|
} |
258 |
|
|
259 |
|
_Myios::setstate(_State); |
260 |
|
return (*this); |
261 |
|
} |
262 |
|
|
263 |
|
_Myt& __CLR_OR_THIS_CALL operator<<(int __w64 _Val) |
264 |
|
{ // insert an int |
265 |
|
ios_base::iostate _State = ios_base::goodbit; |
266 |
|
const sentry _Ok(*this); |
267 |
|
|
268 |
|
if (_Ok) |
269 |
|
{ // state okay, use facet to insert |
270 |
|
const _Nput& _Nput_fac = _USE(ios_base::getloc(), _Nput); |
271 |
|
ios_base::fmtflags _Bfl = |
272 |
|
ios_base::flags() & ios_base::basefield; |
273 |
|
long _Tmp = (_Bfl == ios_base::oct |
274 |
|
|| _Bfl == ios_base::hex) |
275 |
|
? (long)(unsigned int)_Val : (long)_Val; |
276 |
|
|
277 |
|
_TRY_IO_BEGIN |
278 |
|
if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, |
279 |
|
_Myios::fill(), _Tmp).failed()) |
280 |
|
_State |= ios_base::badbit; |
281 |
|
_CATCH_IO_END |
282 |
|
} |
283 |
|
|
284 |
|
_Myios::setstate(_State); |
285 |
|
return (*this); |
286 |
|
} |
287 |
|
|
288 |
|
_Myt& __CLR_OR_THIS_CALL operator<<(unsigned int __w64 _Val) |
289 |
|
{ // insert an unsigned int |
290 |
|
ios_base::iostate _State = ios_base::goodbit; |
291 |
|
const sentry _Ok(*this); |
292 |
|
|
293 |
|
if (_Ok) |
294 |
|
{ // state okay, use facet to insert |
295 |
|
const _Nput& _Nput_fac = _USE(ios_base::getloc(), _Nput); |
296 |
|
|
297 |
|
_TRY_IO_BEGIN |
298 |
|
if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, |
299 |
|
_Myios::fill(), (unsigned long)_Val).failed()) |
300 |
|
_State |= ios_base::badbit; |
301 |
|
_CATCH_IO_END |
302 |
|
} |
303 |
|
|
304 |
|
_Myios::setstate(_State); |
305 |
|
return (*this); |
306 |
|
} |
307 |
|
|
308 |
|
_Myt& __CLR_OR_THIS_CALL operator<<(long _Val) |
309 |
|
{ // insert a long |
310 |
|
ios_base::iostate _State = ios_base::goodbit; |
311 |
|
const sentry _Ok(*this); |
312 |
|
|
313 |
|
if (_Ok) |
314 |
|
{ // state okay, use facet to insert |
315 |
|
const _Nput& _Nput_fac = _USE(ios_base::getloc(), _Nput); |
316 |
|
|
317 |
|
_TRY_IO_BEGIN |
318 |
|
if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, |
319 |
|
_Myios::fill(), _Val).failed()) |
320 |
|
_State |= ios_base::badbit; |
321 |
|
_CATCH_IO_END |
322 |
|
} |
323 |
|
|
324 |
|
_Myios::setstate(_State); |
325 |
|
return (*this); |
326 |
|
} |
327 |
|
|
328 |
|
_Myt& __CLR_OR_THIS_CALL operator<<(unsigned long __w64 _Val) |
329 |
|
{ // insert an unsigned long |
330 |
|
ios_base::iostate _State = ios_base::goodbit; |
331 |
|
const sentry _Ok(*this); |
332 |
|
|
333 |
|
if (_Ok) |
334 |
|
{ // state okay, use facet to insert |
335 |
|
const _Nput& _Nput_fac = _USE(ios_base::getloc(), _Nput); |
336 |
|
|
337 |
|
_TRY_IO_BEGIN |
338 |
|
if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, |
339 |
|
_Myios::fill(), (unsigned long)_Val).failed()) |
340 |
|
_State |= ios_base::badbit; |
341 |
|
_CATCH_IO_END |
342 |
|
} |
343 |
|
|
344 |
|
_Myios::setstate(_State); |
345 |
|
return (*this); |
346 |
|
} |
347 |
|
|
348 |
|
#ifdef _LONGLONG |
349 |
|
_Myt& __CLR_OR_THIS_CALL operator<<(_LONGLONG _Val) |
350 |
|
{ // insert a long long |
351 |
|
ios_base::iostate _State = ios_base::goodbit; |
352 |
|
const sentry _Ok(*this); |
353 |
|
|
354 |
|
if (_Ok) |
355 |
|
{ // state okay, use facet to insert |
356 |
|
const _Nput& _Nput_fac = _USE(ios_base::getloc(), _Nput); |
357 |
|
|
358 |
|
_TRY_IO_BEGIN |
359 |
|
if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, |
360 |
|
_Myios::fill(), _Val).failed()) |
361 |
|
_State |= ios_base::badbit; |
362 |
|
_CATCH_IO_END |
363 |
|
} |
364 |
|
|
365 |
|
_Myios::setstate(_State); |
366 |
|
return (*this); |
367 |
|
} |
368 |
|
|
369 |
|
_Myt& __CLR_OR_THIS_CALL operator<<(_ULONGLONG _Val) |
370 |
|
{ // insert an unsigned long long |
371 |
|
ios_base::iostate _State = ios_base::goodbit; |
372 |
|
const sentry _Ok(*this); |
373 |
|
|
374 |
|
if (_Ok) |
375 |
|
{ // state okay, use facet to insert |
376 |
|
const _Nput& _Nput_fac = _USE(ios_base::getloc(), _Nput); |
377 |
|
|
378 |
|
_TRY_IO_BEGIN |
379 |
|
if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, |
380 |
|
_Myios::fill(), _Val).failed()) |
381 |
|
_State |= ios_base::badbit; |
382 |
|
_CATCH_IO_END |
383 |
|
} |
384 |
|
|
385 |
|
_Myios::setstate(_State); |
386 |
|
return (*this); |
387 |
|
} |
388 |
|
#endif /* _LONGLONG */ |
389 |
|
|
390 |
|
_Myt& __CLR_OR_THIS_CALL operator<<(float _Val) |
391 |
|
{ // insert a float |
392 |
|
ios_base::iostate _State = ios_base::goodbit; |
393 |
|
const sentry _Ok(*this); |
394 |
|
|
395 |
|
if (_Ok) |
396 |
|
{ // state okay, use facet to insert |
397 |
|
const _Nput& _Nput_fac = _USE(ios_base::getloc(), _Nput); |
398 |
|
|
399 |
|
_TRY_IO_BEGIN |
400 |
|
if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, |
401 |
|
_Myios::fill(), (double)_Val).failed()) |
402 |
|
_State |= ios_base::badbit; |
403 |
|
_CATCH_IO_END |
404 |
|
} |
405 |
|
|
406 |
|
_Myios::setstate(_State); |
407 |
|
return (*this); |
408 |
|
} |
409 |
|
|
410 |
|
_Myt& __CLR_OR_THIS_CALL operator<<(double _Val) |
411 |
|
{ // insert a double |
412 |
|
ios_base::iostate _State = ios_base::goodbit; |
413 |
|
const sentry _Ok(*this); |
414 |
|
|
415 |
|
if (_Ok) |
416 |
|
{ // state okay, use facet to insert |
417 |
|
const _Nput& _Nput_fac = _USE(ios_base::getloc(), _Nput); |
418 |
|
|
419 |
|
_TRY_IO_BEGIN |
420 |
|
if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, |
421 |
|
_Myios::fill(), _Val).failed()) |
422 |
|
_State |= ios_base::badbit; |
423 |
|
_CATCH_IO_END |
424 |
|
} |
425 |
|
|
426 |
|
_Myios::setstate(_State); |
427 |
|
return (*this); |
428 |
|
} |
429 |
|
|
430 |
|
_Myt& __CLR_OR_THIS_CALL operator<<(long double _Val) |
431 |
|
{ // insert a long double |
432 |
|
ios_base::iostate _State = ios_base::goodbit; |
433 |
|
const sentry _Ok(*this); |
434 |
|
|
435 |
|
if (_Ok) |
436 |
|
{ // state okay, use facet to insert |
437 |
|
const _Nput& _Nput_fac = _USE(ios_base::getloc(), _Nput); |
438 |
|
|
439 |
|
_TRY_IO_BEGIN |
440 |
|
if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, |
441 |
|
_Myios::fill(), _Val).failed()) |
442 |
|
_State |= ios_base::badbit; |
443 |
|
_CATCH_IO_END |
444 |
|
} |
445 |
|
|
446 |
|
_Myios::setstate(_State); |
447 |
|
return (*this); |
448 |
|
} |
449 |
|
|
450 |
|
_Myt& __CLR_OR_THIS_CALL operator<<(const void *_Val) |
451 |
|
{ // insert a void pointer |
452 |
|
ios_base::iostate _State = ios_base::goodbit; |
453 |
|
const sentry _Ok(*this); |
454 |
|
|
455 |
|
if (_Ok) |
456 |
|
{ // state okay, use facet to insert |
457 |
|
const _Nput& _Nput_fac = _USE(ios_base::getloc(), _Nput); |
458 |
|
|
459 |
|
_TRY_IO_BEGIN |
460 |
|
if (_Nput_fac.put(_Iter(_Myios::rdbuf()), *this, |
461 |
|
_Myios::fill(), _Val).failed()) |
462 |
|
_State |= ios_base::badbit; |
463 |
|
_CATCH_IO_END |
464 |
|
} |
465 |
|
|
466 |
|
_Myios::setstate(_State); |
467 |
|
return (*this); |
468 |
|
} |
469 |
|
|
470 |
|
_Myt& __CLR_OR_THIS_CALL operator<<(_Mysb *_Strbuf) |
471 |
|
{ // insert until end-of-file from a stream buffer |
472 |
|
ios_base::iostate _State = ios_base::goodbit; |
473 |
|
bool _Copied = false; |
474 |
|
const sentry _Ok(*this); |
475 |
|
|
476 |
|
if (_Ok && _Strbuf != 0) |
477 |
|
for (int_type _Meta = _Traits::eof(); ; _Copied = true) |
478 |
|
{ // extract another character from stream buffer |
479 |
|
_TRY_BEGIN |
480 |
|
_Meta = _Traits::eq_int_type(_Traits::eof(), _Meta) |
481 |
|
? _Strbuf->sgetc() : _Strbuf->snextc(); |
482 |
|
_CATCH_ALL |
483 |
|
_Myios::setstate(ios_base::failbit); |
484 |
|
_RERAISE; |
485 |
|
_CATCH_END |
486 |
|
|
487 |
|
if (_Traits::eq_int_type(_Traits::eof(), _Meta)) |
488 |
|
break; // end of file, quit |
489 |
|
|
490 |
|
_TRY_IO_BEGIN |
491 |
|
if (_Traits::eq_int_type(_Traits::eof(), |
492 |
|
_Myios::rdbuf()->sputc( |
493 |
|
_Traits::to_char_type(_Meta)))) |
494 |
|
{ // insertion failed, quit |
495 |
|
_State |= ios_base::badbit; |
496 |
|
break; |
497 |
|
} |
498 |
|
_CATCH_IO_END |
499 |
|
} |
500 |
|
|
501 |
|
ios_base::width(0); |
502 |
|
_Myios::setstate(_Strbuf == 0 ? ios_base::badbit |
503 |
|
: !_Copied ? _State | ios_base::failbit : _State); |
504 |
|
return (*this); |
505 |
|
} |
506 |
|
|
507 |
|
_Myt& __CLR_OR_THIS_CALL put(_Elem _Ch) |
508 |
|
{ // insert a character |
509 |
|
ios_base::iostate _State = ios_base::goodbit; |
510 |
|
const sentry _Ok(*this); |
511 |
|
|
512 |
|
if (!_Ok) |
513 |
|
_State |= ios_base::badbit; |
514 |
|
else |
515 |
|
{ // state okay, insert character |
516 |
|
_TRY_IO_BEGIN |
517 |
|
if (_Traits::eq_int_type(_Traits::eof(), |
518 |
|
_Myios::rdbuf()->sputc(_Ch))) |
519 |
|
_State |= ios_base::badbit; |
520 |
|
_CATCH_IO_END |
521 |
|
} |
522 |
|
|
523 |
|
_Myios::setstate(_State); |
524 |
|
return (*this); |
525 |
|
} |
526 |
|
|
527 |
|
_Myt& __CLR_OR_THIS_CALL write(const _Elem *_Str, |
528 |
|
streamsize _Count) |
529 |
|
{ // insert _Count characters from array _Str |
530 |
|
if (0 < _Count) |
531 |
|
_DEBUG_POINTER(_Str); |
532 |
|
ios_base::iostate _State = ios_base::goodbit; |
533 |
|
const sentry _Ok(*this); |
534 |
|
|
535 |
|
if (!_Ok) |
536 |
|
_State |= ios_base::badbit; |
537 |
|
else |
538 |
|
{ // state okay, insert characters |
539 |
|
_TRY_IO_BEGIN |
540 |
|
if (_Myios::rdbuf()->sputn(_Str, _Count) != _Count) |
541 |
|
_State |= ios_base::badbit; |
542 |
|
_CATCH_IO_END |
543 |
|
} |
544 |
|
|
545 |
|
_Myios::setstate(_State); |
546 |
|
return (*this); |
547 |
|
} |
548 |
|
|
549 |
|
_Myt& __CLR_OR_THIS_CALL flush() |
550 |
|
{ // flush output stream |
551 |
|
ios_base::iostate _State = ios_base::goodbit; |
552 |
|
if (!ios_base::fail() && _Myios::rdbuf()->pubsync() == -1) |
553 |
|
_State |= ios_base::badbit; // sync failed |
554 |
|
_Myios::setstate(_State); |
555 |
|
return (*this); |
556 |
|
} |
557 |
|
|
558 |
|
_Myt& __CLR_OR_THIS_CALL seekp(pos_type _Pos) |
559 |
|
{ // set output stream position to _Pos |
560 |
|
if (!ios_base::fail() |
561 |
|
&& (off_type)_Myios::rdbuf()->pubseekpos(_Pos, |
562 |
|
ios_base::out) == _BADOFF) |
563 |
|
_Myios::setstate(ios_base::failbit); |
564 |
|
return (*this); |
565 |
|
} |
566 |
|
|
567 |
|
_Myt& __CLR_OR_THIS_CALL seekp(off_type _Off, ios_base::seekdir _Way) |
568 |
|
{ // change output stream position by _Off, according to _Way |
569 |
|
if (!ios_base::fail() |
570 |
|
&& (off_type)_Myios::rdbuf()->pubseekoff(_Off, _Way, |
571 |
|
ios_base::out) == _BADOFF) |
572 |
|
_Myios::setstate(ios_base::failbit); |
573 |
|
return (*this); |
574 |
|
} |
575 |
|
|
576 |
|
pos_type __CLR_OR_THIS_CALL tellp() |
577 |
|
{ // return output stream position |
578 |
|
if (!ios_base::fail()) |
579 |
|
return (_Myios::rdbuf()->pubseekoff(0, |
580 |
|
ios_base::cur, ios_base::out)); |
581 |
|
else |
582 |
|
return (pos_type(_BADOFF)); |
583 |
|
} |
584 |
|
}; |
585 |
|
|
586 |
|
#ifndef _NATIVE_WCHAR_T_DEFINED |
587 |
|
/* |
588 |
|
This explicit template specialisation writes a single unicode character to the stream. |
589 |
|
|
590 |
|
By default, the compiler treats wchar_t as if it were a typedef for unsigned short. This means |
591 |
|
that we cannot distinguish between an unsigned short and a wchar_t in the library. To be most |
592 |
|
consistent with previous practice, we add this explicit specialisation to ensure that a single |
593 |
|
unsigned short is read and written as a character. |
594 |
|
|
595 |
|
If you wish to read and write unsigned shorts as integers, we recommend you consider making |
596 |
|
wchar_t a native type by using the /Zc:wchar_t compiler switch. |
597 |
|
*/ |
598 |
|
template <> inline |
599 |
|
basic_ostream<unsigned short, char_traits<unsigned short> >&__CLR_OR_THIS_CALL |
600 |
|
basic_ostream<unsigned short, char_traits<unsigned short> >::operator<<( |
601 |
|
unsigned short _Ch) |
602 |
|
{ // insert a character |
603 |
|
typedef basic_ostream<unsigned short, char_traits<unsigned short> > _Myos; |
604 |
|
typedef char_traits<unsigned short> _Traits; |
605 |
|
_Myos &_Ostr=*this; |
606 |
|
ios_base::iostate _State = ios_base::goodbit; |
607 |
|
const _Myos::sentry _Ok(_Ostr); |
608 |
|
|
609 |
|
if (_Ok) |
610 |
|
{ // state okay, insert |
611 |
|
streamsize _Pad = _Ostr.width() <= 1 ? 0 : _Ostr.width() - 1; |
612 |
|
|
613 |
|
_TRY_IO_BEGIN |
614 |
|
if ((_Ostr.flags() & ios_base::adjustfield) != ios_base::left) |
615 |
|
for (; _State == ios_base::goodbit && 0 < _Pad; |
616 |
|
--_Pad) // pad on left |
617 |
|
if (_Traits::eq_int_type(_Traits::eof(), |
618 |
|
_Ostr.rdbuf()->sputc(_Ostr.fill()))) |
619 |
|
_State |= ios_base::badbit; |
620 |
|
|
621 |
|
if (_State == ios_base::goodbit |
622 |
|
&& _Traits::eq_int_type(_Traits::eof(), |
623 |
|
_Ostr.rdbuf()->sputc(_Ch))) |
624 |
|
_State |= ios_base::badbit; |
625 |
|
|
626 |
|
for (; _State == ios_base::goodbit && 0 < _Pad; |
627 |
|
--_Pad) // pad on right |
628 |
|
if (_Traits::eq_int_type(_Traits::eof(), |
629 |
|
_Ostr.rdbuf()->sputc(_Ostr.fill()))) |
630 |
|
_State |= ios_base::badbit; |
631 |
|
_CATCH_IO_(_Ostr) |
632 |
|
} |
633 |
|
|
634 |
|
_Ostr.width(0); |
635 |
|
_Ostr.setstate(_State); |
636 |
|
return (_Ostr); |
637 |
|
} |
638 |
|
#endif |
639 |
|
|
640 |
|
#if defined(_DLL_CPPLIB) && !defined(_M_CEE_PURE) |
641 |
|
|
642 |
|
template class _CRTIMP2_PURE basic_ostream<char, char_traits<char> >; |
643 |
|
template class _CRTIMP2_PURE basic_ostream<wchar_t, char_traits<wchar_t> >; |
644 |
|
|
645 |
|
|
646 |
|
|
647 |
|
#endif /* _DLL_CPPLIB */ |
648 |
|
|
649 |
|
// INSERTERS |
650 |
|
|
651 |
|
template<class _Elem, |
652 |
|
class _Traits> inline |
653 |
|
basic_ostream<_Elem, _Traits>& __CLRCALL_OR_CDECL operator<<( |
654 |
|
basic_ostream<_Elem, _Traits>& _Ostr, const char *_Val) |
655 |
|
{ // insert NTBS |
656 |
|
ios_base::iostate _State = ios_base::goodbit; |
657 |
|
streamsize _Count = (streamsize)::strlen(_Val); // may overflow |
658 |
|
streamsize _Pad = _Ostr.width() <= 0 || _Ostr.width() <= _Count |
659 |
|
? 0 : _Ostr.width() - _Count; |
660 |
|
const typename basic_ostream<_Elem, _Traits>::sentry _Ok(_Ostr); |
661 |
|
|
662 |
|
if (!_Ok) |
663 |
|
_State |= ios_base::badbit; |
664 |
|
else |
665 |
|
{ // state okay, insert characters |
666 |
|
_TRY_IO_BEGIN |
667 |
|
const ctype<_Elem>& _Ctype_fac = _USE(_Ostr.getloc(), ctype<_Elem>); |
668 |
|
if ((_Ostr.flags() & ios_base::adjustfield) != ios_base::left) |
669 |
|
for (; 0 < _Pad; --_Pad) // pad on left |
670 |
|
if (_Traits::eq_int_type(_Traits::eof(), |
671 |
|
_Ostr.rdbuf()->sputc(_Ostr.fill()))) |
672 |
|
{ // insertion failed, quit |
673 |
|
_State |= ios_base::badbit; |
674 |
|
break; |
675 |
|
} |
676 |
|
|
677 |
|
for (; _State == ios_base::goodbit && 0 < _Count; --_Count, ++_Val) |
678 |
|
if (_Traits::eq_int_type(_Traits::eof(), |
679 |
|
_Ostr.rdbuf()->sputc(_Ctype_fac.widen(*_Val)))) |
680 |
|
_State |= ios_base::badbit; |
681 |
|
|
682 |
|
if (_State == ios_base::goodbit) |
683 |
|
for (; 0 < _Pad; --_Pad) // pad on right |
684 |
|
if (_Traits::eq_int_type(_Traits::eof(), |
685 |
|
_Ostr.rdbuf()->sputc(_Ostr.fill()))) |
686 |
|
{ // insertion failed, quit |
687 |
|
_State |= ios_base::badbit; |
688 |
|
break; |
689 |
|
} |
690 |
|
_Ostr.width(0); |