// istream standard header #ifndef _ISTREAM_ #define _ISTREAM_ #include #include #include #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 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 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 > iostream; typedef basic_iostream > wiostream; // MANIPULATORS template 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 >& ws(basic_istream >& _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 >& ws(basic_istream >& _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. */