You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
530 lines
16 KiB
530 lines
16 KiB
// -*- C++ -*-
|
|
/***************************************************************************
|
|
*
|
|
* istream - Declarations for the Standard Library istreams
|
|
*
|
|
* $Id: istream 186353 2014-07-29 16:30:44Z ransin01 $
|
|
*
|
|
***************************************************************************
|
|
*
|
|
* Copyright (c) 1994-2001 Rogue Wave Software, Inc. All Rights Reserved.
|
|
*
|
|
* This computer software is owned by Rogue Wave Software, Inc. and is
|
|
* protected by U.S. copyright laws and other laws and by international
|
|
* treaties. This computer software is furnished by Rogue Wave Software,
|
|
* Inc. pursuant to a written license agreement and may be used, copied,
|
|
* transmitted, and stored only in accordance with the terms of such
|
|
* license and with the inclusion of the above copyright notice. This
|
|
* computer software or any other copies thereof may not be provided or
|
|
* otherwise made available to any other person.
|
|
*
|
|
* U.S. Government Restricted Rights. This computer software is provided
|
|
* with Restricted Rights. Use, duplication, or disclosure by the
|
|
* Government is subject to restrictions as set forth in subparagraph (c)
|
|
* (1) (ii) of The Rights in Technical Data and Computer Software clause
|
|
* at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the
|
|
* Commercial Computer Software--Restricted Rights at 48 CFR 52.227-19,
|
|
* as applicable. Manufacturer is Rogue Wave Software, Inc., 5500
|
|
* Flatiron Parkway, Boulder, Colorado 80301 USA.
|
|
*
|
|
**************************************************************************/
|
|
|
|
#ifndef _RWSTD_ISTREAM_INCLUDED
|
|
#define _RWSTD_ISTREAM_INCLUDED
|
|
|
|
#include <iosfwd>
|
|
|
|
#ifndef _RWSTD_NO_REDUNDANT_DEFINITIONS
|
|
# include <ostream>
|
|
#endif // _RWSTD_NO_REDUNDANT_DEFINITIONS
|
|
|
|
#include <rw/_iosbase.h>
|
|
#include <rw/_numeric.h>
|
|
#include <rw/_traits.h>
|
|
|
|
#include <rw/_defs.h>
|
|
|
|
|
|
_RWSTD_NAMESPACE_BEGIN (__rw)
|
|
|
|
template <class _CharT, class _Traits, class _NativeType>
|
|
basic_istream<_CharT, _Traits>&
|
|
__rw_extract (_STD::basic_istream<_CharT, _Traits>&, _NativeType&);
|
|
|
|
_RWSTD_NAMESPACE_END // __rw
|
|
|
|
|
|
_RWSTD_NAMESPACE_BEGIN (std)
|
|
|
|
|
|
template<class _CharT, class _Traits /* = char_traits<char> */>
|
|
class basic_istream: virtual public basic_ios<_CharT, _Traits>
|
|
{
|
|
public:
|
|
|
|
typedef _CharT char_type;
|
|
typedef _Traits traits_type;
|
|
typedef _TYPENAME traits_type::int_type int_type;
|
|
typedef _TYPENAME traits_type::pos_type pos_type;
|
|
typedef _TYPENAME traits_type::off_type off_type;
|
|
|
|
// 27.6.1.1.1, p1
|
|
_EXPLICIT basic_istream (basic_streambuf<char_type, traits_type> *__sb)
|
|
: _C_chcount (0) {
|
|
this->init (__sb);
|
|
}
|
|
|
|
// called from sentry's ctor to prepare stream before input
|
|
basic_istream& _C_ipfx (int __flags);
|
|
|
|
// allow access to ios_base::_C_bufmutex()
|
|
class sentry;
|
|
friend class sentry;
|
|
|
|
// 27.6.1.1.2
|
|
class sentry: public _RW::__rw_guard
|
|
{
|
|
bool _C_ok;
|
|
|
|
sentry (const sentry&); // not defined
|
|
sentry& operator= (const sentry&); // not defined
|
|
|
|
public:
|
|
|
|
// 27.6.1.1.2, p2 - assumes 0 != __strm.rdbuf ()
|
|
_EXPLICIT sentry (basic_istream &__strm, bool __noskipws = false)
|
|
: _RW::__rw_guard (__strm._C_bufmutex ()) {
|
|
int __flags = (__strm.flags () & ios_base::skipws && !__noskipws ?
|
|
_C_skipws : 0) | _C_faileof;
|
|
_C_ok = __strm._C_ipfx (__flags).good ();
|
|
}
|
|
|
|
// 27.6.1.1.2, p8
|
|
operator bool () const {
|
|
return _C_ok;
|
|
}
|
|
};
|
|
|
|
// 27.6.1.2.3, p1
|
|
basic_istream& operator>> (basic_istream& (*__pf)(basic_istream&)) {
|
|
return (*__pf)(*this);
|
|
}
|
|
|
|
// 27.6.1.2.3, p2
|
|
basic_istream& operator>>(basic_ios<char_type, traits_type>& (*__pf)
|
|
(basic_ios<char_type, traits_type>&)) {
|
|
return (*__pf)(*this), *this;
|
|
}
|
|
|
|
// 27.6.1.2.3, p4
|
|
basic_istream& operator>> (ios_base& (*__pf)(ios_base&)) {
|
|
return (*__pf)(*this), *this;
|
|
}
|
|
|
|
|
|
// 27.6.1.2.2 - Arithmetic Extractors
|
|
|
|
#ifndef _RWSTD_NO_BOOL
|
|
|
|
basic_istream& operator>> (bool &__val) {
|
|
return _RW::__rw_extract (*this, __val);
|
|
}
|
|
|
|
#endif // _RWSTD_NO_BOOL
|
|
|
|
basic_istream& operator>>(short &__val) {
|
|
return _RW::__rw_extract (*this, __val);
|
|
}
|
|
|
|
basic_istream& operator>>(unsigned short &__val) {
|
|
return _RW::__rw_extract (*this, __val);
|
|
}
|
|
|
|
basic_istream& operator>>(int &__val) {
|
|
return _RW::__rw_extract (*this, __val);
|
|
}
|
|
|
|
basic_istream& operator>>(unsigned int &__val) {
|
|
return _RW::__rw_extract (*this, __val);
|
|
}
|
|
|
|
basic_istream& operator>>(long &__val) {
|
|
return _RW::__rw_extract (*this, __val);
|
|
}
|
|
|
|
basic_istream& operator>>(unsigned long &__val) {
|
|
return _RW::__rw_extract (*this, __val);
|
|
}
|
|
|
|
basic_istream& operator>>(float &__val) {
|
|
return _RW::__rw_extract (*this, __val);
|
|
}
|
|
|
|
basic_istream& operator>>(double &__val) {
|
|
return _RW::__rw_extract (*this, __val);
|
|
}
|
|
|
|
#ifndef _RWSTD_NO_LONG_DOUBLE
|
|
basic_istream& operator>>(long double &__val) {
|
|
return _RW::__rw_extract (*this, __val);
|
|
}
|
|
#endif // _RWSTD_NO_LONG_DOUBLE
|
|
|
|
#ifdef _RWSTD_LONG_LONG
|
|
|
|
basic_istream& operator>>(_RWSTD_LONG_LONG &__val) {
|
|
return _RW::__rw_extract (*this, __val);
|
|
}
|
|
|
|
basic_istream& operator>>(unsigned _RWSTD_LONG_LONG &__val) {
|
|
return _RW::__rw_extract (*this, __val);
|
|
}
|
|
|
|
#endif // _RWSTD_LONG_LONG
|
|
|
|
basic_istream& operator>>(void* &__val) {
|
|
return _RW::__rw_extract (*this, __val);
|
|
}
|
|
|
|
// extension
|
|
basic_istream& operator>> (basic_streambuf<char_type, traits_type> &__sb) {
|
|
// call extension
|
|
return get (__sb, traits_type::eof ());
|
|
}
|
|
|
|
// 27.6.1.2.3, p13
|
|
basic_istream& operator>>(basic_streambuf<char_type, traits_type> *__sb) {
|
|
return __sb ? *this >> *__sb
|
|
: (this->setstate (ios_base::failbit), *this);
|
|
}
|
|
|
|
// 27.6.1.3 - Unformatted input functions
|
|
|
|
// 27.6.1.3, p3
|
|
int_type get () {
|
|
return sentry (*this, true) ?
|
|
_C_unsafe_get (&_C_chcount, traits_type::eof (),
|
|
_C_faileof | _C_eatnull)
|
|
: traits_type::eof ();
|
|
}
|
|
|
|
// 27.6.1.3, p5
|
|
basic_istream& get (char_type& __ch) {
|
|
return read (&__ch, 1, traits_type::eof (), _C_failnoi | _C_eatnull);
|
|
}
|
|
|
|
// 27.6.1.3, p7: extract at most n - 1 chars, delim not extracted
|
|
// always null-terminate, fail if no char extracted
|
|
basic_istream& get (char_type *__s, streamsize __n, char_type __delim) {
|
|
return read (__s, __n, traits_type::to_int_type (__delim),
|
|
_C_nullterm | _C_failnoi | _C_eatnull);
|
|
}
|
|
|
|
// 27.6.1.3, p9: extract at most n - 1 chars
|
|
// always null-terminate, fail if no char extracted
|
|
basic_istream& get (char_type *__s, streamsize __n) {
|
|
return get (__s, __n, this->widen ('\n'));
|
|
}
|
|
|
|
// extension - first arg is a pointer to disambiguate the overloads
|
|
// in case both int_type and char_type are the same type
|
|
basic_istream& get (basic_streambuf<char_type, traits_type>*, int_type);
|
|
|
|
// 27.6.1.3, p12: extract up to but not including delim or eof
|
|
basic_istream& get (basic_streambuf<char_type, traits_type>& __sb,
|
|
char_type __delim) {
|
|
// using extension
|
|
return get (&__sb, traits_type::to_int_type (__delim));
|
|
}
|
|
|
|
// 27.6.1.3, p15
|
|
basic_istream& get (basic_streambuf<char_type, traits_type>& __sb) {
|
|
return get (__sb, this->widen ('\n'));
|
|
}
|
|
|
|
// 27.6.1.3, p16: extract at most n - 1, delim extracted but not stored
|
|
// fail if either 0 or n - 1 are extracted
|
|
basic_istream& getline (char_type *__s, streamsize __n, char_type __delim) {
|
|
// using extension
|
|
return read (__s, __n, traits_type::to_int_type (__delim),
|
|
_C_nullterm | _C_eatdelim | _C_eatnull
|
|
| _C_failend | _C_failnoi);
|
|
}
|
|
|
|
// 27.6.1.3, p23
|
|
basic_istream& getline (char_type *__s, streamsize __n) {
|
|
return getline (__s, __n, this->widen ('\n'));
|
|
}
|
|
|
|
// 27.6.1.3, p24: extract at most n including delim
|
|
basic_istream& ignore (streamsize __n = 1,
|
|
int_type __delim = traits_type::eof ()) {
|
|
// using extension - passing null pointer to ignore input
|
|
return read (0, __n, __delim, _C_eatdelim | _C_eatnull);
|
|
}
|
|
|
|
// extension
|
|
basic_istream& read (char_type*, streamsize, int_type, int);
|
|
|
|
// 27.6.1.3, p28: extract at most n, fail on eof
|
|
basic_istream& read (char_type*, streamsize);
|
|
|
|
// 27.6.1.3, p30: extract at most min (rdbuf()->in_avail(), n))
|
|
streamsize readsome (char_type*, streamsize);
|
|
|
|
// 27.6.1.3, p27
|
|
int_type peek ();
|
|
|
|
// 27.6.1.3, p37
|
|
pos_type tellg ();
|
|
|
|
// 27.6.1.3, p38
|
|
basic_istream& seekg (pos_type);
|
|
|
|
// 27.6.1.3, p40
|
|
basic_istream& seekg (off_type, ios_base::seekdir);
|
|
|
|
// 27.6.1.3, p36
|
|
int sync ();
|
|
|
|
// 27.6.1.3, p32
|
|
basic_istream& putback (char_type);
|
|
|
|
// 27.6.1.3, p34
|
|
basic_istream& unget ();
|
|
|
|
// 27.6.1.3, p2
|
|
streamsize gcount () const {
|
|
return _C_chcount;
|
|
}
|
|
|
|
// flags used by read() extension and _C_unsafe_get()
|
|
enum {
|
|
_C_nullterm = 0x01, // null-terminate input
|
|
_C_wsterm = 0x02, // terminate input on whitespace
|
|
_C_skipws = 0x04, // skip leading whitespace
|
|
_C_eatdelim = 0x08, // extract delimiter
|
|
_C_faileof = 0x10, // set ios_base::failbit on eof
|
|
_C_failend = 0x20, // set ios_base::failbit on end of buffer
|
|
_C_failnoi = 0x40, // set ios_base::failbit on no input
|
|
_C_eatnull = 0x80 // extract null char
|
|
};
|
|
|
|
// does not construct a sentry, does not affect gcount()
|
|
// extracts character unless it is equal to __delim
|
|
int_type _C_unsafe_get (streamsize* = 0,
|
|
int_type = traits_type::eof (),
|
|
int = 0);
|
|
|
|
protected:
|
|
|
|
streamsize _C_chcount; // number of chars extracted
|
|
};
|
|
|
|
|
|
// 27.6.1.4, p1
|
|
template<class _CharT, class _Traits>
|
|
inline basic_istream<_CharT, _Traits>&
|
|
ws (basic_istream<_CharT, _Traits> &__strm)
|
|
{
|
|
return __strm._C_ipfx (basic_istream<_CharT, _Traits>::_C_skipws);
|
|
}
|
|
|
|
|
|
template<class _CharT, class _Traits>
|
|
inline basic_istream<_CharT, _Traits>&
|
|
basic_istream<_CharT, _Traits>::seekg (pos_type __pos)
|
|
{
|
|
_RWSTD_ASSERT (0 != this->rdbuf ());
|
|
|
|
if (!this->fail ()) {
|
|
_RWSTD_MT_GUARD (this->_C_bufmutex ());
|
|
|
|
// 27.6.1.3, p 38 requires that pubseekpos be called with
|
|
// a single argument; the implemented behavior follows
|
|
// the proposed resolution of lwg issue 136
|
|
if (-1 == this->rdbuf ()->pubseekpos (__pos, ios_base::in))
|
|
this->setstate (ios_base::failbit); // lwg issue 129
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
|
|
template<class _CharT, class _Traits>
|
|
inline basic_istream<_CharT, _Traits>&
|
|
basic_istream<_CharT, _Traits>::seekg (off_type __off, ios_base::seekdir __dir)
|
|
{
|
|
_RWSTD_ASSERT (0 != this->rdbuf ());
|
|
|
|
if (!this->fail ()) {
|
|
_RWSTD_MT_GUARD (this->_C_bufmutex ());
|
|
|
|
// 27.6.1.3, p 40 requires that pubseekoff be called with
|
|
// two arguments; the implemented behavior follows
|
|
// the proposed resolution of lwg issue 136
|
|
if (-1 == this->rdbuf ()->pubseekoff (__off, __dir, ios_base::in))
|
|
this->setstate (ios_base::failbit); // lwg issue 129
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
|
|
#ifndef _RWSTD_NO_SIGNED_CHAR_IN_STREAMS
|
|
|
|
// 27.6.1.2.3, p10
|
|
template <class _Traits>
|
|
inline basic_istream<char, _Traits>&
|
|
operator>> (basic_istream<char, _Traits>& __strm,
|
|
unsigned char& __c)
|
|
{
|
|
return __strm >> _RWSTD_REINTERPRET_CAST (char&, __c);
|
|
}
|
|
|
|
template <class _Traits>
|
|
inline basic_istream<char, _Traits>&
|
|
operator>> (basic_istream<char, _Traits>& __strm,
|
|
signed char& __c)
|
|
{
|
|
return __strm >> _RWSTD_REINTERPRET_CAST (char&, __c);
|
|
}
|
|
|
|
|
|
// 27.6.1.2.3, p6
|
|
template <class _Traits>
|
|
inline basic_istream<char, _Traits>&
|
|
operator>> (basic_istream<char, _Traits>& __strm,
|
|
unsigned char* __s)
|
|
{
|
|
return __strm >> _RWSTD_REINTERPRET_CAST (char*, __s);
|
|
}
|
|
|
|
|
|
template <class _Traits>
|
|
inline basic_istream<char, _Traits>&
|
|
operator>> (basic_istream<char, _Traits>& __strm,
|
|
signed char* __s)
|
|
{
|
|
return __strm >> _RWSTD_REINTERPRET_CAST (char*, __s);
|
|
}
|
|
|
|
#endif // _RWSTD_NO_SIGNED_CHAR_IN_STREAMS
|
|
|
|
|
|
template<class _CharT, class _Traits>
|
|
inline _TYPENAME basic_istream<_CharT, _Traits>::int_type
|
|
basic_istream<_CharT, _Traits>::peek ()
|
|
{
|
|
_RWSTD_ASSERT (0 != this->rdbuf ());
|
|
|
|
_C_chcount = 0;
|
|
|
|
return sentry (*this, true) ? this->rdbuf ()->sgetc ()
|
|
: traits_type::eof ();
|
|
}
|
|
|
|
|
|
// 27.6.1.2.3, p10
|
|
template<class _CharT, class _Traits>
|
|
inline basic_istream<_CharT, _Traits>&
|
|
operator>> (basic_istream<_CharT, _Traits> &__strm, _CharT &__c)
|
|
{
|
|
// read the first non-space char, set failbit if none read
|
|
return __strm.read (&__c, 1, _Traits::eof (),
|
|
__strm._C_skipws | __strm._C_failnoi | __strm._C_eatnull);
|
|
}
|
|
|
|
|
|
// 27.6.1.2.3, p6
|
|
template<class _CharT, class _Traits>
|
|
inline basic_istream<_CharT, _Traits>&
|
|
operator>> (basic_istream<_CharT, _Traits> &__strm, _CharT *__s)
|
|
{
|
|
_RWSTD_ASSERT (0 != __s);
|
|
|
|
// store at most this many chars including terminating null
|
|
const streamsize __maxlen = __strm.width () ? __strm.width () :
|
|
numeric_limits<streamsize>::max () - 1;
|
|
|
|
// read at most __maxlen non-space chars up to the first whitespace
|
|
__strm.read (__s, __maxlen, _Traits::to_int_type (__strm.widen ('\n')),
|
|
__strm._C_nullterm | __strm._C_wsterm
|
|
| __strm._C_skipws | __strm._C_failnoi);
|
|
|
|
__strm.width (0);
|
|
|
|
return __strm;
|
|
}
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
basic_istream<_CharT, _Traits>&
|
|
operator>> (basic_istream<_CharT, _Traits>&,
|
|
basic_string<_CharT, _Traits, _Allocator>&);
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
basic_istream<_CharT, _Traits>&
|
|
getline (basic_istream<_CharT, _Traits>&,
|
|
basic_string<_CharT, _Traits, _Allocator>&,
|
|
_CharT);
|
|
|
|
|
|
template<class _CharT, class _Traits, class _Allocator>
|
|
inline basic_istream<_CharT, _Traits>&
|
|
getline (basic_istream<_CharT, _Traits>& __is,
|
|
basic_string<_CharT, _Traits, _Allocator>& __str)
|
|
{
|
|
return getline (__is, __str, __is.widen ('\n'));
|
|
}
|
|
|
|
|
|
// 27.6.1.5
|
|
template<class _CharT, class _Traits /* = char_traits<_CharT> */>
|
|
class basic_iostream
|
|
: public basic_istream<_CharT, _Traits>,
|
|
public basic_ostream<_CharT, _Traits>
|
|
{
|
|
public:
|
|
|
|
// prevent ambiguity between types defined in the bases
|
|
typedef _CharT char_type;
|
|
typedef _Traits traits_type;
|
|
typedef _TYPENAME traits_type::int_type int_type;
|
|
typedef _TYPENAME traits_type::pos_type pos_type;
|
|
typedef _TYPENAME traits_type::off_type off_type;
|
|
|
|
_EXPLICIT basic_iostream (basic_streambuf<_CharT, _Traits> *__sb)
|
|
: basic_istream<_CharT, _Traits> (__sb),
|
|
basic_ostream<_CharT, _Traits> (__sb)
|
|
{ /* 27.6.1.5.1, p1 */ }
|
|
};
|
|
|
|
|
|
_RWSTD_INSTANTIATE_2 (class _RWSTD_EXPORT
|
|
basic_istream<char, char_traits<char> >);
|
|
_RWSTD_INSTANTIATE_1 (_RWSTD_EXPORT istream& operator>> (istream&, string&));
|
|
_RWSTD_INSTANTIATE_1 (_RWSTD_EXPORT istream&
|
|
getline (istream&, string&, char));
|
|
|
|
#ifndef _RWSTD_NO_WCHAR_T
|
|
_RWSTD_INSTANTIATE_2 (class _RWSTD_EXPORT
|
|
basic_istream<wchar_t, char_traits<wchar_t> >);
|
|
_RWSTD_INSTANTIATE_1 (_RWSTD_EXPORT wistream&
|
|
operator>> (wistream&, wstring&));
|
|
_RWSTD_INSTANTIATE_1 (_RWSTD_EXPORT wistream&
|
|
getline (wistream&, wstring&, wchar_t));
|
|
#endif // _RWSTD_NO_WCHAR_T
|
|
|
|
_RWSTD_NAMESPACE_END // std
|
|
|
|
|
|
#if _RWSTD_DEFINE_TEMPLATE (BASIC_ISTREAM)
|
|
# include <istream.cc>
|
|
#endif
|
|
|
|
|
|
#endif // _RWSTD_ISTREAM_INCLUDED
|
|
|