diff --git a/fmt/format.cc b/fmt/format.cc index b770fc02..55ece67c 100644 --- a/fmt/format.cc +++ b/fmt/format.cc @@ -463,7 +463,7 @@ template void internal::FixedBuffer::grow(std::size_t); template void internal::ArgMap::init(const format_args &args); -template void PrintfFormatter::format(CStringRef format); +template void PrintfFormatter::format(Writer &writer, CStringRef format); template int internal::CharTraits::format_float( char *buffer, std::size_t size, const char *format, @@ -479,7 +479,8 @@ template void internal::FixedBuffer::grow(std::size_t); template void internal::ArgMap::init(const format_args &args); -template void PrintfFormatter::format(WCStringRef format); +template void PrintfFormatter::format(WWriter &writer, + WCStringRef format); template int internal::CharTraits::format_float( wchar_t *buffer, std::size_t size, const wchar_t *format, diff --git a/fmt/format.h b/fmt/format.h index 8cddbd7f..9d9359bc 100644 --- a/fmt/format.h +++ b/fmt/format.h @@ -2132,13 +2132,13 @@ private: next_arg_index_ = -1; return true; } - - template - void write(BasicWriter &w, const Char *start, const Char *end) { - if (start != end) - w << BasicStringRef(start, internal::to_unsigned(end - start)); - } }; + +template +inline void write(BasicWriter &w, const Char *start, const Char *end) { + if (start != end) + w << BasicStringRef(start, internal::to_unsigned(end - start)); +} } // namespace internal /** @@ -2173,14 +2173,15 @@ class BasicArgFormatter : public internal::ArgFormatterBase { to the part of the format string being parsed for custom argument types. \endrst */ - BasicArgFormatter(basic_formatter &formatter, + BasicArgFormatter(BasicWriter &writer, + basic_formatter &formatter, FormatSpec &spec, const Char *fmt) - : internal::ArgFormatterBase(formatter.writer(), spec), + : internal::ArgFormatterBase(writer, spec), formatter_(formatter), format_(fmt) {} /** Formats an argument of a custom (user-defined) type. */ void visit_custom(internal::Arg::CustomValue c) { - c.format(&formatter_.writer(), c.value, &formatter_, &format_); + c.format(&this->writer(), c.value, &formatter_, &format_); } }; @@ -2189,9 +2190,9 @@ template class ArgFormatter : public BasicArgFormatter, Char> { public: /** Constructs an argument formatter object. */ - ArgFormatter(basic_formatter &formatter, + ArgFormatter(BasicWriter &writer, basic_formatter &formatter, FormatSpec &spec, const Char *fmt) - : BasicArgFormatter, Char>(formatter, spec, fmt) {} + : BasicArgFormatter, Char>(writer, formatter, spec, fmt) {} }; /** This template formats data and writes the output to a writer. */ @@ -2203,7 +2204,6 @@ class basic_formatter : typedef Char char_type; private: - BasicWriter &writer_; internal::ArgMap map_; FMT_DISALLOW_COPY_AND_ASSIGN(basic_formatter); @@ -2215,41 +2215,26 @@ class basic_formatter : // specified name. internal::Arg get_arg(BasicStringRef arg_name, const char *&error); - // Parses argument index and returns corresponding argument. - internal::Arg parse_arg_index(const Char *&s); - - // Parses argument name and returns corresponding argument. - internal::Arg parse_arg_name(const Char *&s); - public: /** \rst - Constructs a ``basic_formatter`` object. References to the arguments and - the writer are stored in the formatter object so make sure they have - appropriate lifetimes. + Constructs a ``basic_formatter`` object. References to the arguments are + stored in the formatter object so make sure they have appropriate lifetimes. \endrst */ - basic_formatter(basic_format_args args, BasicWriter &w) - : Base(args), writer_(w) {} + basic_formatter(basic_format_args args) : Base(args) {} - /** Returns a reference to the writer associated with this formatter. */ - BasicWriter &writer() { return writer_; } - - /** Formats stored arguments and writes the output to the writer. */ - void format(BasicCStringRef format_str); + // Parses argument index and returns corresponding argument. + internal::Arg parse_arg_index(const Char *&s); + + // Parses argument name and returns corresponding argument. + internal::Arg parse_arg_name(const Char *&s); // Formats a single argument and advances format_str, a format string pointer. - const Char *format(const Char *&format_str, const internal::Arg &arg); + const Char *format(BasicWriter &writer, const Char *&format_str, + const internal::Arg &arg); }; -template -void vformat(BasicWriter &writer, - BasicCStringRef format_str, - basic_format_args> args) { - basic_formatter formatter(args, writer); - formatter.format(format_str); -} - /** An error returned by an operating system or a language runtime, for example a file opening error. @@ -3463,13 +3448,13 @@ inline internal::Arg basic_formatter::parse_arg_name(const Char *&s) { template const Char *basic_formatter::format( - const Char *&format_str, const internal::Arg &arg) { + BasicWriter &writer, const Char *&format_str, const internal::Arg &arg) { using internal::Arg; const Char *s = format_str; FormatSpec spec; if (*s == ':') { if (arg.type == Arg::CUSTOM) { - arg.custom.format(&writer(), arg.custom.value, this, &s); + arg.custom.format(&writer, arg.custom.value, this, &s); return s; } ++s; @@ -3627,30 +3612,33 @@ const Char *basic_formatter::format( FMT_THROW(format_error("missing '}' in format string")); // Format argument. - ArgFormatter(*this, spec, s - 1).visit(arg); + ArgFormatter(writer, *this, spec, s - 1).visit(arg); return s; } -template -void basic_formatter::format(BasicCStringRef format_str) { +/** Formats arguments and writes the output to the writer. */ +template +void vformat(BasicWriter &writer, BasicCStringRef format_str, + basic_format_args> args) { + basic_formatter formatter(args); const Char *s = format_str.c_str(); const Char *start = s; while (*s) { Char c = *s++; if (c != '{' && c != '}') continue; if (*s == c) { - this->write(writer_, start, s); + internal::write(writer, start, s); start = ++s; continue; } if (c == '}') FMT_THROW(format_error("unmatched '}' in format string")); - this->write(writer_, start, s - 1); + internal::write(writer, start, s - 1); internal::Arg arg = internal::is_name_start(*s) ? - parse_arg_name(s) : parse_arg_index(s); - start = s = format(s, arg); + formatter.parse_arg_name(s) : formatter.parse_arg_index(s); + start = s = formatter.format(writer, s, arg); } - this->write(writer_, start, s); + internal::write(writer, start, s); } } // namespace fmt diff --git a/fmt/ostream.h b/fmt/ostream.h index 968a4100..6173e688 100644 --- a/fmt/ostream.h +++ b/fmt/ostream.h @@ -89,7 +89,7 @@ void format_value(BasicWriter &w, const T &value, internal::MemoryBuffer buffer; auto str = internal::format_value(buffer, value); typedef internal::MakeArg< basic_formatter > MakeArg; - format_str = f.format(format_str, MakeArg(str)); + format_str = f.format(w, format_str, MakeArg(str)); } FMT_API void vprint(std::ostream &os, CStringRef format_str, format_args args); diff --git a/fmt/printf.h b/fmt/printf.h index cf9a8517..7d171255 100644 --- a/fmt/printf.h +++ b/fmt/printf.h @@ -262,11 +262,11 @@ class BasicPrintfArgFormatter : public internal::ArgFormatterBase { /** Formats an argument of a custom (user-defined) type. */ void visit_custom(internal::Arg::CustomValue c) { - basic_formatter formatter(basic_format_args>(), - this->writer()); + typedef basic_formatter Formatter; + Formatter formatter((basic_format_args())); const Char format_str[] = {'}', 0}; const Char *format = format_str; - c.format(&formatter.writer(), c.value, &formatter, &format); + c.format(&this->writer(), c.value, &formatter, &format); } }; @@ -290,8 +290,6 @@ class PrintfFormatter : typedef Char char_type; private: - BasicWriter &writer_; - typedef internal::FormatterBase Base; void parse_flags(FormatSpec &spec, const Char *&s); @@ -313,14 +311,12 @@ class PrintfFormatter : appropriate lifetimes. \endrst */ - explicit PrintfFormatter(basic_format_args args, - BasicWriter &w) - : Base(args), writer_(w) {} - - BasicWriter &writer() { return writer_; } + explicit PrintfFormatter(basic_format_args args) + : Base(args) {} /** Formats stored arguments and writes the output to the writer. */ - FMT_API void format(BasicCStringRef format_str); + FMT_API void format(BasicWriter &writer, + BasicCStringRef format_str); }; template @@ -396,18 +392,19 @@ unsigned PrintfFormatter::parse_header( } template -void PrintfFormatter::format(BasicCStringRef format_str) { +void PrintfFormatter::format(BasicWriter &writer, + BasicCStringRef format_str) { const Char *start = format_str.c_str(); const Char *s = start; while (*s) { Char c = *s++; if (c != '%') continue; if (*s == c) { - this->write(writer_, start, s); + internal::write(writer, start, s); start = ++s; continue; } - this->write(writer_, start, s - 1); + internal::write(writer, start, s - 1); FormatSpec spec; spec.align_ = ALIGN_RIGHT; @@ -490,9 +487,9 @@ void PrintfFormatter::format(BasicCStringRef format_str) { start = s; // Format argument. - AF(writer_, spec).visit(arg); + AF(writer, spec).visit(arg); } - this->write(writer_, start, s); + internal::write(writer, start, s); } // Formats a value. @@ -500,13 +497,13 @@ template void format_value(BasicWriter &w, const T &value, PrintfFormatter &f, const Char *&) { internal::MemoryBuffer buffer; - f.writer() << internal::format_value(buffer, value); + w << internal::format_value(buffer, value); } template void printf(BasicWriter &w, BasicCStringRef format, basic_format_args> args) { - PrintfFormatter(args, w).format(format); + PrintfFormatter(args).format(w, format); } inline std::string vsprintf(CStringRef format, diff --git a/test/custom-formatter-test.cc b/test/custom-formatter-test.cc index 53227a3c..499e07a2 100644 --- a/test/custom-formatter-test.cc +++ b/test/custom-formatter-test.cc @@ -17,9 +17,10 @@ using fmt::BasicPrintfArgFormatter; class CustomArgFormatter : public fmt::BasicArgFormatter { public: - CustomArgFormatter(fmt::basic_formatter &f, + CustomArgFormatter(fmt::Writer &w, + fmt::basic_formatter &f, fmt::FormatSpec &s, const char *fmt) - : fmt::BasicArgFormatter(f, s, fmt) {} + : fmt::BasicArgFormatter(w, f, s, fmt) {} void visit_double(double value) { if (round(value * pow(10, spec().precision())) == 0) @@ -47,12 +48,11 @@ class CustomPrintfArgFormatter : typedef fmt::basic_formatter CustomFormatter; -std::string custom_vformat(const char *format_str, +std::string custom_vformat(fmt::CStringRef format_str, fmt::basic_format_args args) { fmt::MemoryWriter writer; - // Pass custom argument formatter as a template arg to basic_formatter. - CustomFormatter formatter(args, writer); - formatter.format(format_str); + // Pass custom argument formatter as a template arg to vformat. + fmt::vformat(writer, format_str, args); return writer.str(); } @@ -69,8 +69,8 @@ std::string custom_vsprintf( const char* format_str, fmt::basic_format_args args) { fmt::MemoryWriter writer; - CustomPrintfFormatter formatter(args, writer); - formatter.format(format_str); + CustomPrintfFormatter formatter(args); + formatter.format(writer, format_str); return writer.str(); } diff --git a/test/format-test.cc b/test/format-test.cc index 2d4d10aa..4493d003 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1357,7 +1357,7 @@ TEST(FormatterTest, FormatCStringRef) { void format_value(fmt::Writer &w, const Date &d, fmt::basic_formatter &f, const char *) { - f.writer() << d.year() << '-' << d.month() << '-' << d.day(); + w << d.year() << '-' << d.month() << '-' << d.day(); } TEST(FormatterTest, FormatCustom) { @@ -1371,7 +1371,7 @@ class Answer {}; template void format_value(BasicWriter &w, Answer, fmt::basic_formatter &f, const Char *) { - f.writer() << "42"; + w << "42"; } TEST(FormatterTest, CustomFormat) { @@ -1626,9 +1626,10 @@ class MockArgFormatter : public: typedef fmt::internal::ArgFormatterBase Base; - MockArgFormatter(fmt::basic_formatter &f, + MockArgFormatter(fmt::Writer &w, + fmt::basic_formatter &f, fmt::FormatSpec &s, const char *) - : fmt::internal::ArgFormatterBase(f.writer(), s) { + : fmt::internal::ArgFormatterBase(w, s) { EXPECT_CALL(*this, visit_int(42)); } @@ -1637,11 +1638,10 @@ class MockArgFormatter : typedef fmt::basic_formatter CustomFormatter; -void custom_vformat(const char *format_str, +void custom_vformat(fmt::CStringRef format_str, fmt::basic_format_args args) { fmt::MemoryWriter writer; - CustomFormatter formatter(args, writer); - formatter.format(format_str); + vformat(writer, format_str, args); } template diff --git a/test/ostream-test.cc b/test/ostream-test.cc index 224540b1..17c9d079 100644 --- a/test/ostream-test.cc +++ b/test/ostream-test.cc @@ -59,17 +59,18 @@ TEST(OStreamTest, Enum) { } struct TestArgFormatter : fmt::BasicArgFormatter { - TestArgFormatter(fmt::basic_formatter &f, + TestArgFormatter(fmt::Writer &w, + fmt::basic_formatter &f, fmt::FormatSpec &s, const char *fmt) - : fmt::BasicArgFormatter(f, s, fmt) {} + : fmt::BasicArgFormatter(w, f, s, fmt) {} }; TEST(OStreamTest, CustomArg) { fmt::MemoryWriter writer; typedef fmt::basic_formatter Formatter; - Formatter formatter(fmt::basic_format_args(), writer); + Formatter formatter((fmt::basic_format_args())); fmt::FormatSpec spec; - TestArgFormatter af(formatter, spec, "}"); + TestArgFormatter af(writer, formatter, spec, "}"); af.visit(fmt::internal::MakeArg(TestEnum())); EXPECT_EQ("TestEnum", writer.str()); } diff --git a/test/util-test.cc b/test/util-test.cc index 33603340..87ad25e7 100644 --- a/test/util-test.cc +++ b/test/util-test.cc @@ -567,9 +567,9 @@ TEST(ArgTest, MakeArg) { EXPECT_EQ(fmt::internal::Arg::CUSTOM, arg.type); EXPECT_EQ(&t, arg.custom.value); fmt::MemoryWriter w; - fmt::basic_formatter formatter(fmt::format_args(), w); + fmt::basic_formatter formatter((fmt::format_args())); const char *s = "}"; - arg.custom.format(&formatter.writer(), &formatter, &t, &s); + arg.custom.format(&w, &formatter, &t, &s); EXPECT_EQ("test", w.str()); }