/**************************************************************************** ** COPYRIGHT (C): 1997 Cay S. Horstmann. All Rights Reserved. ** PROJECT: Practical OO Development with C++ and Java ** FILE: setfmt.cpp ** PURPOSE: setformat manipulator ** VERSION 1.0 ** PROGRAMMERS: Cay Horstmann (CSH) ** RELEASE DATE: 3-15-97 (CSH) ** UPDATE HISTORY: ****************************************************************************/ #include "setup.h" #include #include EXPORT ostream& do_setformat(ostream& os, const char* fmt) { int i = 0; while (fmt[i] != 0) { if (fmt[i] != '%') { os << fmt[i]; i++; } else { i++; if (fmt[i] == '%') { os << fmt[i]; i++; } else { bool ok = true; int istart = i; bool more = true; int width = 0; int precision = 6; long flags = 0; char fill = ' '; bool alternate = false; while (more) { switch (fmt[i]) { case '+': flags |= ios::showpos; break; case '-': flags |= ios::left; break; case '0': flags |= ios::internal; fill = '0'; break; case '#': alternate = true; break; case ' ': break; default: more = false; break; } if (more) i++; } if (isdigit(fmt[i])) { width = atoi(fmt+i); do i++; while (isdigit(fmt[i])); } if (fmt[i] == '.') { i++; precision = atoi(fmt+i); while (isdigit(fmt[i])) i++; } switch (fmt[i]) { case 'd': flags |= ios::dec; break; case 'x': flags |= ios::hex; if (alternate) flags |= ios::showbase; break; case 'X': flags |= ios::hex | ios::uppercase; if (alternate) flags |= ios::showbase; break; case 'o': flags |= ios::hex; if (alternate) flags |= ios::showbase; break; case 'f': flags |= ios::fixed; if (alternate) flags |= ios::showpoint; break; case 'e': flags |= ios::scientific; if (alternate) flags |= ios::showpoint; break; case 'E': flags |= ios::scientific | ios::uppercase; if (alternate) flags |= ios::showpoint; break; case 'g': if (alternate) flags |= ios::showpoint; break; case 'G': flags |= ios::uppercase; if (alternate) flags |= ios::showpoint; break; default: ok = false; break; } i++; if (fmt[i] != 0) ok = false; if (ok) { os.unsetf(ios::adjustfield | ios::basefield | ios::floatfield); os.setf(flags); os.width(width); os.precision(precision); os.fill(fill); } else i = istart; } } } return os; } EXPORT template class Manipulator { public: typedef S& (*Action)(S&, T); Manipulator(Action a, T v) { _action = a; _value = v; } friend S& operator<<(S&, const Manipulator&); private: Action _action; T _value; }; EXPORT template inline S& operator<<(S& s, const Manipulator& m) { (*m._action)(s, m._value); return s; } EXPORT inline Manipulator setformat(const char* s) { return Manipulator(do_setformat, s); }