/*  
**  iomanip.h		C++ Runtime
**
**  Copyright (C)	Microway, Inc. 1987 - 1994.
**			P.O. BOX 79
**			Kingston, MA. 02364
**			(508) 746 - 7341 Voice
**			(508) 746 - 4678 FAX
**			e-mail tech@microway.com
**
**  This program is the property of Microway, Inc, its contents are
**  proprietary information and no part of it is to be disclosed to anyone
**  except employees of Microway, Inc., or as agreed in writing by the
**  President of Microway, Inc.
*/

#ifndef __IOMANIP_H
# define __IOMANIP_H
# include <iostream.h>
# include <generic.h>

#define SMANIP(T)   name2(_smanip_,T)
#define IMANIP(T)   name2(_imanip_,T)
#define OMANIP(T)   name2(_omanip_,T)
#define IOMANIP(T)  name2(_iomanip_,T)
#define SAPP(T)     name2(_sapp_,T)
#define IAPP(T)     name2(_iapp_,T)
#define OAPP(T)     name2(_oapp_,T)
#define IOAPP(T)    name2(_ioapp_,T)

/* these wretched manipulators work in the following inefficeint fashion: */
//	  cin << dec(3)
//	    becomes
//    IAPP(int) dec=dec 	    // variable initialized to function
//	  istream &operator<<(istream &,dec.operator()(3));
// Note that we have a function and a variable with the same name.
//	(surely that's illegal?) (Yup, the example in the book is wrong)

#define IOMANIPdeclare(T)				    \
class SMANIP(T) {					    \
    ios &(*fnc)(ios &,T);				    \
    T thing;						    \
public: 						    \
    SMANIP(T)(ios &(*f)(ios &,T),T a) : thing(a) { fnc=f; } \
    friend istream &operator>>(istream &s, SMANIP(T) f)     \
	{(*f.fnc)(s,f.thing); return( s ); }		    \
    friend ostream &operator<<(ostream &s, SMANIP(T) f)     \
	{(*f.fnc)(s,f.thing); return( s ); }		    \
};							    \
class IMANIP(T) {					    \
    istream &(*fnc)(istream &,T);			    \
    T thing;						    \
public: 						    \
    IMANIP(T)(istream &(*f)(istream &,T),T a) : thing(a) { fnc=f; }   \
    friend istream &operator>>(istream &s, IMANIP(T) f)     \
	{(*f.fnc)(s,f.thing); return( s ); }		    \
};							    \
class OMANIP(T) {					    \
    ostream &(*fnc)(ostream &,T);			    \
    T thing;						    \
public: 						    \
    OMANIP(T)(ostream &(*f)(ostream &,T),T a) : thing(a) { fnc=f; }   \
    friend ostream &operator<<(ostream &s, OMANIP(T) f)     \
	{(*f.fnc)(s,f.thing); return( s ); }		    \
};							    \
class IOMANIP(T) {					    \
    iostream &(*fnc)(iostream &,T);			    \
    T thing;						    \
public: 						    \
    IOMANIP(T)(iostream &(*f)(iostream &,T),T a) : thing(a) { fnc=f; }   \
    friend istream &operator>>(iostream &s, IOMANIP(T) f)   \
	{(*f.fnc)(s,f.thing); return( s ); }		    \
    friend ostream &operator<<(iostream &s, IOMANIP(T) f)   \
	{(*f.fnc)(s,f.thing); return( s ); }		    \
};							    \
class SAPP(T) { 					    \
    ios &(*fnc)(ios &,T);				    \
public: 						    \
    SAPP(T)(ios &(*f)(ios&,T)) { fnc = f; }		    \
    SMANIP(T) operator()(T a) { return( SMANIP(T)(fnc,a) ); } \
};							    \
class IAPP(T) { 					    \
    istream &(*fnc)(istream &,T);			    \
public: 						    \
    IAPP(T)(istream &(*f)(istream&,T)) { fnc = f; }	    \
    IMANIP(T) operator()(T a) { return( IMANIP(T)(fnc,a) ); } \
};							    \
class OAPP(T) { 					    \
    ostream &(*fnc)(ostream &,T);			    \
public: 						    \
    OAPP(T)(ostream &(*f)(ostream&,T)) { fnc = f; }	    \
    OMANIP(T) operator()(T a) { return( OMANIP(T)(fnc,a) ); } \
};							    \
class IOAPP(T) {					    \
    iostream &(*fnc)(iostream &,T);			    \
public: 						    \
    IOAPP(T)(iostream &(*f)(iostream&,T)) { fnc = f; }	    \
    IOMANIP(T) operator()(T a) { return( IOMANIP(T)(fnc,a) ); } \
};

IOMANIPdeclare(int);
IOMANIPdeclare(long);

SMANIP(int)	setbase(int);
SMANIP(long)	resetiosflags(long);
SMANIP(long)	setiosflags(long);
SMANIP(int)	setfill(int);
SMANIP(int)	setprecision(int);
SMANIP(int)	setw(int);

#endif
