|
|
// ostream standard header #pragma once #ifndef _OSTREAM_ #define _OSTREAM_ #include <ios>
#pragma pack(push,8) #pragma warning(push,3) _STD_BEGIN
// I/O EXCEPTION MACROS #if _HAS_EXCEPTIONS #define _TRY_IO_BEGIN _TRY_BEGIN /* begin try block */
#define _CATCH_IO_END _CATCH_ALL /* catch block for _Myios */ \ _Myios::setstate(ios_base::badbit, true); /* set badbit and rethrow */ \ _CATCH_END
#define _CATCH_IO_(x) _CATCH_ALL /* catch block for basic_ios x */ \ (x).setstate(ios_base::badbit, true); /* set badbit and rethrow */ \ _CATCH_END #else #define _TRY_IO_BEGIN { /* begin try block */
#define _CATCH_IO_END } /* catch block for _Myios */
#define _CATCH_IO_(x) } /* catch block for basic_ios x */ #endif
// TEMPLATE CLASS basic_ostream template<class _Elem, class _Traits> class basic_ostream : virtual public basic_ios<_Elem, _Traits> { // control insertions into a stream buffer public: typedef basic_ostream<_Elem, _Traits> _Myt; typedef basic_ios<_Elem, _Traits> _Myios; typedef basic_streambuf<_Elem, _Traits> _Mysb; typedef ostreambuf_iterator<_Elem, _Traits> _Iter; typedef num_put<_Elem, _Iter> _Nput;
explicit basic_ostream(basic_streambuf<_Elem, _Traits> *_Strbuf, bool _Isstd = false) { // construct from a stream buffer pointer _Myios::init(_Strbuf, _Isstd); }
basic_ostream(_Uninitialized) { // construct uninitialized ios_base::_Addstd(); }
virtual ~basic_ostream() { // destroy the object }
typedef typename _Traits::int_type int_type; typedef typename _Traits::pos_type pos_type; typedef typename _Traits::off_type off_type;
class _Sentry_base { // stores thread lock and reference to output stream public: _Sentry_base(_Myt& _Ostr) : _Myostr(_Ostr) { // lock the stream buffer, if there if (_Myostr.rdbuf() != 0) _Myostr.rdbuf()->_Lock(); }
~_Sentry_base() { // destroy after unlocking if (_Myostr.rdbuf() != 0) _Myostr.rdbuf()->_Unlock(); }
_Myt& _Myostr; // the output stream, for _Unlock call at destruction };
class sentry : public _Sentry_base { // stores thread lock and state of stream public: explicit sentry(_Myt& _Ostr) : _Sentry_base(_Ostr) { // construct locking and testing stream if (_Ostr.good() && _Ostr.tie() != 0) _Ostr.tie()->flush(); _Ok = _Ostr.good(); // store test only after flushing tie }
~sentry() { // destroy the object #if _HAS_EXCEPTIONS if (!uncaught_exception()) _Myostr._Osfx(); } #else _Myostr._Osfx(); } #endif
operator bool() const { // test if stream state okay return (_Ok); }
private: sentry(const sentry&); // not defined sentry& operator=(const sentry&); // not defined
bool _Ok; // true if stream state okay at construction };
bool opfx() { // test stream state and flush tie stream as needed (retained) if (ios_base::good() && _Myios::tie() != 0) _Myios::tie()->flush(); return (ios_base::good()); }
void osfx() { // perform any wrapup (retained) _Osfx(); }
void _Osfx() { // perform any wrapup if (ios_base::flags() & ios_base::unitbuf) flush(); // flush stream as needed }
_Myt& operator<<(_Myt& (__cdecl *_Pfn)(_Myt&)) { // call basic_ostream manipulator return ((*_Pfn)(*this)); }
_Myt& operator<<(_Myios& (__cdecl *_Pfn)(_Myios&)) { // call basic_ios manipulator (*_Pfn)(*(_Myios *)this); return (*this); }
_Myt& operator<<(ios_base& (__cdecl *_Pfn)(ios_base&)) { // call ios_base manipulator (*_Pfn)(*(ios_base *)this); return (*this); }
_Myt& operator<<(_Bool _Val) { // insert a boolean ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this);
if (_Ok) { // state okay, use facet to insert const _Nput& _Fac = _USE(ios_base::getloc(), _Nput);
_TRY_IO_BEGIN if (_Fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Val).failed()) _State |= ios_base::badbit; _CATCH_IO_END }
_Myios::setstate(_State); return (*this); }
_Myt& operator<<(short _Val) { // insert a short ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this);
if (_Ok) { // state okay, use facet to insert const _Nput& _Fac = _USE(ios_base::getloc(), _Nput); ios_base::fmtflags _Bfl = ios_base::flags() & ios_base::basefield; long _Tmp = (_Bfl == ios_base::oct || _Bfl == ios_base::hex) ? (long)(unsigned short)_Val : (long)_Val;
_TRY_IO_BEGIN if (_Fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Tmp).failed()) _State |= ios_base::badbit; _CATCH_IO_END }
_Myios::setstate(_State); return (*this); }
_Myt& operator<<(unsigned short _Val) { // insert an unsigned short ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this);
if (_Ok) { // state okay, use facet to insert const _Nput& _Fac = _USE(ios_base::getloc(), _Nput);
_TRY_IO_BEGIN if (_Fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), (unsigned long)_Val).failed()) _State |= ios_base::badbit; _CATCH_IO_END }
_Myios::setstate(_State); return (*this); }
_Myt& operator<<(int _Val) { // insert an int ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this);
if (_Ok) { // state okay, use facet to insert const _Nput& _Fac = _USE(ios_base::getloc(), _Nput); ios_base::fmtflags _Bfl = ios_base::flags() & ios_base::basefield; long _Tmp = (_Bfl == ios_base::oct || _Bfl == ios_base::hex) ? (long)(unsigned int)_Val : (long)_Val;
_TRY_IO_BEGIN if (_Fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Tmp).failed()) _State |= ios_base::badbit; _CATCH_IO_END }
_Myios::setstate(_State); return (*this); }
_Myt& operator<<(unsigned int _Val) { // insert an unsigned int ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this);
if (_Ok) { // state okay, use facet to insert const _Nput& _Fac = _USE(ios_base::getloc(), _Nput);
_TRY_IO_BEGIN if (_Fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), (unsigned long)_Val).failed()) _State |= ios_base::badbit; _CATCH_IO_END }
_Myios::setstate(_State); return (*this); }
_Myt& operator<<(long _Val) { // insert a long ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this);
if (_Ok) { // state okay, use facet to insert const _Nput& _Fac = _USE(ios_base::getloc(), _Nput);
_TRY_IO_BEGIN if (_Fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Val).failed()) _State |= ios_base::badbit; _CATCH_IO_END }
_Myios::setstate(_State); return (*this); }
_Myt& operator<<(unsigned long _Val) { // insert an unsigned long ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this);
if (_Ok) { // state okay, use facet to insert const _Nput& _Fac = _USE(ios_base::getloc(), _Nput);
_TRY_IO_BEGIN if (_Fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Val).failed()) _State |= ios_base::badbit; _CATCH_IO_END }
_Myios::setstate(_State); return (*this); } #ifdef _LONGLONG
_Myt& operator<<(_LONGLONG _Val) { // insert a long long ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this);
if (_Ok) { // state okay, use facet to insert const _Nput& _Fac = _USE(ios_base::getloc(), _Nput);
_TRY_IO_BEGIN if (_Fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Val).failed()) _State |= ios_base::badbit; _CATCH_IO_END }
_Myios::setstate(_State); return (*this); }
_Myt& operator<<(_ULONGLONG _Val) { // insert an unsigned long long ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this);
if (_Ok) { // state okay, use facet to insert const _Nput& _Fac = _USE(ios_base::getloc(), _Nput);
_TRY_IO_BEGIN if (_Fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Val).failed()) _State |= ios_base::badbit; _CATCH_IO_END }
_Myios::setstate(_State); return (*this); } #endif /* _LONGLONG */
_Myt& operator<<(float _Val) { // insert a float ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this);
if (_Ok) { // state okay, use facet to insert const _Nput& _Fac = _USE(ios_base::getloc(), _Nput);
_TRY_IO_BEGIN if (_Fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), (double)_Val).failed()) _State |= ios_base::badbit; _CATCH_IO_END }
_Myios::setstate(_State); return (*this); }
_Myt& operator<<(double _Val) { // insert a double ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this);
if (_Ok) { // state okay, use facet to insert const _Nput& _Fac = _USE(ios_base::getloc(), _Nput);
_TRY_IO_BEGIN if (_Fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Val).failed()) _State |= ios_base::badbit; _CATCH_IO_END }
_Myios::setstate(_State); return (*this); }
_Myt& operator<<(long double _Val) { // insert a long double ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this);
if (_Ok) { // state okay, use facet to insert const _Nput& _Fac = _USE(ios_base::getloc(), _Nput);
_TRY_IO_BEGIN if (_Fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Val).failed()) _State |= ios_base::badbit; _CATCH_IO_END }
_Myios::setstate(_State); return (*this); }
_Myt& operator<<(const void *_Val) { // insert a void pointer ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this);
if (_Ok) { // state okay, use facet to insert const _Nput& _Fac = _USE(ios_base::getloc(), _Nput);
_TRY_IO_BEGIN if (_Fac.put(_Iter(_Myios::rdbuf()), *this, _Myios::fill(), _Val).failed()) _State |= ios_base::badbit; _CATCH_IO_END }
_Myios::setstate(_State); return (*this); }
_Myt& operator<<(_Mysb *_Strbuf) { // insert until end-of-file from a stream buffer ios_base::iostate _State = ios_base::goodbit; bool _Copied = false; const sentry _Ok(*this);
if (_Ok && _Strbuf != 0) for (int_type _Meta = _Traits::eof(); ; _Copied = true) { // extract another character from stream buffer _TRY_BEGIN _Meta = _Traits::eq_int_type(_Traits::eof(), _Meta) ? _Strbuf->sgetc() : _Strbuf->snextc(); _CATCH_ALL _Myios::setstate(ios_base::failbit); _RERAISE; _CATCH_END
if (_Traits::eq_int_type(_Traits::eof(), _Meta)) break; // end of file, quit
_TRY_IO_BEGIN if (_Traits::eq_int_type(_Traits::eof(), _Myios::rdbuf()->sputc( _Traits::to_char_type(_Meta)))) { // insertion failed, quit _State |= ios_base::badbit; break; } _CATCH_IO_END }
ios_base::width(0); _Myios::setstate(!_Copied ? _State | ios_base::failbit : _State); return (*this); }
_Myt& put(_Elem _Ch) { // insert a character ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this);
if (!_Ok) _State |= ios_base::badbit; else { // state okay, insert character _TRY_IO_BEGIN if (_Traits::eq_int_type(_Traits::eof(), _Myios::rdbuf()->sputc(_Ch))) _State |= ios_base::badbit; _CATCH_IO_END }
_Myios::setstate(_State); return (*this); }
_Myt& write(const _Elem *_Str, streamsize _Count) { // insert _Count characters from array _Str ios_base::iostate _State = ios_base::goodbit; const sentry _Ok(*this);
if (!_Ok) _State |= ios_base::badbit; else { // state okay, insert characters _TRY_IO_BEGIN if (_Myios::rdbuf()->sputn(_Str, _Count) != _Count) _State |= ios_base::badbit; _CATCH_IO_END }
_Myios::setstate(_State); return (*this); }
_Myt& flush() { // flush output stream ios_base::iostate _State = ios_base::goodbit; if (!ios_base::fail() && _Myios::rdbuf()->pubsync() == -1) _State |= ios_base::badbit; // sync failed _Myios::setstate(_State); return (*this); }
_Myt& seekp(pos_type _Pos) { // set output stream position to _Pos if (!ios_base::fail() && (off_type)_Myios::rdbuf()->pubseekpos(_Pos, ios_base::out) == _BADOFF) _Myios::setstate(ios_base::failbit); return (*this); }
_Myt& seekp(off_type _Off, ios_base::seekdir _Way) { // change output stream position by _Off, according to _Way if (!ios_base::fail() && (off_type)_Myios::rdbuf()->pubseekoff(_Off, _Way, ios_base::out) == _BADOFF) _Myios::setstate(ios_base::failbit); return (*this); }
pos_type tellp() { // return output stream position if (!ios_base::fail()) return (_Myios::rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out)); else return (pos_type(_BADOFF)); } };
#ifdef _DLL_CPPLIB template class _CRTIMP2 basic_ostream<char, char_traits<char> >; template class _CRTIMP2 basic_ostream<wchar_t, char_traits<wchar_t> >; #endif // _DLL_CPPLIB
// INSERTERS
template<class _Elem, class _Traits> inline basic_ostream<_Elem, _Traits>& __cdecl operator<<( basic_ostream<_Elem, _Traits>& _Ostr, const _Elem *_Val) { // insert NTCS typedef basic_ostream<_Elem, _Traits> _Myos; ios_base::iostate _State = ios_base::goodbit; streamsize _Count = (streamsize)_Traits::length(_Val); // may overflow streamsize _Pad = _Ostr.width() <= 0 || _Ostr.width() <= _Count ? 0 : _Ostr.width() - _Count; const typename _Myos::sentry _Ok(_Ostr);
if (!_Ok) _State |= ios_base::badbit; else { // state okay, insert _TRY_IO_BEGIN if ((_Ostr.flags() & ios_base::adjustfield) != ios_base::left) for (; 0 < _Pad; --_Pad) // pad on left if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ostr.fill()))) { // insertion failed, quit _State |= ios_base::badbit; break; }
if (_State == ios_base::goodbit && _Ostr.rdbuf()->sputn(_Val, _Count) != _Count) _State |= ios_base::badbit;
if (_State == ios_base::goodbit) for (; 0 < _Pad; --_Pad) // pad on right if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ostr.fill()))) { // insertion failed, quit _State |= ios_base::badbit; break; } _Ostr.width(0); _CATCH_IO_(_Ostr) }
_Ostr.setstate(_State); return (_Ostr); }
template<class _Elem, class _Traits> inline basic_ostream<_Elem, _Traits>& __cdecl operator<<( basic_ostream<_Elem, _Traits>& _Ostr, _Elem _Ch) { // insert a character typedef basic_ostream<_Elem, _Traits> _Myos; ios_base::iostate _State = ios_base::goodbit; const typename _Myos::sentry _Ok(_Ostr);
if (_Ok) { // state okay, insert streamsize _Pad = _Ostr.width() <= 1 ? 0 : _Ostr.width() - 1;
_TRY_IO_BEGIN if ((_Ostr.flags() & ios_base::adjustfield) != ios_base::left) for (; _State == ios_base::goodbit && 0 < _Pad; --_Pad) // pad on left if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ostr.fill()))) _State |= ios_base::badbit;
if (_State == ios_base::goodbit && _Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ch))) _State |= ios_base::badbit;
for (; _State == ios_base::goodbit && 0 < _Pad; --_Pad) // pad on right if (_Traits::eq_int_type(_Traits::eof(), _Ostr.rdbuf()->sputc(_Ostr.fill()))) _State |= ios_base::badbit; _CATCH_IO_(_Ostr) }
_Ostr.width(0); _Ostr.setstate(_State); return (_Ostr); }
template<class _Traits> inline basic_ostream<char, _Traits>& __cdecl operator<<( basic_ostream<char, _Traits>& _Ostr, const signed char *_Val) { // insert a signed char NTBS return (_Ostr << (const char *)_Val); }
template<class _Traits> inline basic_ostream<char, _Traits>& __cdecl operator<<( basic_ostream<char, _Traits>& _Ostr, signed char _Ch) { // insert a signed char return (_Ostr << (char)_Ch); }
template<class _Traits> inline basic_ostream<char, _Traits>& __cdecl operator<<( basic_ostream<char, _Traits>& _Ostr, const unsigned char *_Val) { // insert an unsigned char NTBS return (_Ostr << (const char *)_Val); }
template<class _Traits> inline basic_ostream<char, _Traits>& __cdecl operator<<( basic_ostream<char, _Traits>& _Ostr, unsigned char _Ch) { // insert an unsigned char return (_Ostr << (char)_Ch); }
// MANIPULATORS template<class _Elem, class _Traits> inline basic_ostream<_Elem, _Traits>& __cdecl endl(basic_ostream<_Elem, _Traits>& _Ostr) { // insert newline and flush stream _Ostr.put(_Ostr.widen('\n')); _Ostr.flush(); return (_Ostr); }
template<class _Elem, class _Traits> inline basic_ostream<_Elem, _Traits>& __cdecl ends(basic_ostream<_Elem, _Traits>& _Ostr) { // insert null character _Ostr.put(_Elem()); return (_Ostr); }
template<class _Elem, class _Traits> inline basic_ostream<_Elem, _Traits>& __cdecl flush(basic_ostream<_Elem, _Traits>& _Ostr) { // flush stream _Ostr.flush(); return (_Ostr); }
_CRTIMP2 inline basic_ostream<char, char_traits<char> >& __cdecl endl(basic_ostream<char, char_traits<char> >& _Ostr) { // insert newline and flush byte stream _Ostr.put('\n'); _Ostr.flush(); return (_Ostr); }
_CRTIMP2 inline basic_ostream<wchar_t, char_traits<wchar_t> >& __cdecl endl(basic_ostream<wchar_t, char_traits<wchar_t> >& _Ostr) { // insert newline and flush wide stream _Ostr.put('\n'); _Ostr.flush(); return (_Ostr); }
_CRTIMP2 inline basic_ostream<char, char_traits<char> >& __cdecl ends(basic_ostream<char, char_traits<char> >& _Ostr) { // insert null character into byte stream _Ostr.put('\0'); return (_Ostr); }
_CRTIMP2 inline basic_ostream<wchar_t, char_traits<wchar_t> >& __cdecl ends(basic_ostream<wchar_t, char_traits<wchar_t> >& _Ostr) { // insert null character into wide stream _Ostr.put('\0'); return (_Ostr); }
_CRTIMP2 inline basic_ostream<char, char_traits<char> >& __cdecl flush(basic_ostream<char, char_traits<char> >& _Ostr) { // flush byte stream _Ostr.flush(); return (_Ostr); }
_CRTIMP2 inline basic_ostream<wchar_t, char_traits<wchar_t> >& __cdecl flush(basic_ostream<wchar_t, char_traits<wchar_t> >& _Ostr) { // flush wide stream _Ostr.flush(); return (_Ostr); }
#ifdef _DLL_CPPLIB template _CRTIMP2 basic_ostream<char, char_traits<char> >& __cdecl operator<<(basic_ostream<char, char_traits<char> >&, const char *); template _CRTIMP2 basic_ostream<char, char_traits<char> >& __cdecl operator<<(basic_ostream<char, char_traits<char> >&, char); template _CRTIMP2 basic_ostream<char, char_traits<char> >& __cdecl operator<<(basic_ostream<char, char_traits<char> >&, const signed char *); template _CRTIMP2 basic_ostream<char, char_traits<char> >& __cdecl operator<<(basic_ostream<char, char_traits<char> >&, signed char); template _CRTIMP2 basic_ostream<char, char_traits<char> >& __cdecl operator<<(basic_ostream<char, char_traits<char> >&, const unsigned char *); template _CRTIMP2 basic_ostream<char, char_traits<char> >& __cdecl operator<<(basic_ostream<char, char_traits<char> >&, unsigned char); template _CRTIMP2 basic_ostream<wchar_t, char_traits<wchar_t> >& __cdecl operator<<(basic_ostream<wchar_t, char_traits<wchar_t> >&, const wchar_t *); template _CRTIMP2 basic_ostream<wchar_t, char_traits<wchar_t> >& __cdecl operator<<(basic_ostream<wchar_t, char_traits<wchar_t> >&, wchar_t); #endif // _DLL_CPPLIB _STD_END #pragma warning(pop) #pragma pack(pop)
#endif /* _OSTREAM_ */
/* * Copyright (c) 1992-2001 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V3.10:0009 */
|