14 #ifndef DOXYGEN_IGNORE_INTERNAL
24 ALT = 1, ZP=2, LEFT=4, SPACE=8, SIGN=16, PERCENT=32, BAD=64,
25 NO_PRECISION=-1, NO_WIDTH=-1
32 inline int parse(
const std::string& fmt,
int pos)
36 precision=NO_PRECISION;
81 width = width * 10 + (c-
'0');
87 if(pos < s && fmt[pos] ==
'.')
97 precision = precision * 10 + (c-
'0');
104 if(pos < s && isalpha(fmt[pos]))
105 conversion = fmt[pos++];
114 template<
class Char,
class Traits>
struct bound_format
116 bound_format(std::basic_ostream<Char, Traits>& os,
const format& ff)
120 std::basic_ostream<Char, Traits>& o;
125 template<
class Char,
class Traits> bound_format<Char, Traits> operator<<(std::basic_ostream<Char, Traits>& o,
const format& f)
127 return bound_format<Char, Traits>(o, f);
131 template<
class Char,
class Traits,
class C> std::basic_ostream<Char, Traits>& operator<<(bound_format<Char,Traits> f,
const C& c)
136 bool precision_is_max_width=0;
140 int old_p = f.o.precision();
141 Char old_fill = f.o.fill();
142 ios::fmtflags old_flags = f.o.flags();
146 f.o.unsetf(ios::floatfield | ios::boolalpha);
152 switch(f.f.conversion)
156 f.o.setf(ios::fixed);
161 f.o.setf(ios::scientific);
166 f.o.unsetf(ios::floatfield);
186 precision_is_max_width=1;
197 if(f.f.width != format::NO_WIDTH)
198 f.o.width(f.f.width);
200 if(f.f.flags & format::ZP && !(f.f.flags & format::LEFT))
203 if(f.f.flags & format::SIGN)
204 f.o.setf(ios::showpos);
206 f.o.unsetf(ios::showpos);
208 if(f.f.flags & format::LEFT)
211 f.o.setf(ios::internal);
213 if(f.f.flags * format::ALT)
214 f.o.setf(ios::showbase | ios::showpoint);
216 f.o.unsetf(ios::showbase | ios::showpoint);
219 if(isupper(f.f.conversion))
220 f.o.setf(ios::uppercase);
222 f.o.unsetf(ios::uppercase);
225 if(f.f.precision != format::NO_PRECISION && ! precision_is_max_width)
226 f.o.precision(f.f.precision);
228 if(precision_is_max_width && f.f.precision != format::NO_PRECISION)
237 f.o << tmp.str().substr(0, f.f.precision);
244 f.o.precision(old_p);
255 template<
class C,
class D,
int i,
int max>
struct print_typelist
257 static void print(std::ostream& o,
const std::string& fmt,
int fpos,
const T_list<C,D>& l)
263 ppos = fmt.find(
'%', fpos);
273 o << fmt.substr(fpos, ppos - fpos);
277 int pos = f.parse(fmt, ppos+1);
279 if(f.flags & format::PERCENT)
285 else if(f.flags & format::BAD)
287 o <<
"<Malformed format>" << &fmt[ppos];
292 o << f << l.template index<i>();
301 template<
class C,
class D,
int max>
struct print_typelist<C, D, max, max>
303 static void print(std::ostream& o,
const std::string& fmt,
int fpos,
const T_list<C,D>&)
309 ppos = fmt.find(
'%', fpos);
319 o << fmt.substr(fpos, ppos - fpos);
323 int pos = f.parse(fmt, ppos+1);
325 if(f.flags & format::PERCENT)
331 else if(f.flags & format::BAD)
333 o <<
"<Malformed format>" << &fmt[ppos];
338 o <<
"<Missing value>";
441 template<
class A,
class B,
class C,
class D>
void vfPrintf(std::basic_ostream<A, B>& o,
const std::string fmt,
const T_list<C,D>& l)
443 Internal::print_typelist<C, D, 0, T_list<C,D>::elements >
::print(o, fmt, 0, l);
462 std::ostringstream o;
485 #define Printf(A, ...) vPrintf(A, (tag::Fmt,## __VA_ARGS__))
493 #define fPrintf(A,B, ...) vfPrintf(A,B, (tag::Fmt,## __VA_ARGS__))
501 #define sPrintf(A, ...) vsPrintf(A, (tag::Fmt,## __VA_ARGS__))