Make BasicArgFormatter public and add ArgFormatter
This allows providing custom argument formatters without relying on internal APIs (#235).
This commit is contained in:
parent
4d8cee2d48
commit
b69e6dcead
@ -372,17 +372,15 @@ class BasicWriter;
|
|||||||
typedef BasicWriter<char> Writer;
|
typedef BasicWriter<char> Writer;
|
||||||
typedef BasicWriter<wchar_t> WWriter;
|
typedef BasicWriter<wchar_t> WWriter;
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
class BasicArgFormatter;
|
class ArgFormatter;
|
||||||
}
|
|
||||||
|
|
||||||
template <typename CharType,
|
template <typename CharType,
|
||||||
typename ArgFormatter = internal::BasicArgFormatter<CharType> >
|
typename ArgFormatter = fmt::ArgFormatter<CharType> >
|
||||||
class BasicFormatter;
|
class BasicFormatter;
|
||||||
|
|
||||||
template <typename Char, typename T>
|
template <typename Char, typename ArgFormatter, typename T>
|
||||||
void format(BasicFormatter<Char> &f, const Char *&format_str, const T &value);
|
void format(BasicFormatter<Char, ArgFormatter> &f, const Char *&format_str, const T &value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\rst
|
\rst
|
||||||
@ -1842,24 +1840,6 @@ class ArgFormatterBase : public ArgVisitor<Impl, void> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// An argument formatter.
|
|
||||||
template <typename Char>
|
|
||||||
class BasicArgFormatter :
|
|
||||||
public ArgFormatterBase<BasicArgFormatter<Char>, Char> {
|
|
||||||
private:
|
|
||||||
BasicFormatter<Char> &formatter_;
|
|
||||||
const Char *format_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
BasicArgFormatter(BasicFormatter<Char> &f, FormatSpec &s, const Char *fmt)
|
|
||||||
: ArgFormatterBase<BasicArgFormatter<Char>, Char>(f.writer(), s),
|
|
||||||
formatter_(f), format_(fmt) {}
|
|
||||||
|
|
||||||
void visit_custom(Arg::CustomValue c) {
|
|
||||||
c.format(&formatter_, c.value, &format_);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class FormatterBase {
|
class FormatterBase {
|
||||||
private:
|
private:
|
||||||
ArgList args_;
|
ArgList args_;
|
||||||
@ -1927,6 +1907,32 @@ class PrintfFormatter : private FormatterBase {
|
|||||||
};
|
};
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
|
// An argument formatter.
|
||||||
|
template <typename Impl, typename Char>
|
||||||
|
class BasicArgFormatter : public internal::ArgFormatterBase<Impl, Char> {
|
||||||
|
private:
|
||||||
|
BasicFormatter<Char, Impl> &formatter_;
|
||||||
|
const Char *format_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BasicArgFormatter(BasicFormatter<Char, Impl> &f,
|
||||||
|
FormatSpec &s, const Char *fmt)
|
||||||
|
: internal::ArgFormatterBase<Impl, Char>(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 <typename Char>
|
||||||
|
class ArgFormatter : public BasicArgFormatter<ArgFormatter<Char>, Char> {
|
||||||
|
public:
|
||||||
|
ArgFormatter(BasicFormatter<Char> &f, FormatSpec &s, const Char *fmt)
|
||||||
|
: BasicArgFormatter<ArgFormatter<Char>, Char>(f, s, fmt) {}
|
||||||
|
};
|
||||||
|
|
||||||
/** This template formats data and writes the output to a writer. */
|
/** This template formats data and writes the output to a writer. */
|
||||||
template <typename CharType, typename ArgFormatter>
|
template <typename CharType, typename ArgFormatter>
|
||||||
class BasicFormatter : private internal::FormatterBase {
|
class BasicFormatter : private internal::FormatterBase {
|
||||||
@ -3009,8 +3015,9 @@ typedef BasicArrayWriter<char> ArrayWriter;
|
|||||||
typedef BasicArrayWriter<wchar_t> WArrayWriter;
|
typedef BasicArrayWriter<wchar_t> WArrayWriter;
|
||||||
|
|
||||||
// Formats a value.
|
// Formats a value.
|
||||||
template <typename Char, typename T>
|
template <typename Char, typename ArgFormatter, typename T>
|
||||||
void format(BasicFormatter<Char> &f, const Char *&format_str, const T &value) {
|
void format(BasicFormatter<Char, ArgFormatter> &f,
|
||||||
|
const Char *&format_str, const T &value) {
|
||||||
internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer;
|
internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer;
|
||||||
|
|
||||||
internal::FormatBuf<Char> format_buf(buffer);
|
internal::FormatBuf<Char> format_buf(buffer);
|
||||||
|
@ -1671,7 +1671,7 @@ TEST(FormatTest, EmptyCustomOutput) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MockArgFormatter :
|
class MockArgFormatter :
|
||||||
public fmt::internal::ArgFormatterBase<MockArgFormatter, char> {
|
public fmt::internal::ArgFormatterBase<MockArgFormatter, char> {
|
||||||
public:
|
public:
|
||||||
typedef fmt::internal::ArgFormatterBase<MockArgFormatter, char> Base;
|
typedef fmt::internal::ArgFormatterBase<MockArgFormatter, char> Base;
|
||||||
|
|
||||||
@ -1694,3 +1694,19 @@ FMT_VARIADIC(void, custom_format, const char *)
|
|||||||
TEST(FormatTest, CustomArgFormatter) {
|
TEST(FormatTest, CustomArgFormatter) {
|
||||||
custom_format("{}", 42);
|
custom_format("{}", 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TestArgFormatter : fmt::BasicArgFormatter<TestArgFormatter, char> {
|
||||||
|
TestArgFormatter(fmt::BasicFormatter<char, TestArgFormatter> &f,
|
||||||
|
fmt::FormatSpec &s, const char *fmt)
|
||||||
|
: fmt::BasicArgFormatter<TestArgFormatter, char>(f, s, fmt) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(ArgFormatterTest, CustomArg) {
|
||||||
|
fmt::MemoryWriter writer;
|
||||||
|
typedef fmt::BasicFormatter<char, TestArgFormatter> Formatter;
|
||||||
|
Formatter formatter(fmt::ArgList(), writer);
|
||||||
|
fmt::FormatSpec spec;
|
||||||
|
TestArgFormatter af(formatter, spec, "}");
|
||||||
|
af.visit(fmt::internal::MakeArg<Formatter>(TestEnum()));
|
||||||
|
EXPECT_EQ("TestEnum", writer.str());
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user