Update arg visitors
This commit is contained in:
parent
751ff64bdb
commit
e2dfd39c75
56
fmt/printf.h
56
fmt/printf.h
@ -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>
|
||||||
@ -120,7 +129,7 @@ class ArgConverter {
|
|||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
typename std::enable_if<!std::is_integral<U>::value>::type
|
typename std::enable_if<!std::is_integral<U>::value>::type
|
||||||
operator()(U value) {
|
operator()(U value) {
|
||||||
// No coversion needed for non-integral types.
|
// 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.
|
// 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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user