Update arg visitors

This commit is contained in:
Victor Zverovich 2016-11-19 09:29:09 -08:00
parent 751ff64bdb
commit e2dfd39c75

View File

@ -40,25 +40,34 @@ struct IntChecker<true> {
static bool fits_in_int(int) { return true; } static bool fits_in_int(int) { return true; }
}; };
class PrecisionHandler : public ArgVisitor<PrecisionHandler, int> { class PrecisionHandler {
public: public:
void report_unhandled_arg() {
FMT_THROW(format_error("precision is not integer"));
}
template <typename T> template <typename T>
int visit_any_int(T value) { typename std::enable_if<std::is_integral<T>::value, int>::type
operator()(T value) {
if (!IntChecker<std::numeric_limits<T>::is_signed>::fits_in_int(value)) if (!IntChecker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
FMT_THROW(format_error("number is too big")); FMT_THROW(format_error("number is too big"));
return static_cast<int>(value); return static_cast<int>(value);
} }
template <typename T>
typename std::enable_if<!std::is_integral<T>::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. // An argument visitor that returns true iff arg is a zero integer.
class IsZeroInt : public ArgVisitor<IsZeroInt, bool> { class IsZeroInt {
public: public:
template <typename T> template <typename T>
bool visit_any_int(T value) { return value == 0; } typename std::enable_if<std::is_integral<T>::value, bool>::type
operator()(T value) { return value == 0; }
template <typename T>
typename std::enable_if<!std::is_integral<T>::value, bool>::type
operator()(T value) { return false; }
}; };
template <typename T, typename U> template <typename T, typename U>
@ -135,7 +144,7 @@ void convert_arg(format_arg &arg, wchar_t type) {
} }
// Converts an integer argument to char for printf. // Converts an integer argument to char for printf.
class CharConverter : public ArgVisitor<CharConverter, void> { class CharConverter {
private: private:
internal::Arg &arg_; internal::Arg &arg_;
@ -145,15 +154,22 @@ class CharConverter : public ArgVisitor<CharConverter, void> {
explicit CharConverter(internal::Arg &arg) : arg_(arg) {} explicit CharConverter(internal::Arg &arg) : arg_(arg) {}
template <typename T> template <typename T>
void visit_any_int(T value) { typename std::enable_if<std::is_integral<T>::value>::type
operator()(T value) {
arg_.type = internal::Arg::CHAR; arg_.type = internal::Arg::CHAR;
arg_.int_value = static_cast<char>(value); arg_.int_value = static_cast<char>(value);
} }
template <typename T>
typename std::enable_if<!std::is_integral<T>::value>::type
operator()(T value) {
// No coversion needed for non-integral types.
}
}; };
// Checks if an argument is a valid printf width specifier and sets // Checks if an argument is a valid printf width specifier and sets
// left alignment if it is negative. // left alignment if it is negative.
class WidthHandler : public ArgVisitor<WidthHandler, unsigned> { class WidthHandler {
private: private:
FormatSpec &spec_; FormatSpec &spec_;
@ -162,12 +178,9 @@ class WidthHandler : public ArgVisitor<WidthHandler, unsigned> {
public: public:
explicit WidthHandler(FormatSpec &spec) : spec_(spec) {} explicit WidthHandler(FormatSpec &spec) : spec_(spec) {}
void report_unhandled_arg() {
FMT_THROW(format_error("width is not integer"));
}
template <typename T> template <typename T>
unsigned visit_any_int(T value) { typename std::enable_if<std::is_integral<T>::value, unsigned>::type
operator()(T value) {
typedef typename internal::IntTraits<T>::MainType UnsignedType; typedef typename internal::IntTraits<T>::MainType UnsignedType;
UnsignedType width = static_cast<UnsignedType>(value); UnsignedType width = static_cast<UnsignedType>(value);
if (internal::is_negative(value)) { if (internal::is_negative(value)) {
@ -179,6 +192,13 @@ class WidthHandler : public ArgVisitor<WidthHandler, unsigned> {
FMT_THROW(format_error("number is too big")); FMT_THROW(format_error("number is too big"));
return static_cast<unsigned>(width); return static_cast<unsigned>(width);
} }
template <typename T>
typename std::enable_if<!std::is_integral<T>::value, unsigned>::type
operator()(T value) {
FMT_THROW(format_error("width is not integer"));
return 0;
}
}; };
} // namespace internal } // namespace internal