diff --git a/fmt/printf.h b/fmt/printf.h index c8d7b3dc..83f5fa37 100644 --- a/fmt/printf.h +++ b/fmt/printf.h @@ -71,29 +71,24 @@ struct is_same { enum { value = 1 }; }; -// An argument visitor that converts an integer argument to T for printf, -// if T is an integral type. If T is void, the argument is converted to -// corresponding signed or unsigned type depending on the type specifier: -// 'd' and 'i' - signed, other - unsigned) -template -class ArgConverter : public ArgVisitor, void> { +template +class ArgConverter { private: internal::Arg &arg_; wchar_t type_; - FMT_DISALLOW_COPY_AND_ASSIGN(ArgConverter); - public: ArgConverter(internal::Arg &arg, wchar_t type) : arg_(arg), type_(type) {} - void visit_bool(bool value) { + void operator()(bool value) { if (type_ != 's') - visit_any_int(value); + operator()(value); } template - void visit_any_int(U value) { + typename std::enable_if::value>::type + operator()(U value) { bool is_signed = type_ == 'd' || type_ == 'i'; using internal::Arg; typedef typename internal::Conditional< @@ -122,8 +117,23 @@ class ArgConverter : public ArgVisitor, void> { } } } + + template + typename std::enable_if::value>::type + operator()(U value) { + // No coversion needed for non-integral types. + } }; +// Converts an integer argument to T for printf, if T is an integral type. +// If T is void, the argument is converted to corresponding signed or unsigned +// type depending on the type specifier: 'd' and 'i' - signed, other - +// unsigned). +template +void convert_arg(format_arg &arg, wchar_t type) { + visit(ArgConverter(arg, type), arg); +} + // Converts an integer argument to char for printf. class CharConverter : public ArgVisitor { private: @@ -436,28 +446,28 @@ void printf_context::format(BasicWriter &writer) { } // Parse length and convert the argument to the required type. - using internal::ArgConverter; + using internal::convert_arg; switch (*s++) { case 'h': if (*s == 'h') - visit(ArgConverter(arg, *++s), arg); + convert_arg(arg, *++s); else - visit(ArgConverter(arg, *s), arg); + convert_arg(arg, *s); break; case 'l': if (*s == 'l') - visit(ArgConverter(arg, *++s), arg); + convert_arg(arg, *++s); else - visit(ArgConverter(arg, *s), arg); + convert_arg(arg, *s); break; case 'j': - visit(ArgConverter(arg, *s), arg); + convert_arg(arg, *s); break; case 'z': - visit(ArgConverter(arg, *s), arg); + convert_arg(arg, *s); break; case 't': - visit(ArgConverter(arg, *s), arg); + convert_arg(arg, *s); break; case 'L': // printf produces garbage when 'L' is omitted for long double, no @@ -465,7 +475,7 @@ void printf_context::format(BasicWriter &writer) { break; default: --s; - visit(ArgConverter(arg, *s), arg); + convert_arg(arg, *s); } // Parse type.