/*
 *   iostream.h
 *
 *   C++ IOStreams and base classes.
 *
 *	   Copyright (c) 1991-1992, MetaWare Incorporated
 */

#ifndef __IOSTREAM_H
#define __IOSTREAM_H
#pragma push_align_members(64);

#c_include <memory.h>
	// ANSI version of memory.h is shipped in C++ include directory
	// to avoid problem with UNIX's non-prototyped memory.h.
//   EOF and NULL may have been defined elsewhere.
#ifndef EOF
# define EOF (-1)
#endif

#ifndef NULL
    #define NULL 0
#endif

#if _NONEXCEPT_LIB
    #pragma off(exception_aware_class);
#elif _MSDOS || _MSNT || _OS2
    #pragma on(exception_aware_class);
#endif

#if _MSNT && _DLL && !_DLLBUILD
    #pragma on(dllimport);
#endif


#pragma off(Behaved)
#pragma off(try_static_cast)
//   Extract a character from c, eliminating possibility of EOF.
#define zapeof(c) ((unsigned char)(c))

typedef long streampos;
typedef long streamoff;

class streambuf;
class ostream;

// #define _OLD_IOSTREAM	// if defined, enables old version of xalloc

// Definitions for multi-thread libraries
#if _MT
    #define _MT_ONLY(X) X
    #define _UNSAFE(X) X ## _unsafe
    #define _LOCK_THIS _stream_lock l1(this);
    #define _LOCK_BUF  _stream_lock l2(rdbuf());
    #define _MT_OR_ST(X,Y) X

    typedef void * _mt_lock;

    extern "C" {
	_mt_lock  _mwinit_lock  (void);
	void      _mwlock       (_mt_lock);
	void	  _mwunlock     (_mt_lock);
	void	  _mwdelete_lock(_mt_lock);
	}
#else
    #undef  _MT
    #define _MT_ONLY(X)
    #define _UNSAFE(X) X
    #define _LOCK_THIS
    #define _LOCK_BUF
    #define _MT_OR_ST(X,Y) Y
#endif

#pragma on(nodebug)
/*---------------------------------------------------------------------------
 * class _mt_stream
 *
 *	Base class for all multi-thread-safe classes.
 */

#if _MT

class _mt_stream {

private:
	_mt_lock	mutex;		// mutual exclusion lock
	int		lock_flag;	// non-zero if locking is required

protected:
	_mt_lock get_mutex() { return mutex; }
	int get_lock_flag() { return lock_flag; }
public:
	_mt_stream(int safe = 1) {
		lock_flag = safe;	// set safety flag
		mutex = _mwinit_lock();
		}

	~_mt_stream() { _mwdelete_lock(mutex); }

	void lock()	{		// lock the stream
		if (lock_flag) _mwlock(mutex); }

	void unlock() {		// unlock the stream
    		if (lock_flag) _mwunlock(mutex); }

	void clr_safe() {		// mark the stream as unsafe
		_mwlock(mutex);
		if (lock_flag)
			lock_flag--;
		_mwunlock(mutex);
		}

	void set_safe() {		// mark the stream as safe
		_mwlock(mutex);
		lock_flag++;
		_mwunlock(mutex);
		}

	friend class _stream_lock;
	};

/*---------------------------------------------------------------------------
 * class _stream_lock:
 *
 *	Class for locking and unlocking streams.
 *
 *	Use this class instead of explicitly locking or
 *	unlocking a stream, because its destructor will
 *	automatically clean up the lock.  This makes
 *	it safe even if an exception should occur while
 *	a stream is locked.
 */

class _stream_lock {

private:
	_mt_lock	mutex;		// mutual exclusion semaphore
	int		count;		// no. of times mutex has been locked

	void do_lock() {
		_mwlock(mutex);
		count++;
		}

	void do_unlock() {
		if (count) {
			--count;
			_mwunlock(mutex);
			}
		}

	void init_lock(_mt_lock p, int lock_now) {
		mutex = p;
		count = 0;
		if (lock_now)
			do_lock();
		}

public:
	/* Constructors allow references or pointers to
	 * streams or mutexes. The optional second parameter
	 * is non-zero if the mutex should be locked now.
	 */
	_stream_lock(_mt_stream &strm, int lock_now = 1) {
		init_lock(strm.get_mutex(), lock_now && strm.get_lock_flag());
		}

	_stream_lock(_mt_stream *strmp, int lock_now = 1) {
		init_lock(strmp->get_mutex(),
			lock_now && strmp->get_lock_flag());
		}

	_stream_lock(_mt_lock &mutex, int lock_now = 1) {
		init_lock(mutex, lock_now);
		}

	_stream_lock(_mt_lock *mutexp, int lock_now = 1) {
		init_lock(*mutexp, lock_now);
		}

	~_stream_lock() {
		do_unlock();
		}

	void lock() {
		do_lock();
		}

	void unlock() {
		do_unlock();
		}
	};

#endif	// _MT


/*---------------------------------------------------------------------------
 *   Class ios:
 *
 *      I/O Status values and access members.
 *
 */

class ios _MT_ONLY(: public _mt_stream) {

//   Public constants and enumerations.
public:
	// Stream status
	enum io_state   { 
	    goodbit	= 0x00,	// No error
	    eofbit	= 0x01,	// End-of-file reached
	    failbit     = 0x02,	// Insertion/extraction failed
	    range_errbit= 0x04,	// Value out of range
	    badbit	= 0x08,	// Access failed
	    hardfail    = 0x80 	// Unrecoverable error
	    };

	// Stream I/O mode
	enum open_mode  { 
	    in	     = 0x01,	// Input
	    out	     = 0x02,	// Output
	    ate	     = 0x04,	// Seek to EOF at open
	    app	     = 0x08,	// All operations append
	    trunc    = 0x10,	// Truncate file
	    nocreate = 0x20,	// Do not create file
	    noreplace= 0x40,	// Do not overwrite file
	    binary   = 0x80	// Binary file (no CR/LF translation).
	    };

	// Stream seek direction
	enum seek_dir   { 
	    beg	     = 0x00,	// Seek from beginning
	    cur	     = 0x01,	// Seek from current position
	    end	     = 0x02	// Seek from end
	    };

	// Formatting flags
	enum		{ 
	    skipws     = 0x01,	// Skip whitespace on input
				       
	    left       = 0x02,	// Padding location
	    right      = 0x04,
	    internal   = 0x08,	// Between sign and digits
					
	    dec	     = 0x10,	// Conversion base
	    oct	     = 0x20,
	    hex	     = 0x40,

	    showbase   = 0x80,	// Show base on output (eg. 0x)
	    showpoint  = 0x100,	// Print trailing zeros,decimals
	    uppercase  = 0x200,	// Use uppercase E,X
	    showpos    = 0x400,	// Print leading + for positive
				// Floating point notation
	    scientific = 0x800,	// 5.6789e3
	    fixed      = 0x1000,// 5678.9 
						    
	    unitbuf    = 0x2000,// Buffering--if set, flush after 
				// operation complete, not every character.
	    keepwidth  = 0x4000,// If set, width is NOT reset
				//  after each operation.
	    input_seps = 0x8000,// Allow digit separators on input.
	    char_width_1= 0x10000,// Char inserter ignores width setting.
	    fp_bases   = 0x20000,// Floating point inserters
				//  respect base setting.
	    stdio      = 0x40000// Flush stdout, stderr
	    };

	// Constants for use in second argument to setf().
	static const long basefield;		//  dec | oct | hex;
	static const long adjustfield;	//  left | right | internal;
	static const long floatfield;		//  scientific | fixed;

private:
	void		ios_check();
	// Privates for implementing allocated bits and words.
	static unsigned long     priv_nextbit;
	static unsigned long     priv_nextword;
	unsigned long     old_priv_nextword;  // unused. supposed to be static

	long		priv_numuwords;
	union ios_user_union {
	    long	long_value;
	    void *	pointer_value;
	    };
	ios_user_union*   priv_userwords;
	int		priv_user_resize(long __newsize);


protected:

			ios(ios&);		// Declared but not defined.
	void		operator=(ios&);	// Causes error on copy.

			// Special flags
	enum		{ skipping=0x200,	// Skipping whitespace
			  tied=0x400		// Tied to another stream
			};
			
	streambuf*	bp;			// streambuf for this ios

			// Set status to __new_state
	void		_UNSAFE(setstate)(int __new_state) {
				state |= (__new_state & 0xff);
				}

	long		state;		// Userbits and error state
	long		ispecial;	// Input special flags
	long		ospecial;	// Output special flags
	long		isfx_special;	// Input suffix special flags
	long		osfx_special;	// Output suffix special flags
	long		delbuf;

	long		x_flags;	// Formatting flags
	short		x_width;	// Field width
	short		x_precision;	// Precision
	char		x_fill;		// Fill character
	char		x_decimal;	// Decimal character
	char		x_digsep;	// Digit separator character
	short		x_sepfreq;	// Digit separator frequency
	ostream*	x_tie;		// Link to tied output stream

	static void     (*_UNSAFE(stdioflush))();   // Function to flush stdio

			// Does the real work of a constructor.
	void		init(streambuf* __buffer);

			ios();  // No initialization. Needed by
				//  multiple-inheritance versions.
	int		assign_private; // Needed by with_assign classes.

public:

			ios(streambuf* __buffer);

	virtual		~ios();

			// Read flags.
	long		flags() const { return x_flags; }

			// Set flags, return previous.
	long		_UNSAFE(flags)(long __newflags);

			// Set flags, return previous.
	long		_UNSAFE(setf)(long __setbits, long __field);

			// Turn on bits set in __setbits, return previous value.
	long		_UNSAFE(setf)(long __setbits);

			// Turn off bits set in __unsetbits, return prev.
	long		_UNSAFE(unsetf)(long __unsetbits);

    			// Return current width.
	int		width() const { return x_width; }

			// Set width, return previous value.
	int		_UNSAFE(width)(int __new_width)  {
				int temp = x_width;
				x_width = __new_width;
				return temp;
				}

			// Read tie value.
	ostream*	tie() const { return x_tie; }

  			// Tie to __tie_stream.
	ostream*	_UNSAFE(tie)(ostream* __tie_stream);

			// Read fill value.
	char		fill() const { return x_fill; }

			// Set fill char to __fillc, return previous.
	char		_UNSAFE(fill)(char __fillc);

			// Read decimal character
	char		decimal_point() const { return x_decimal; }

			// Set decimal char to __decimalc, return previous.
	char		_UNSAFE(decimal_point)(char __decimalc) {
				char tmp = x_decimal;
				if (__decimalc !=0) x_decimal = __decimalc;
				return tmp;
				}

			// Read digit separator character
	char		digit_sep() const { return x_digsep; }

			// Set digit separator char to __sepchar
	char		_UNSAFE(digit_sep)(char __sepchar) {
				char temp = x_digsep;
				x_digsep = __sepchar;
				return temp;
				}

			// Read digit separator character
	int		digit_sep_freq() const { return x_sepfreq; }

			// Set digit separator frequenct to __sepfreq
	int		_UNSAFE(digit_sep_freq)(char __sepfreq) {
				int temp = x_sepfreq;
				x_sepfreq = __sepfreq;
				return temp;
				}

			// Read current precision
	int		precision() { return x_precision; }

			// Set precision to __prec, return previous.
	int		_UNSAFE(precision)(int __prec);

			// Read state.
	int		rdstate() const { return state; }

			// Typecast operator.
			// Return valid pointer only if state is not bad.
			operator void*() {
				if(state&(failbit|badbit|hardfail)) return NULL;
				else return this;
				}

			// Check state -- 0 if state is bad, 1 otherwise
	int		operator!()
				{ return (state&(failbit|badbit|hardfail)); }

			// Check for EOF
	int		eof()   const { return (state&eofbit); }

			// Check for failed operation
	int		fail()  const { return (state&(failbit|badbit|hardfail)); }

			// Check for unusable stream
	int		hard_fail()  const { return (state&(hardfail)); }

			// Check for bad stream status
	int		bad()   const { return (state&badbit); }

			// Check for range error status
	int		range_err()   const { return (state&range_errbit); }

			// Check for good stream status
	int		good()  const { return (state==0); }

			// Clear status, set to __init
			// Note: Only modifies standard state flags
	void		_UNSAFE(clear)(int __init = 0) {
				state =  (__init&0xff) | (state&hardfail);
				}

			// Clear status, set to __init
			// Use this function to modify user-defined
			//  state flags.
			// This function is the same as clear(), except
			//  that it modifies all state flags.
	virtual void	_UNSAFE(set_err)(int __init = 0) {
				state =  __init | (state&hardfail);
				}

			// Get pointer to associated streambuf
	streambuf*	rdbuf() { return bp;}

	// Members related to user-allocated bits and words.

			// Returns __index_num'th user-defined flag word.
	long &		iword(int __index_num);

			// Returns __index_num'th user-defined flag word.
	void* &		pword(int __index_num);

			// Returns a long with one previously-unused bit set.
			// This can be used as a user error flag.
	static long	bitalloc();

			// Returns a previously-unused index into an array of
			//  words available for use as format state variables.
			// For use by derived classes.
#ifndef _OLD_IOSTREAM
	static
#endif
	int	xalloc();

			// Allows mixed use of stdio FILE*'s and streams.
			// Has an effect only the first time called.
	static void	sync_with_stdio();
#if _MT
private:
	static _mt_lock	static_mutex;		// mutex for static members
protected:
	void		setstate(int __new_state);
	static void     (*stdioflush)();	// Function to flush stdio
public:
	long		flags(long __newflags);
	long		setf(long __setbits, long __field);
	long		setf(long __setbits);
	long		unsetf(long __unsetbits);
	int		width(int __new_width);
	ostream*	tie(ostream* __tie_stream);
	char		fill(char __fillc);
	char		decimal_point(char __decimalc);
	char		digit_sep(char __sepchar);
	int		digit_sep_freq(char __sepfreq);
	int		precision(int __prec);
	void		clear(int __init = 0);
	virtual void	set_err(int __init = 0);
#endif
	};

/*---------------------------------------------------------------------------
 *   Class streambuf
 *
 *      Base stream-buffer class.
 *
 */

class streambuf _MT_ONLY(: public _mt_stream) {

private:
	void		check_stat();
	short		priv_alloc;	// TRUE == Delete buffer on setbuf
	short		priv_unbuf;	// TRUE == unbuffered stream
	char*		priv_base;	// Base of reserve area.
	char*		priv_ebuf;	// Byte after end of reserve area.
	char*		priv_pbase;	// Base of put area.
	char*		priv_pptr;	// Current position in put area.
	char*		priv_epptr;	// Byte after end of put area.
	char*		priv_gptr;	// Current position in get area.
	char*		priv_egptr;	// Byte after end of get area.
	char*		priv_eback;	// Lower bound of gptr -- space
					//  available for putback.

	int		priv_snextc();
	
protected:
			// Copy operators declared but not defined.
			// Declaring as protected causes compiler to produce
			//  an error if an assignment of a streambuf is 
			//  attempted.  This is desirable, as assignment
			//  of streambufs is not well-defined.
			streambuf(streambuf&);
	void		operator=(streambuf&);
	
			streambuf();
			streambuf(char* __buf, int __len);

	char*		base()  const { return priv_base; }
	char*		pbase() const { return priv_pbase; }
	char*		pptr()  const { return priv_pptr; }
	char*		epptr() const { return priv_epptr; }
	char*		gptr()  const { return priv_gptr; }
	char*		egptr() const { return priv_egptr; }
	char*		eback() const { return priv_eback; }
	char*		ebuf()  const { return priv_ebuf; }
	int		_UNSAFE(blen)()  {
				return ((priv_ebuf>priv_base)
					? (priv_ebuf-priv_base)
					: 0);
				}

	void		_UNSAFE(setp)(char*  __p, char*  __ep) {
				priv_pbase=priv_pptr=__p; priv_epptr=__ep;
				}

	void		_UNSAFE(setg)(char*  __eb, char*  __g, char*  __eg) {
				priv_eback=__eb; priv_gptr=__g; priv_egptr=__eg;
				}

	void		_UNSAFE(pbump)(int __num) {
				priv_pptr+=__num;
				}

	void		_UNSAFE(gbump)(int __num) {
				priv_gptr+=__num;
				}

	void		_UNSAFE(setb)(char* __b, char* __eb, int __a = 0 ) {
				if ( priv_alloc && priv_base ) delete priv_base;
				priv_base = __b;
				priv_ebuf = __eb;
				priv_alloc = __a;
				priv_unbuf = (__eb<=__b?1:0);
				}

	int		unbuffered() const { return priv_unbuf; }

	void		unbuffered(int __unb) { priv_unbuf = (__unb!=0); }

	int		_UNSAFE(allocate)() {
				if ( priv_base == 0 && !unbuffered() )
					return _UNSAFE(doallocate)();
				else
					return 0;
				}

	virtual int	_UNSAFE(doallocate)();
	
	virtual int	_UNSAFE(xsputn)(const char* __str, int __num);
	virtual int	_UNSAFE(xsgetn)(char* __str,int __num);

public :
	void		_UNSAFE(dbp)(int __level=0);
	virtual int	_UNSAFE(overflow)(int __c=EOF);
	virtual int	_UNSAFE(underflow)();
	virtual int	_UNSAFE(pbackfail)(int __c);
	virtual int	_UNSAFE(sync)();
	
	virtual streampos
		_UNSAFE(seekoff)(streamoff __offset, ios::seek_dir __dir,
				long __mode=ios::in|ios::out);
	virtual streampos
		_UNSAFE(seekpos)(streampos __pos, long __mode=ios::in|ios::out);

	int		_UNSAFE(in_avail)() const {
				return (priv_gptr<priv_egptr
					? priv_egptr-priv_gptr
					: 0);
				}

	int		_UNSAFE(out_waiting)() const {
				if ( priv_pptr ) return priv_pptr-priv_pbase;
				else return 0;
				}

			// *** WARNING: sgetc does not bump the get pointer
	int		_UNSAFE(sgetc)() {
				return (priv_gptr>=priv_egptr)
					? _UNSAFE(underflow)()
					: zapeof(*priv_gptr);
				}

	int		_UNSAFE(snextc)() {
				return (++priv_gptr>=priv_egptr)
					? priv_snextc()
					: zapeof(*priv_gptr);
				}

	int		_UNSAFE(sbumpc)() {
				return ((priv_gptr>=priv_egptr
					  && _UNSAFE(underflow)()==EOF)
					? EOF
					: zapeof(*priv_gptr++));
				}

	void		_UNSAFE(stossc)() {
				if (priv_gptr>=priv_egptr) _UNSAFE(underflow)();
				else ++priv_gptr;
				}

	int		_UNSAFE(sputbackc)(char __c) {
				if (priv_gptr > priv_egptr) return EOF;
				if (priv_gptr > priv_eback ) {
					if ( *--priv_gptr == __c )
						return zapeof(__c);
					else return zapeof(*priv_gptr=__c);
					}
				else {
					return _UNSAFE(pbackfail)(__c);
					}
				}

	int		_UNSAFE(sputc)(int __c) {
				return (priv_pptr>=priv_epptr)
					? _UNSAFE(overflow)((int)zapeof(__c))
					: zapeof(*priv_pptr++=__c);
				}

	int		_UNSAFE(sputn)(const char* __str,int __num) {
				if ( __num <= (priv_epptr-priv_pptr) ) {
					memcpy(priv_pptr, __str, __num);
					_UNSAFE(pbump)(__num);
					return __num;
					}
				else {
					return _UNSAFE(xsputn)(__str, __num);
					}
				}

	int		_UNSAFE(sgetn)(char* __str,int __num) {
				if ( __num <= (priv_egptr-priv_gptr) ) {
					memcpy(__str,(const char*)priv_gptr,
					       __num);
					_UNSAFE(gbump)(__num);
					return __num;
					}
				else {
					return _UNSAFE(xsgetn)(__str, __num);
					}
				}

	virtual streambuf*
			setbuf(char* __buf, int __len);

	streambuf*	setbuf(unsigned char* __buf, int __len) {
				return (setbuf((char*)__buf, __len));
				}

	virtual		~streambuf();
#if _MT
protected:
	int		blen();
	void		setp(char*  __p, char*  __ep);
	void		setg(char*  __eb, char*  __g, char*  __eg);
	void		pbump(int __num);
	void		gbump(int __num);
	void		setb(char* __b, char* __eb, int __a = 0 );
	int		allocate();
	virtual int	doallocate();
	virtual int	xsputn(const char* __str, int __num);
	virtual int	xsgetn(char* __str,int __num);
public :
	void		dbp(int __level=0);
	virtual int	overflow(int __c=EOF);
	virtual int	underflow();
	virtual int	pbackfail(int __c);
	virtual int	sync();
	virtual streampos
		seekoff(streamoff __offset, ios::seek_dir __dir,
				long __mode=ios::in|ios::out);
	virtual streampos
		seekpos(streampos __pos, long __mode=ios::in|ios::out);
	int		in_avail();
	int		out_waiting();
	int		sgetc();
	int		snextc();
	int		sbumpc();
	void		stossc();
	int		sputbackc(char __c);
	int		sputc(int __c);
	int		sputn(const char* __str,int __num);
	int		sgetn(char* __str,int __num);
#endif
	};


/*---------------------------------------------------------------------------
 *   Class istream
 *
 */

class istream : virtual public ios {

private:
	int		priv_gcount;		// Keep track of # of chars
						//  last extracted.
	void		ischeck_state();
	void		_doget(char* __c);	// Actually does a get.

protected:
	int		_UNSAFE(do_ipfx)(int __noskipws);
	void		_UNSAFE(do_isfx)();
	int		_UNSAFE(eatwhite)(void);
			istream();
			
public:
			istream(streambuf *__buffer);
	virtual		~istream();
	
	int		_UNSAFE(ipfx)(int __noskipws=0) {
				if ( __noskipws?(ispecial&~skipping):ispecial) {
					return _UNSAFE(do_ipfx)(__noskipws);
					}
				else return 1;
				}

	void		_UNSAFE(isfx)() {
				if (isfx_special) _UNSAFE(do_isfx)();
				}

	istream&	seekg(streampos __position);
	istream&	seekg(streamoff __offset, ios::seek_dir __dir);

			// Returns the current offset into the get buffer.
	streampos	tellg();

			// For manipulators.
	istream&	operator>> (istream& (*__fcn)(istream&)) {
				return (*__fcn)(*this);
				}

			// For manipulators.
	istream&	operator>> (ios& (*__fcn)(ios&) );

	istream&	operator>>(char *__cp);
	istream&	operator>>(unsigned char *__ucp);
	istream&	operator>>(unsigned char &__ucr);
	istream&	operator>>(char& __cr);
	istream&	operator>>(short& __sr);
	istream&	operator>>(int& __ir);
	istream&	operator>>(long& __lr);
	istream&	operator>>(unsigned short& __usr);
	istream&	operator>>(unsigned int& __uir);
	istream&	operator>>(unsigned long& __ulr);
	istream&	operator>>(float& __fr);
	istream&	operator>>(double& __dr);
	istream&	operator>>(long double& __ldr);
	istream&	operator>>(streambuf* __sp);

			// Read and extract characters ending in delim,
			//  up to a maximum of lim characters.
			// delim IS NOT stored in buffer.
	istream&	get(char* __buffer, int __lim, char __delim='\n');
	istream&	get(unsigned char* __buffer, int __lim, char __delim='\n');
	istream&	get(char* __buffer, int __lim, char *__delims);
	istream&	get(unsigned char* __buffer, int __lim, char *__delims);

			// Read and extract characters ending in delim,
			//  up to a maximum of lim characters.
			// delim IS stored in buffer if space allows.
	istream&	getline(char* __buffer, int __lim, char __delim='\n');
	istream&	getline(unsigned char* __buffer,int __lim, char __delim='\n'); 
	istream&	getline(char* __buffer, int __lim, char *__delims);
	istream&	getline(unsigned char* __buffer,int __lim, char *__delims); 
			// Read and extract character.
	istream&	get(streambuf& __sb, char __delim ='\n');
	istream&	get(unsigned char& __c);
	istream&	get(char& __c);
	int		_UNSAFE(get)();

			// Read next character, but don't extract.
	int		_UNSAFE(peek)() {
				if ( _UNSAFE(ipfx)(-1) )
				    return rdbuf()->_UNSAFE(sgetc)();
				else return EOF;
				}

			// Extract and trash n characters, stopping
			//  if delim is encountered.
	istream&	ignore(int __num=1,int __delim=EOF);

	istream&	read(char* __buf,int __num);
	istream&	read(unsigned char* __buf,int __num) {
				return read((char*)__buf,__num);
				}
	int		gcount() { return priv_gcount; }
	istream&	putback(char __c);
	int		_UNSAFE(sync)()  { return rdbuf()->_UNSAFE(sync)(); }

#if _MT
protected:
	int		do_ipfx(int __noskipws);
	void		do_isfx();
	int		eatwhite(void);
public:
	int		ipfx(int __noskipws=0);
	void		isfx();
	int		peek();
	int		sync();
	int		get();
	istream&	operator_shrd_unsafe(double& __dr);
	istream&	operator_shrc_unsafe(char& __cr);
#endif
	};


/*---------------------------------------------------------------------------
 *   Class ostream
 *
 */

class ostream : virtual public ios {

protected:
	int		_UNSAFE(do_opfx)();
	void		_UNSAFE(do_osfx)();
			ostream();

public:
			ostream(streambuf *__sbp);
	virtual		~ostream();

	int		_UNSAFE(opfx)() {
				if (!good()) return 0;
				else if (ospecial) return _UNSAFE(do_opfx)();
				else return 1;
				}

	void		_UNSAFE(osfx)() {
				if (osfx_special) _UNSAFE(do_osfx)();
				}

	ostream&	_UNSAFE(flush)();

	ostream&	seekp(streampos __pos);
	ostream&	seekp(streamoff __off, ios::seek_dir __dir);
	streampos	tellp();

	ostream&	put(char __c);

	ostream&	operator<<(char __c) {
				return put(__c);
				}

	ostream&	operator<<(unsigned char __uc) {
				return put(__uc);
				}

	ostream&	operator<<(const char* __ccp);
	ostream&	operator<<(int __i);
	ostream&	operator<<(long __l);
	ostream&	operator<<(double __d);
	ostream&	operator<<(long double __ld);
	ostream&	operator<<(float __f);
	ostream&	operator<<(unsigned int  __ui);
	ostream&	operator<<(unsigned long __ul);
	ostream&	operator<<(void* __vp);
	ostream&	operator<<(streambuf* __sbp);
	ostream&	operator<<(short __s);
	ostream&	operator<<(unsigned short __us);

			// For manipulators.
	ostream&	operator<<(ostream& (*__fcn)(ostream&)) {
				return (*__fcn)(*this);
				}

			// For manipulators.
	ostream&	operator<<(ios& (*__fcn)(ios&) );

	ostream&	write(const char* __str,int __num);
	ostream&	write(const unsigned char* __str, int __num) {
				return write((const char*)__str,__num);
				}
#if _MT
protected:
    int			do_opfx();
    void		do_osfx();
public:
    int			opfx();
    void		osfx();
    ostream&		flush();
    ostream&		operator_shlccp_unsafe(const char *__ccp);
#endif
	};

/*---------------------------------------------------------------------------
*/
class iostream : public istream, public ostream {
protected:
			iostream();

public:
			iostream(streambuf* __sbp);
	virtual		~iostream();
	};


class istream_withassign : public istream {
public:
				istream_withassign();
	virtual			~istream_withassign();
	istream_withassign&	operator=(istream&);
	istream_withassign&	operator=(streambuf*);
	};


class ostream_withassign : public ostream {
public:
				ostream_withassign();
	virtual			~ostream_withassign();
	ostream_withassign&	operator=(ostream&);
	ostream_withassign&	operator=(streambuf*);
	};


class iostream_withassign : public iostream {
public:
				iostream_withassign();
	virtual			~iostream_withassign();
	iostream_withassign&	operator=(ios&);
	iostream_withassign&	operator=(streambuf*);
	};
#pragma pop(nodebug)

/*---------------------------------------------------------------------------
*/
extern istream_withassign cin;
extern ostream_withassign cout;
extern ostream_withassign cerr;
extern ostream_withassign clog;
#ifdef _MSDOS
// Additional standard streams provided under DOS
extern ostream_withassign caux;
extern ostream_withassign cprn;
#endif

extern ostream&		endl(ostream& os);
extern ostream&		ends(ostream& os);
extern ostream&		flush(ostream& os);
extern ios&		dec(ios& iosr);
extern ios&		oct(ios& iosr);
extern ios&		hex(ios& iosr);
extern istream&		ws(istream& is);

#if _MSNT && _DLL && !_DLLBUILD
    #pragma pop(dllimport);
#endif


#if _NONEXCEPT_LIB
    #pragma pop(exception_aware_class);
#elif _MSDOS || _MSNT || _OS2
    #pragma pop(exception_aware_class);
#endif

#pragma pop(try_static_cast)
#pragma pop(Behaved)
#pragma pop_align_members();
#endif


/**	  Copyright (c) 1991-1993, MetaWare Incorporated	     **/
