From e2dfd39c756e16ebabc75314728864ca35e2933f Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 19 Nov 2016 09:29:09 -0800 Subject: [PATCH] Update arg visitors --- fmt/printf.h | 56 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/fmt/printf.h b/fmt/printf.h index 83f5fa37..c8ae99b2 100644 --- a/fmt/printf.h +++ b/fmt/printf.h @@ -40,25 +40,34 @@ struct IntChecker { static bool fits_in_int(int) { return true; } }; -class PrecisionHandler : public ArgVisitor { +class PrecisionHandler { public: - void report_unhandled_arg() { - FMT_THROW(format_error("precision is not integer")); - } - template - int visit_any_int(T value) { + typename std::enable_if::value, int>::type + operator()(T value) { if (!IntChecker::is_signed>::fits_in_int(value)) FMT_THROW(format_error("number is too big")); return static_cast(value); } + + template + typename std::enable_if::value, int>::type + operator()(T) { + FMT_THROW(format_error("precision is not integer")); + return 0; + } }; -// IsZeroInt::visit(arg) returns true iff arg is a zero integer. -class IsZeroInt : public ArgVisitor { +// An argument visitor that returns true iff arg is a zero integer. +class IsZeroInt { public: template - bool visit_any_int(T value) { return value == 0; } + typename std::enable_if::value, bool>::type + operator()(T value) { return value == 0; } + + template + typename std::enable_if::value, bool>::type + operator()(T value) { return false; } }; template @@ -120,7 +129,7 @@ class ArgConverter { template typename std::enable_if::value>::type - operator()(U value) { + operator()(U value) { // No coversion needed for non-integral types. } }; @@ -135,7 +144,7 @@ void convert_arg(format_arg &arg, wchar_t type) { } // Converts an integer argument to char for printf. -class CharConverter : public ArgVisitor { +class CharConverter { private: internal::Arg &arg_; @@ -145,15 +154,22 @@ class CharConverter : public ArgVisitor { explicit CharConverter(internal::Arg &arg) : arg_(arg) {} template - void visit_any_int(T value) { + typename std::enable_if::value>::type + operator()(T value) { arg_.type = internal::Arg::CHAR; arg_.int_value = static_cast(value); } + + template + typename std::enable_if::value>::type + operator()(T value) { + // No coversion needed for non-integral types. + } }; // Checks if an argument is a valid printf width specifier and sets // left alignment if it is negative. -class WidthHandler : public ArgVisitor { +class WidthHandler { private: FormatSpec &spec_; @@ -162,12 +178,9 @@ class WidthHandler : public ArgVisitor { public: explicit WidthHandler(FormatSpec &spec) : spec_(spec) {} - void report_unhandled_arg() { - FMT_THROW(format_error("width is not integer")); - } - template - unsigned visit_any_int(T value) { + typename std::enable_if::value, unsigned>::type + operator()(T value) { typedef typename internal::IntTraits::MainType UnsignedType; UnsignedType width = static_cast(value); if (internal::is_negative(value)) { @@ -179,6 +192,13 @@ class WidthHandler : public ArgVisitor { FMT_THROW(format_error("number is too big")); return static_cast(width); } + + template + typename std::enable_if::value, unsigned>::type + operator()(T value) { + FMT_THROW(format_error("width is not integer")); + return 0; + } }; } // namespace internal