Retro video games delivered to your door every month!
Click above to get retro games delivered to your door ever month!
X-Hacker.org- Zortech C++ 3.0r4 - <b>manipulators with parameters</b> http://www.X-Hacker.org [<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
Manipulators with Parameters

   Manipulators with parameters allow simple expressions like:

       cout << setw(12) << setfill('#');

   To modify the state of a stream in some way needs not only an indication
   of what state variable to change, but also an argument to change it to.
   These arguments are provided by a set of template types like the
   following, SMANIP, parameterized on type T, and defined by suitable
   macros in manip.hpp.

       class SMANIP(T) {

       public:
           SMANIP(T)(ios &(*)(ios &, T), T);
           friend istream &operator>>(istream &, SMANIP(T) &);
           friend ostream &operator<<(ostream &, SMANIP(T) &);

       private:
           ios &(*func)(ios &, T);
           T value;
       };

   The constructor for a manipulator class like this stores a pointer to a
   function that takes a stream reference and the required type as
   arguments. It returns a reference to the argument stream, and also stores
   a value of the required type.

   The friend extractor or inserter function can then call the function
   pointed at by the stored pointer, with the stream as its first argument
   and the stored value as its second:

       istream &operator>>(istream &s, SMANIP(T) &m)
       {
           (*m.func)(s, m.value);
           return s;

       }

   An alternative, called an applicator, is provided of the form:

       class SAPP(T) {
           SAPP(T)(ios &(*)(ios &, T));
           SMANIP(T) operator()(T);
       private:
           ios &(*func)(ios &, T);
       };

   This stores only the function pointer, and uses an overload of the
   function call operator to provide the parameter value of type T. This
   pseudo function call returns an SMANIP(T) object, so can be used with the
   same extraction and insertion operator functions.

   The header file manip.hpp declares template classes like these for class
   ios, and for classes istream, ostream, and iostream:

   SMANIP(T)

   SAPP(T)
   IMANIP(T)
   IAPP(T)
   OMANIP(T)
   OAPP(T)
   IOMANIP(T)
   IOAPP(T)

   Classes for types int and long are instantiated from these templates in
   the same header file, along with appropriate extractor and inserter
   functions (the friends of the manipulator classes). The header file then
   defines the following functions that return manipulator objects:

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

   These are implemented like this:


       static ios &_setw(ios &s, int w)
       {
           s.width(w);
           return s;
       }

       SMANIP(int) setw(int w)
       {
           return SMANIP(int)(_setw, w);
       }

   These functions can then be embedded in the normal usage of extractors or
   inserters:

       cout << resetiosflags(ios::floatfield) << setw(12);

   Applicators can be used as follows:

       static ostream &_inschr(ostream &s, int c)

       {
           s << char(c);
           return s;
       }

       OAPP(int) character(_inschr);

   Given the definition of this applicator, character, it can then be used
   in a similar way:

       cout << character('a'); // output is 'a'

   This is a trivial example, but applicators of this sort can be used as
   shorthand for complex output operations that might otherwise be verbose
   to express.



Online resources provided by: http://www.X-Hacker.org --- NG 2 HTML conversion by Dave Pearson