Commit 751ff64b authored by Victor Zverovich's avatar Victor Zverovich

Update ArgConverter to the new visitor API

parent c9dc41ab
...@@ -71,29 +71,24 @@ struct is_same<T, T> { ...@@ -71,29 +71,24 @@ struct is_same<T, T> {
enum { value = 1 }; enum { value = 1 };
}; };
// An argument visitor that converts an integer argument to T for printf, template <typename T>
// if T is an integral type. If T is void, the argument is converted to class ArgConverter {
// corresponding signed or unsigned type depending on the type specifier:
// 'd' and 'i' - signed, other - unsigned)
template <typename T = void>
class ArgConverter : public ArgVisitor<ArgConverter<T>, void> {
private: private:
internal::Arg &arg_; internal::Arg &arg_;
wchar_t type_; wchar_t type_;
FMT_DISALLOW_COPY_AND_ASSIGN(ArgConverter);
public: public:
ArgConverter(internal::Arg &arg, wchar_t type) ArgConverter(internal::Arg &arg, wchar_t type)
: arg_(arg), type_(type) {} : arg_(arg), type_(type) {}
void visit_bool(bool value) { void operator()(bool value) {
if (type_ != 's') if (type_ != 's')
visit_any_int(value); operator()<bool>(value);
} }
template <typename U> template <typename U>
void visit_any_int(U value) { typename std::enable_if<std::is_integral<U>::value>::type
operator()(U value) {
bool is_signed = type_ == 'd' || type_ == 'i'; bool is_signed = type_ == 'd' || type_ == 'i';
using internal::Arg; using internal::Arg;
typedef typename internal::Conditional< typedef typename internal::Conditional<
...@@ -122,8 +117,23 @@ class ArgConverter : public ArgVisitor<ArgConverter<T>, void> { ...@@ -122,8 +117,23 @@ class ArgConverter : public ArgVisitor<ArgConverter<T>, void> {
} }
} }
} }
template <typename U>
typename std::enable_if<!std::is_integral<U>::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 <typename T>
void convert_arg(format_arg &arg, wchar_t type) {
visit(ArgConverter<T>(arg, type), arg);
}
// Converts an integer argument to char for printf. // Converts an integer argument to char for printf.
class CharConverter : public ArgVisitor<CharConverter, void> { class CharConverter : public ArgVisitor<CharConverter, void> {
private: private:
...@@ -436,28 +446,28 @@ void printf_context<Char, AF>::format(BasicWriter<Char> &writer) { ...@@ -436,28 +446,28 @@ void printf_context<Char, AF>::format(BasicWriter<Char> &writer) {
} }
// Parse length and convert the argument to the required type. // Parse length and convert the argument to the required type.
using internal::ArgConverter; using internal::convert_arg;
switch (*s++) { switch (*s++) {
case 'h': case 'h':
if (*s == 'h') if (*s == 'h')
visit(ArgConverter<signed char>(arg, *++s), arg); convert_arg<signed char>(arg, *++s);
else else
visit(ArgConverter<short>(arg, *s), arg); convert_arg<short>(arg, *s);
break; break;
case 'l': case 'l':
if (*s == 'l') if (*s == 'l')
visit(ArgConverter<fmt::LongLong>(arg, *++s), arg); convert_arg<fmt::LongLong>(arg, *++s);
else else
visit(ArgConverter<long>(arg, *s), arg); convert_arg<long>(arg, *s);
break; break;
case 'j': case 'j':
visit(ArgConverter<intmax_t>(arg, *s), arg); convert_arg<intmax_t>(arg, *s);
break; break;
case 'z': case 'z':
visit(ArgConverter<std::size_t>(arg, *s), arg); convert_arg<std::size_t>(arg, *s);
break; break;
case 't': case 't':
visit(ArgConverter<std::ptrdiff_t>(arg, *s), arg); convert_arg<std::ptrdiff_t>(arg, *s);
break; break;
case 'L': case 'L':
// printf produces garbage when 'L' is omitted for long double, no // printf produces garbage when 'L' is omitted for long double, no
...@@ -465,7 +475,7 @@ void printf_context<Char, AF>::format(BasicWriter<Char> &writer) { ...@@ -465,7 +475,7 @@ void printf_context<Char, AF>::format(BasicWriter<Char> &writer) {
break; break;
default: default:
--s; --s;
visit(ArgConverter<void>(arg, *s), arg); convert_arg<void>(arg, *s);
} }
// Parse type. // Parse type.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment