2020-09-30 17:12:29 +02:00

544 lines
14 KiB
Plaintext

// istream standard header
#ifndef _ISTREAM_
#define _ISTREAM_
#include <use_ansi.h>
#include <cfloat>
#include <ostream>
#ifdef _MSC_VER
/*
* Currently, all MS C compilers for Win32 platforms default to 8 byte
* alignment.
*/
#pragma pack(push,8)
#endif /* _MSC_VER */
// TEMPLATE CLASS basic_istream
template<class _E, class _TYPE>
class basic_istream : virtual public basic_ios<_E, _TYPE> {
public:
typedef basic_istream<_E, _TYPE> _Myt;
typedef istreambuf_iterator<_E, _TYPE> _Iter;
typedef num_get<_E, _Iter> _Nget;
typedef _TYPE::char_type char_type;
typedef _TYPE::int_type int_type;
typedef _TYPE::pos_type pos_type;
typedef _TYPE::off_type off_type;
class sentry {
public:
explicit sentry(_Myt& _Is, bool _Noskip = false)
: _Ok(_Is.ipfx(_Noskip)) {}
operator bool() const
{return (_Ok); }
private:
bool _Ok;
};
explicit basic_istream(basic_streambuf<_E, _TYPE> *_S,
bool _Isstd = false)
: _Chcount(0) {init(_S, _Isstd); }
basic_istream(_Uninitialized)
{_Addstd(); }
virtual ~basic_istream()
{}
bool ipfx(bool _Noskip = false)
{if (good())
{if (tie() != 0)
tie()->flush();
if (!_Noskip && flags() & skipws)
{const ctype<_E>& _Fac =
_USE(getloc(), ctype<_E>);
_TRY_IO_BEGIN
int_type _C = rdbuf()->sgetc();
for (; _Iswhite(_C, _Fac); )
_C = rdbuf()->snextc();
_CATCH_IO_END }
if (good())
return (true); }
setstate(failbit);
return (false); }
void isfx()
{}
_Myt& operator>>(_Myt& (*_F)(_Myt&))
{return ((*_F)(*this)); }
_Myt& operator>>(basic_ios<_E, _TYPE>& (*_F)(basic_ios<_E, _TYPE>&))
{(*_F)(*(basic_ios<_E, _TYPE> *)this);
return (*this); }
_Myt& operator>>(ios_base& (*_F)(ios_base&))
{(*_F)(*(ios_base *)this);
return (*this); }
_Myt& operator>>(_E *_X)
{iostate _St = goodbit;
_E *_S = _X;
const sentry _Ok(*this);
if (_Ok)
{const ctype<_E>& _Fac = _USE(getloc(), ctype<_E>);
_TRY_IO_BEGIN
int _N = 0 < width() ? width() : INT_MAX;
int_type _C = rdbuf()->sgetc();
for (; 0 < --_N; _C = rdbuf()->snextc())
if(_Iswhite(_C, _Fac))
break;
else if (_TYPE::eq_int_type(_TYPE::eof(), _C))
{_St |= eofbit;
break; }
else
*_S++ = _TYPE::to_char_type(_C);
_CATCH_IO_END }
*_S = _E(0);
width(0);
setstate(_S == _X ? _St | failbit : _St);
return (*this); }
_Myt& operator>>(char_type& _X)
{int_type _C;
iostate _St = goodbit;
const sentry _Ok(*this);
if (_Ok)
{_TRY_IO_BEGIN
_C = rdbuf()->sbumpc();
if (_TYPE::eq_int_type(_TYPE::eof(), _C))
_St |= eofbit | failbit;
else
_X = _TYPE::to_char_type(_C);
_CATCH_IO_END }
setstate(_St);
return (*this); }
_Myt& operator>>(_Bool& _X)
{iostate _St = goodbit;
const sentry _Ok(*this);
if (_Ok)
{const _Nget& _Fac = _USE(getloc(), _Nget);
_TRY_IO_BEGIN
_Fac.get(_Iter(rdbuf()), _Iter(0), *this, _St, _X);
_CATCH_IO_END }
setstate(_St);
return (*this); }
_Myt& operator>>(short& _X)
{iostate _St = goodbit;
const sentry _Ok(*this);
if (_Ok)
{long _Y;
const _Nget& _Fac = _USE(getloc(), _Nget);
_TRY_IO_BEGIN
_Fac.get(_Iter(rdbuf()), _Iter(0), *this, _St, _Y);
_CATCH_IO_END
if (_St & failbit || _Y < SHRT_MIN || SHRT_MAX < _Y)
_St |= failbit;
else
_X = _Y; }
setstate(_St);
return (*this); }
_Myt& operator>>(unsigned short& _X)
{iostate _St = goodbit;
const sentry _Ok(*this);
if (_Ok)
{const _Nget& _Fac = _USE(getloc(), _Nget);
_TRY_IO_BEGIN
_Fac.get(_Iter(rdbuf()), _Iter(0), *this, _St, _X);
_CATCH_IO_END }
setstate(_St);
return (*this); }
_Myt& operator>>(int& _X)
{iostate _St = goodbit;
const sentry _Ok(*this);
if (_Ok)
{long _Y;
const _Nget& _Fac = _USE(getloc(), _Nget);
_TRY_IO_BEGIN
_Fac.get(_Iter(rdbuf()), _Iter(0), *this, _St, _Y);
_CATCH_IO_END
if (_St & failbit || _Y < INT_MIN || INT_MAX < _Y)
_St |= failbit;
else
_X = _Y; }
setstate(_St);
return (*this); }
_Myt& operator>>(unsigned int& _X)
{iostate _St = goodbit;
const sentry _Ok(*this);
if (_Ok)
{const _Nget& _Fac = _USE(getloc(), _Nget);
_TRY_IO_BEGIN
_Fac.get(_Iter(rdbuf()), _Iter(0), *this, _St, _X);
_CATCH_IO_END }
setstate(_St);
return (*this); }
_Myt& operator>>(long& _X)
{iostate _St = goodbit;
const sentry _Ok(*this);
if (_Ok)
{const _Nget& _Fac = _USE(getloc(), _Nget);
_TRY_IO_BEGIN
_Fac.get(_Iter(rdbuf()), _Iter(0), *this, _St, _X);
_CATCH_IO_END }
setstate(_St);
return (*this); }
_Myt& operator>>(unsigned long& _X)
{iostate _St = goodbit;
const sentry _Ok(*this);
if (_Ok)
{const _Nget& _Fac = _USE(getloc(), _Nget);
_TRY_IO_BEGIN
_Fac.get(_Iter(rdbuf()), _Iter(0), *this, _St, _X);
_CATCH_IO_END }
setstate(_St);
return (*this); }
_Myt& operator>>(float& _X)
{iostate _St = goodbit;
const sentry _Ok(*this);
if (_Ok)
{const _Nget& _Fac = _USE(getloc(), _Nget);
_TRY_IO_BEGIN
_Fac.get(_Iter(rdbuf()), _Iter(0), *this, _St, _X);
_CATCH_IO_END }
setstate(_St);
return (*this); }
_Myt& operator>>(double& _X)
{iostate _St = goodbit;
const sentry _Ok(*this);
if (_Ok)
{const _Nget& _Fac = _USE(getloc(), _Nget);
_TRY_IO_BEGIN
_Fac.get(_Iter(rdbuf()), _Iter(0), *this, _St, _X);
_CATCH_IO_END }
setstate(_St);
return (*this); }
_Myt& operator>>(long double& _X)
{iostate _St = goodbit;
const sentry _Ok(*this);
if (_Ok)
{const _Nget& _Fac = _USE(getloc(), _Nget);
_TRY_IO_BEGIN
_Fac.get(_Iter(rdbuf()), _Iter(0), *this, _St, _X);
_CATCH_IO_END }
setstate(_St);
return (*this); }
_Myt& operator>>(void *& _X)
{iostate _St = goodbit;
basic_ios<_E, _TYPE> _Iosx(rdbuf());
union _Pvlo {
void *_Pv;
unsigned long _Lo[1 +
(sizeof (void *) - 1) / sizeof (unsigned long)];
} _U;
const int _NL = sizeof (_U._Lo) / sizeof (unsigned long);
const sentry _Ok(*this);
if (_Ok)
{_Iosx.setf(hex, basefield);
const _Nget& _Fac = _USE(getloc(), _Nget);
_Iter _F(rdbuf()), _L;
_TRY_IO_BEGIN
for (int _I = 0; ; ++_F)
{unsigned long _Y;
_F = _Fac.get(_F, _L, _Iosx, _St, _Y);
if (_St & failbit)
break;
_U._Lo[_I] = _Y;
if (_NL <= ++_I)
break;
if (_F == _L || *_F != _WIDEN(_E, ':'))
{_St |= failbit;
break; }}
if (!(_St & failbit))
_X = _U._Pv;
_CATCH_IO_END }
setstate(_St);
return (*this); }
_Myt& operator>>(basic_streambuf<_E, _TYPE> *_Pb)
{iostate _St = goodbit;
bool _Copied = false;
const sentry _Ok(*this);
if (_Ok && _Pb != 0)
{_TRY_IO_BEGIN
int_type _C = rdbuf()->sgetc();
for (; ; _C = rdbuf()->snextc())
if (_TYPE::eq_int_type(_TYPE::eof(), _C))
{_St |= eofbit;
break; }
else
{_TRY_BEGIN
if (_TYPE::eq_int_type(_TYPE::eof(),
_Pb->sputc(_TYPE::to_char_type(_C))))
break;
_CATCH_ALL
break;
_CATCH_END
_Copied = true; }
_CATCH_IO_END }
setstate(!_Copied ? _St | failbit : _St);
return (*this); }
int_type get()
{int_type _C;
iostate _St = goodbit;
_Chcount = 0;
const sentry _Ok(*this, true);
if (!_Ok)
_C = _TYPE::eof();
else
{_TRY_IO_BEGIN
_C = rdbuf()->sbumpc();
if (_TYPE::eq_int_type(_TYPE::eof(), _C))
_St |= eofbit | failbit;
else
++_Chcount;
_CATCH_IO_END }
setstate(_St);
return (_C); }
_Myt& get(_E *_S, streamsize _N, _E _D = _E('\n'))
{iostate _St = goodbit;
_Chcount = 0;
const sentry _Ok(*this, true);
if (_Ok && 0 < _N)
{_TRY_IO_BEGIN
int_type _C = rdbuf()->sgetc();
for (; 0 < --_N; _C = rdbuf()->snextc())
if (_TYPE::eq_int_type(_TYPE::eof(), _C))
{_St |= eofbit;
break; }
else if (_TYPE::to_char_type(_C) == _D)
break;
else
*_S++ = _TYPE::to_char_type(_C), ++_Chcount;
_CATCH_IO_END }
setstate(_Chcount == 0 ? _St | failbit : _St);
*_S = _E(0);
return (*this); }
_Myt& get(_E& _X)
{int_type _C = get();
if (!_TYPE::eq_int_type(_TYPE::eof(), _C))
_X = _TYPE::to_char_type(_C);
return (*this); }
_Myt& get(basic_streambuf<_E, _TYPE>& _Sb, _E _D = _E('\n'))
{iostate _St = goodbit;
_Chcount = 0;
const sentry _Ok(*this, true);
if (_Ok)
{_TRY_IO_BEGIN
int_type _C = rdbuf()->sgetc();
for (; ; _C = rdbuf()->snextc())
if (_TYPE::eq_int_type(_TYPE::eof(), _C))
{_St |= eofbit;
break; }
else
{_TRY_BEGIN
_E _Ch = _TYPE::to_char_type(_C);
if (_Ch == _D
|| _TYPE::eq_int_type(_TYPE::eof(),
_Sb.sputc(_Ch)))
break;
_CATCH_ALL
break;
_CATCH_END
++_Chcount; }
_CATCH_IO_END }
if (_Chcount == 0)
_St |= failbit;
setstate(_St);
return (*this); }
_Myt& getline(_E *_S, streamsize _N, _E _D = _E('\n'))
{iostate _St = goodbit;
_Chcount = 0;
const sentry _Ok(*this, true);
if (_Ok && 0 < _N)
{int_type _Di = _TYPE::to_int_type(_D);
_TRY_IO_BEGIN
int_type _C = rdbuf()->sgetc();
for (; ; _C = rdbuf()->snextc())
if (_TYPE::eq_int_type(_TYPE::eof(), _C))
{_St |= eofbit;
break; }
else if (_C == _Di)
{++_Chcount;
rdbuf()->snextc();
break; }
else if (--_N <= 0)
{_St |= failbit;
break; }
else
{++_Chcount;
*_S++ = _TYPE::to_char_type(_C); }
_CATCH_IO_END }
*_S = _E(0);
setstate(_Chcount == 0 ? _St | failbit : _St);
return (*this); }
_Myt& ignore(streamsize _N = 1, int_type _Di = _TYPE::eof())
{iostate _St = goodbit;
_Chcount = 0;
const sentry _Ok(*this, true);
if (_Ok && 0 < _N)
{_TRY_IO_BEGIN
for (; ; )
{int_type _C;
if (_N != INT_MAX && --_N < 0)
break;
else if (_TYPE::eq_int_type(_TYPE::eof(),
_C = rdbuf()->sbumpc()))
{_St |= eofbit;
break; }
else
{++_Chcount;
if (_C == _Di)
break; }}
_CATCH_IO_END }
setstate(_St);
return (*this); }
_Myt& read(_E *_S, streamsize _N)
{iostate _St = goodbit;
_Chcount = 0;
const sentry _Ok(*this, true);
if (_Ok)
{_TRY_IO_BEGIN
const streamsize _M = rdbuf()->sgetn(_S, _N);
_Chcount += _M;
if (_M != _N)
_St |= eofbit | failbit;
_CATCH_IO_END }
setstate(_St);
return (*this); }
streamsize readsome(_E *_S, streamsize _N)
{iostate _St = goodbit;
_Chcount = 0;
int _M;
if (rdbuf() == 0)
_St |= failbit;
else if ((_M = rdbuf()->in_avail()) < 0)
_St |= eofbit;
else if (0 < _M)
read(_S, _M < _N ? _M : _N);
setstate(_St);
return (gcount()); }
int_type peek()
{iostate _St = goodbit;
_Chcount = 0;
int_type _C;
const sentry _Ok(*this, true);
if (!_Ok)
_C = _TYPE::eof();
else
{_TRY_IO_BEGIN
if (_TYPE::eq_int_type(_TYPE::eof(),
_C = rdbuf()->sgetc()))
_St |= eofbit;
_CATCH_IO_END }
setstate(_St);
return (_C); }
_Myt& putback(_E _X)
{iostate _St = goodbit;
_Chcount = 0;
const sentry _Ok(*this, true);
if (_Ok)
{_TRY_IO_BEGIN
if (_TYPE::eq_int_type(_TYPE::eof(),
rdbuf()->sputbackc(_X)))
_St |= badbit;
_CATCH_IO_END }
setstate(_St);
return (*this); }
_Myt& unget()
{iostate _St = goodbit;
_Chcount = 0;
const sentry _Ok(*this, true);
if (_Ok)
{_TRY_IO_BEGIN
if (_TYPE::eq_int_type(_TYPE::eof(), rdbuf()->sungetc()))
_St |= badbit;
_CATCH_IO_END }
setstate(_St);
return (*this); }
streamsize gcount() const
{return (_Chcount); }
int sync()
{iostate _St = goodbit;
int _Ans;
if (rdbuf() == 0)
_Ans = -1;
else if (rdbuf()->pubsync() == -1)
_St |= badbit, _Ans = -1;
else
_Ans = 0;
setstate(_St);
return (_Ans); }
_Myt& seekg(const pos_type& _P)
{if (!fail())
rdbuf()->pubseekpos(_P, in);
return (*this); }
_Myt& seekg(const off_type& _O, ios_base::seekdir _W)
{if (!fail())
rdbuf()->pubseekoff(_O, _W, in);
return (*this); }
pos_type tellg()
{if (!fail())
return (rdbuf()->pubseekoff(0, cur, in));
else
return (streampos(_BADOFF)); }
private:
bool _Iswhite(int_type _C, const ctype<_E>& _Fac)
{return (!_TYPE::eq_int_type(_TYPE::eof(), _C)
&& _Fac.is(ctype<_E>::space, _TYPE::to_char_type(_C))); }
streamsize _Chcount;
};
// TEMPLATE CLASS basic_iostream
template<class _E, class _TYPE>
class basic_iostream : public basic_istream<_E, _TYPE>,
public basic_ostream<_E, _TYPE> {
public:
explicit basic_iostream(basic_streambuf<_E, _TYPE> *_S)
: basic_istream<_E, _TYPE>(_S), basic_ostream<_E, _TYPE>(_S)
{}
virtual ~basic_iostream()
{}
};
typedef basic_iostream<char, char_traits<char> > iostream;
typedef basic_iostream<wchar_t, char_traits<wchar_t> > wiostream;
// MANIPULATORS
template<class _E, class _TYPE> inline
basic_istream<_E, _TYPE>& ws(basic_istream<_E, _TYPE>& _I)
{const basic_istream<_E, _TYPE>::sentry _Ok(_I, true);
if (_Ok)
{const ctype<_E>& _Fac = _USE(_I.getloc(), ctype<_E>);
_TRY_IO_BEGIN
_TYPE::int_type _C = _I.rdbuf()->sgetc();
for (; !_TYPE::eq_int_type(_TYPE::eof(), _C)
&& _Fac.is(ctype<_E>::space, _TYPE::to_char_type(_C)); )
_C = _I.rdbuf()->snextc();
_CATCH_IO_(_I) }
return (_I); }
inline basic_istream<char, char_traits<char> >&
ws(basic_istream<char, char_traits<char> >& _I)
{typedef char _E;
typedef char_traits<_E> _TYPE;
const basic_istream<_E, _TYPE>::sentry _Ok(_I, true);
if (_Ok)
{const ctype<_E>& _Fac = _USE(_I.getloc(), ctype<_E>);
_TRY_IO_BEGIN
_TYPE::int_type _C = _I.rdbuf()->sgetc();
for (; !_TYPE::eq_int_type(_TYPE::eof(), _C)
&& _Fac.is(ctype<_E>::space, _TYPE::to_char_type(_C)); )
_C = _I.rdbuf()->snextc();
_CATCH_IO_(_I) }
return (_I); }
inline basic_istream<wchar_t, char_traits<wchar_t> >&
ws(basic_istream<wchar_t, char_traits<wchar_t> >& _I)
{typedef wchar_t _E;
typedef char_traits<_E> _TYPE;
const basic_istream<_E, _TYPE>::sentry _Ok(_I, true);
if (_Ok)
{const ctype<_E>& _Fac = _USE(_I.getloc(), ctype<_E>);
_TRY_IO_BEGIN
_TYPE::int_type _C = _I.rdbuf()->sgetc();
for (; !_TYPE::eq_int_type(_TYPE::eof(), _C)
&& _Fac.is(ctype<_E>::space, _TYPE::to_char_type(_C)); )
_C = _I.rdbuf()->snextc();
_CATCH_IO_(_I) }
return (_I); }
#ifdef _MSC_VER
#pragma pack(pop)
#endif /* _MSC_VER */
#endif /* _ISTREAM_ */
/*
* Copyright (c) 1994 by P.J. Plauger. ALL RIGHTS RESERVED.
* Consult your license regarding permissions and restrictions.
*/