From b69e6dcead82f0e15751346ee2c3aadfcbfde9a5 Mon Sep 17 00:00:00 2001 From: vitaut Date: Tue, 19 Apr 2016 08:56:31 -0700 Subject: [PATCH] Make BasicArgFormatter public and add ArgFormatter This allows providing custom argument formatters without relying on internal APIs (#235). --- cppformat/format.h | 59 +++++++++++++++++++++++++-------------------- test/format-test.cc | 18 +++++++++++++- 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/cppformat/format.h b/cppformat/format.h index 4e26d828..ccd928fc 100644 --- a/cppformat/format.h +++ b/cppformat/format.h @@ -372,17 +372,15 @@ class BasicWriter; typedef BasicWriter Writer; typedef BasicWriter WWriter; -namespace internal { template -class BasicArgFormatter; -} +class ArgFormatter; template > + typename ArgFormatter = fmt::ArgFormatter > class BasicFormatter; -template -void format(BasicFormatter &f, const Char *&format_str, const T &value); +template +void format(BasicFormatter &f, const Char *&format_str, const T &value); /** \rst @@ -1842,24 +1840,6 @@ class ArgFormatterBase : public ArgVisitor { } }; -// An argument formatter. -template -class BasicArgFormatter : - public ArgFormatterBase, Char> { - private: - BasicFormatter &formatter_; - const Char *format_; - - public: - BasicArgFormatter(BasicFormatter &f, FormatSpec &s, const Char *fmt) - : ArgFormatterBase, Char>(f.writer(), s), - formatter_(f), format_(fmt) {} - - void visit_custom(Arg::CustomValue c) { - c.format(&formatter_, c.value, &format_); - } -}; - class FormatterBase { private: ArgList args_; @@ -1927,6 +1907,32 @@ class PrintfFormatter : private FormatterBase { }; } // namespace internal +// An argument formatter. +template +class BasicArgFormatter : public internal::ArgFormatterBase { + private: + BasicFormatter &formatter_; + const Char *format_; + + public: + BasicArgFormatter(BasicFormatter &f, + FormatSpec &s, const Char *fmt) + : internal::ArgFormatterBase(f.writer(), s), + formatter_(f), format_(fmt) {} + + void visit_custom(internal::Arg::CustomValue c) { + c.format(&formatter_, c.value, &format_); + } +}; + +// The default argument formatter. +template +class ArgFormatter : public BasicArgFormatter, Char> { + public: + ArgFormatter(BasicFormatter &f, FormatSpec &s, const Char *fmt) + : BasicArgFormatter, Char>(f, s, fmt) {} +}; + /** This template formats data and writes the output to a writer. */ template class BasicFormatter : private internal::FormatterBase { @@ -3009,8 +3015,9 @@ typedef BasicArrayWriter ArrayWriter; typedef BasicArrayWriter WArrayWriter; // Formats a value. -template -void format(BasicFormatter &f, const Char *&format_str, const T &value) { +template +void format(BasicFormatter &f, + const Char *&format_str, const T &value) { internal::MemoryBuffer buffer; internal::FormatBuf format_buf(buffer); diff --git a/test/format-test.cc b/test/format-test.cc index 121a7be6..b15c8aac 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1671,7 +1671,7 @@ TEST(FormatTest, EmptyCustomOutput) { } class MockArgFormatter : - public fmt::internal::ArgFormatterBase { + public fmt::internal::ArgFormatterBase { public: typedef fmt::internal::ArgFormatterBase Base; @@ -1694,3 +1694,19 @@ FMT_VARIADIC(void, custom_format, const char *) TEST(FormatTest, CustomArgFormatter) { custom_format("{}", 42); } + +struct TestArgFormatter : fmt::BasicArgFormatter { + TestArgFormatter(fmt::BasicFormatter &f, + fmt::FormatSpec &s, const char *fmt) + : fmt::BasicArgFormatter(f, s, fmt) {} +}; + +TEST(ArgFormatterTest, CustomArg) { + fmt::MemoryWriter writer; + typedef fmt::BasicFormatter Formatter; + Formatter formatter(fmt::ArgList(), writer); + fmt::FormatSpec spec; + TestArgFormatter af(formatter, spec, "}"); + af.visit(fmt::internal::MakeArg(TestEnum())); + EXPECT_EQ("TestEnum", writer.str()); +}