.\" '\" tep .\" to invoke 'tbl', 'eqn', 'pic' in the proper order .\" .\" @(#)manip.3 1.7 00/02/18 SMI; .\" .TH MANIP 3CC4 "14 March 1995" .\" .SH NAME manip \- iostream manipulators .SH SYNOPSIS .LP .nf .ft B #include #include .sp .5v #define IOMANIPdeclare(typ) \fI expands to the following definitions ... \fB .sp .5v class SMANIP(typ) { public: SMANIP(typ)(ios& (*)(ios&, typ), typ); friend istream& operator>>(istream&, SMANIP(typ)&); friend ostream& operator<<(ostream&, SMANIP(typ)&); }; class SAPP(typ) { public: SAPP(typ)(ios& (*)(ios&, typ)); SMANIP(typ) operator()(typ); }; class IMANIP(typ) { public: IMANIP(typ)(istream& (*)(istream&, typ), typ); friend istream& operator>>(istream&, IMANIP(typ)&); }; class IAPP(typ) { public: IAPP(typ)(istream& (*)(istream&, typ)); IMANIP(typ) operator()(typ); }; class OMANIP(typ) { public: OMANIP(typ)(ostream& (*)(ostream&, typ), typ); friend ostream& operator<<(ostream&, OMANIP(typ)&); }; class OAPP(typ) { public: OAPP(typ)(ostream& (*)(ostream&, typ)); OMANIP(typ) operator()(typ); }; class IOMANIP(typ) { public: IOMANIP(typ)(iostream& (*)(iostream&, typ), typ); friend istream& operator>>(iostream&, IOMANIP(typ)&); friend ostream& operator<<(iostream&, IOMANIP(typ)&); }; class IOAPP(typ) { public: IOAPP(typ)(iostream& (*)(iostream&, typ)); IOMANIP(typ) operator()(typ); }; .sp .5v IOMANIPdeclare(int); IOMANIPdeclare(long); .sp .5v smanip_long resetiosflags(long); smanip_int setbase(int); smanip_int setfill(int); smanip_long setiosflags(long); smanip_int setprecision(int); smanip_int setw(int); .ft R .fi .\" .SH DESCRIPTION .LP A \fImanipulator\fR appears to be an object inserted or extracted into a stream, but many only change the state of the stream. Their purpose is to embed what is really a function call into a sequence of insertions or extractions as a convenience. For example, instead of writing: .in +.5i .ft B .nf cout.width(8); cout << val1 << " "; cout.width(4); cout << val2 << '\\n'; cout.flush(); .ti -.5i \fRwe can write:\fB cout << setw(8) << val1 << " " << setw(4) << val2 << endl; .fi .ft R .in -.5i .LP There are several predefined manipulators described in .BR ios (3CC4), .BR istream "(3CC4), and " .BR ostream (3CC4). These are simple, taking no arguments, such as \fBendl\fR as used above, or \fBflush\fR. Manipulators may also take arguments, such as \fBsetw\fR as used above, or \fBsetfill\fR. The header file \fB\fR defines some of these manipulators, and also provides the definitions necessary for you to create your own. .LP Manipulators are logically defined as templates, but were introduced before templates were available in the C++ language. They are accordingly defined as macros simulating templates. The macro \fBIOMANIPdeclare(typ)\fR expands to a complete set of definitions for a manipulator taking one parameter of type \fBtyp\fR. Due to the nature of the macros, the type parameter must be a simple type name (just an identifier). The header provides the expanded definitions for types \fBint\fR and \fBlong\fR. .SS "Simple manipulators" A manipulator without arguments is a function with one parameter of type \fIreference to stream\fR, and which returns the same type. The streams have predefined overloaded operators which take such a function as a parameter. The manipulator performs whatever operations are necessary on the stream argument, then returns the same stream. For example, here is code for a \fBtab\fR manipulator: .in +.5i .ft B .nf ostream& tab(ostream& s) { s << '\\t'; return s; } .fi .ft R .in -.5i In the expression \fBcout<> SMANIP(typ)(f, t)" .br .B "s >> SAPP(typ)(f)(t)" .br .in +.5i Returns \fBf(s,t)\fR. The stream \fBs\fR could also be any of the other stream types \fBi\fR, \fBo\fR, or \fBio\fR. .sp .5v .in -.5i .B "i >> IMANIP(typ)(if, t)" .br .B "i >> IAPP(typ)(if)(t)" .br .in +.5i Returns \fBif(i,t)\fR. .sp .5v .in -.5i .B "o << OMANIP(typ)(of, t)" .br .B "o << OAPP(typ)(of)(t)" .br .in +.5i Returns \fBof(o,t)\fR. .sp .5v .in -.5i .B "io << IOMANIP(typ)(iof, t)" .br .B "io << IOAPP(typ)(iof)(t)" .br .B "io >> IOMANIP(typ)(iof, t)" .br .B "io >> IOAPP(typ)(iof)(t)" .br .in +.5i Returns \fBiof(io,t)\fR. .in -.5i .LP The \fB\fR header contains declarations for manipulators taking an \fBint\fR or a \fBlong\fR argument (\fBtyp\fR in the above presentation). The predefined manipulators are all used for changing the state of a stream, as follows: .sp .5v .in +.5i .ti -.5i .B "o << setw(n)" .ti -.5i .B "i >> setw(n)" .br Sets the field width of stream \fBi\fR or \fBo\fR to \fBn\fR. Note: the next formatted insertion or extraction resets the width to 0. .sp .5v .ti -.5i .B "o << setfill(n)" .ti -.5i .B "i >> setfill(n)" .br Sets the fill character of stream \fBi\fR or \fBo\fR to \fBn\fR. .sp .5v .ti -.5i .B "o << setprecision(n)" .ti -.5i .B "i >> setprecision(n)" .br Sets the precision variable of stream \fBi\fR or \fBo\fR to \fBn\fR. .sp .5v .ti -.5i .B "o << setiosflags(l)" .ti -.5i .B "i >> setiosflags(l)" .br Turns on the \fBios\fR flags of stream \fBi\fR or \fBo\fR which are set in \fBl\fR. .sp .5v .ti -.5i .B "o << resetiosflags(l)" .ti -.5i .B "i >> resetiosflags(l)" .br Turns off the \fBios\fR flags of stream \fBi\fR or \fBo\fR which are set in \fBl\fR. .in -.5i .LP To write your own parameterized manipulator you need to declare the \fImanip\fR function, then implement both the \fImanip\fR and \fIapply\fR functions. If the manipulator is to take an argument of type \fBtyp\fR, declare the \fImanip\fR function to take one argument of that type, and to return an object of type \fIX\fBmanip_\fItyp\fR. Replace \fIX\fR with one of .BR s ", " i ", " .BR o ", or " io , if it is intended to manipulate objects of type .BR ios ", " istream ", " .BR ostream ", or " iostream , respectively. Replace \fItyp\fR with the actual type name. For types \fBint\fR and \fBlong\fR, all the declarations are already in place. For other types, you need to invoke the ``template'' \fBIOMANIPdeclare(\fItyp\fB)\fR. .LP The \fIapply\fR function is usually static, since it is only called by the \fImanip\fR function. Define it to return a reference to the type of stream to be manipulated, to have a first parameter of that same type, and a second of type \fBtyp\fR. .LP For example, consider the \fBsetiosflags\fR manipulator. The manipulator operates on an \fBios\fR, and takes a \fBlong\fR parameter, so it is declared to return type \fBsmanip_long\fR. If it operated on an \fBostream\fR and took an \fBint\fR parameter, it would be declared to return type \fBomanip_int\fR. The manipulator (the \fImanip\fR function) is therefore declared in the header like this: .ti +.5i .B "smanip_long setiosflags(long);" .br The \fIapply\fR function does not appear in the header, since it is never called directly by user code. The code for both functions appears in the implementation module: .in +.5i .nf .ft B // set the flags bitvector according to the bits set in b static ios& sios(ios& i, long b) \fR// private \fIapply\fR function\fB { i.setf(b); return i; } smanip_long setiosflags(long b) \fR// public \fImanip\fR function\fB { return smanip_long(sios, b); } .ft R .fi .in -.5i .\" .SH "SEE ALSO" .LP .na .BR ios.intro (3CC4), .BR ios (3CC4), .BR istream (3CC4), .BR ostream (3CC4) .TP .I C++ Library Reference .TP Chapter 3, "The Classic \fIiostream\fR Library." .TP .\" .TZ ????