diff --git a/format.cc b/format.cc index e71207ba..ff39d1fa 100644 --- a/format.cc +++ b/format.cc @@ -169,15 +169,19 @@ const Char *find_closing_brace(const Char *s, int num_open_braces = 1) { throw fmt::FormatError("unmatched '{' in format"); } -// Handles width specifier. +// Checks if an argument is a valid printf width specifier and sets +// left alignment if it is negative. struct WidthHandler : public fmt::internal::ArgVisitor { private: fmt::FormatSpec &spec_; + public: explicit WidthHandler(fmt::FormatSpec &spec) : spec_(spec) {} + ULongLong visit_unhandled_arg() { throw fmt::FormatError("width is not integer"); } + ULongLong visit_any_int(fmt::LongLong value) { ULongLong width = value; if (value < 0) { @@ -186,6 +190,7 @@ struct WidthHandler : public fmt::internal::ArgVisitor } return width; } + ULongLong visit_any_uint(ULongLong value) { return value; } }; } // namespace @@ -565,7 +570,9 @@ void fmt::BasicWriter::FormatDouble(T value, const FormatSpec &spec) { template template void fmt::BasicWriter::write_str( - const internal::StringValue &str, const FormatSpec &spec) { + const internal::Arg::StringValue &str, const FormatSpec &spec) { + // Check if StringChar is convertible to Char. + internal::CharTraits::convert(StringChar()); if (spec.type_ && spec.type_ != 's') internal::ReportUnknownType(spec.type_, "string"); const StringChar *s = str.value; @@ -840,7 +847,7 @@ void fmt::internal::PrintfParser::Format( writer.write_str(arg.string, spec); break; case Arg::WSTRING: - writer.write_str(internal::CharTraits::convert(arg.wstring), spec); + writer.write_str(arg.wstring, spec); break; case Arg::POINTER: if (spec.type_ && spec.type_ != 'p') @@ -1048,7 +1055,7 @@ const Char *fmt::BasicFormatter::format( writer_.write_str(arg.string, spec); break; case Arg::WSTRING: - writer_.write_str(internal::CharTraits::convert(arg.wstring), spec); + writer_.write_str(arg.wstring, spec); break; case Arg::POINTER: if (spec.type_ && spec.type_ != 'p') diff --git a/format.h b/format.h index 1c5220ed..2b1ce9e1 100644 --- a/format.h +++ b/format.h @@ -340,12 +340,6 @@ void Array::append(const T *begin, const T *end) { size_ += num_elements; } -template -struct StringValue { - const Char *value; - std::size_t size; -}; - template class BasicCharTraits { public: @@ -373,11 +367,6 @@ public: static char convert(char value) { return value; } - static StringValue convert(StringValue) { - StringValue s = {"", 0}; - return s; - } - template static int FormatFloat(char *buffer, std::size_t size, const char *format, unsigned width, int precision, T value); @@ -391,8 +380,6 @@ class CharTraits : public BasicCharTraits { static wchar_t convert(char value) { return value; } static wchar_t convert(wchar_t value) { return value; } - static StringValue convert(StringValue s) { return s; } - static const wchar_t *check(const wchar_t *s) { return s; } template @@ -600,6 +587,12 @@ struct Arg { }; Type type; + template + struct StringValue { + const Char *value; + std::size_t size; + }; + typedef void (*FormatFunc)( void *formatter, const void *arg, const void *format_str); @@ -773,10 +766,10 @@ class ArgVisitor { Result visit_char(int) { return FMT_DISPATCH(visit_unhandled_arg()); } - Result visit_string(StringValue) { + Result visit_string(Arg::StringValue) { return FMT_DISPATCH(visit_unhandled_arg()); } - Result visit_wstring(StringValue) { + Result visit_wstring(Arg::StringValue) { return FMT_DISPATCH(visit_unhandled_arg()); } Result visit_pointer(const void *) { @@ -1347,7 +1340,7 @@ class BasicWriter { template void write_str( - const internal::StringValue &str, const FormatSpec &spec); + const internal::Arg::StringValue &str, const FormatSpec &spec); // This method is private to disallow writing a wide string to a // char stream and vice versa. If you want to print a wide string diff --git a/test/util-test.cc b/test/util-test.cc index f93258db..0b7facc0 100644 --- a/test/util-test.cc +++ b/test/util-test.cc @@ -254,10 +254,10 @@ struct TestVisitor : fmt::internal::ArgVisitor { Result visit_double(double value) { return value; } Result visit_long_double(long double value) { return value; } Result visit_char(int value) { return static_cast(value); } - Result visit_string(fmt::internal::StringValue s) { return s.value; } - Result visit_wstring(fmt::internal::StringValue s) { return s.value; } + Result visit_string(Arg::StringValue s) { return s.value; } + Result visit_wstring(Arg::StringValue s) { return s.value; } Result visit_pointer(const void *p) { return p; } - Result visit_custom(fmt::internal::Arg::CustomValue c) { + Result visit_custom(Arg::CustomValue c) { return *static_cast(c.value); } };