forked from fmtlib/fmt
Refactor argument visitor API (#422)
This commit is contained in:
41
fmt/format.h
41
fmt/format.h
@@ -1536,7 +1536,8 @@ typedef basic_format_args<basic_format_context<wchar_t>> wformat_args;
|
|||||||
#define FMT_DISPATCH(call) static_cast<Impl*>(this)->call
|
#define FMT_DISPATCH(call) static_cast<Impl*>(this)->call
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename Visitor>
|
||||||
typename std::result_of<Visitor(int)>::type visit(Visitor &&vis, format_arg arg) {
|
typename std::result_of<Visitor(int)>::type visit(Visitor &&vis,
|
||||||
|
format_arg arg) {
|
||||||
switch (arg.type) {
|
switch (arg.type) {
|
||||||
case format_arg::NONE:
|
case format_arg::NONE:
|
||||||
case format_arg::NAMED_ARG:
|
case format_arg::NAMED_ARG:
|
||||||
@@ -1746,7 +1747,9 @@ class ArgVisitor {
|
|||||||
called.
|
called.
|
||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
Result visit(const format_arg &arg) { return fmt::visit(*this, arg); }
|
Result visit(const format_arg &arg) {
|
||||||
|
return fmt::visit(*static_cast<Impl*>(this), arg);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Alignment {
|
enum Alignment {
|
||||||
@@ -2056,6 +2059,22 @@ class ArgFormatterBase : public ArgVisitor<Impl, void> {
|
|||||||
writer_.write_int(reinterpret_cast<uintptr_t>(p), spec_);
|
writer_.write_int(reinterpret_cast<uintptr_t>(p), spec_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename StrChar>
|
||||||
|
void write_str(Arg::StringValue<StrChar> value,
|
||||||
|
typename EnableIf<
|
||||||
|
std::is_same<Char, wchar_t>::value &&
|
||||||
|
std::is_same<StrChar, wchar_t>::value, int>::type = 0) {
|
||||||
|
writer_.write_str(value, spec_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename StrChar>
|
||||||
|
void write_str(Arg::StringValue<StrChar> value,
|
||||||
|
typename EnableIf<
|
||||||
|
!std::is_same<Char, wchar_t>::value ||
|
||||||
|
!std::is_same<StrChar, wchar_t>::value, int>::type = 0) {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BasicWriter<Char> &writer() { return writer_; }
|
BasicWriter<Char> &writer() { return writer_; }
|
||||||
FormatSpec &spec() { return spec_; }
|
FormatSpec &spec() { return spec_; }
|
||||||
@@ -2083,13 +2102,15 @@ class ArgFormatterBase : public ArgVisitor<Impl, void> {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void visit_any_double(T value) { writer_.write_double(value, spec_); }
|
void visit_any_double(T value) { writer_.write_double(value, spec_); }
|
||||||
|
|
||||||
void visit_bool(bool value) {
|
using ArgVisitor<Impl, void>::operator();
|
||||||
|
|
||||||
|
void operator()(bool value) {
|
||||||
if (spec_.type_)
|
if (spec_.type_)
|
||||||
return visit_any_int(value);
|
return visit_any_int(value);
|
||||||
write(value);
|
write(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit_char(int value) {
|
void operator()(wchar_t value) {
|
||||||
if (spec_.type_ && spec_.type_ != 'c') {
|
if (spec_.type_ && spec_.type_ != 'c') {
|
||||||
spec_.flags_ |= CHAR_FLAG;
|
spec_.flags_ |= CHAR_FLAG;
|
||||||
writer_.write_int(value, spec_);
|
writer_.write_int(value, spec_);
|
||||||
@@ -2119,23 +2140,21 @@ class ArgFormatterBase : public ArgVisitor<Impl, void> {
|
|||||||
*out = internal::CharTraits<Char>::cast(value);
|
*out = internal::CharTraits<Char>::cast(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit_cstring(const char *value) {
|
void operator()(const char *value) {
|
||||||
if (spec_.type_ == 'p')
|
if (spec_.type_ == 'p')
|
||||||
return write_pointer(value);
|
return write_pointer(value);
|
||||||
write(value);
|
write(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit_string(Arg::StringValue<char> value) {
|
void operator()(Arg::StringValue<char> value) {
|
||||||
writer_.write_str(value, spec_);
|
writer_.write_str(value, spec_);
|
||||||
}
|
}
|
||||||
|
|
||||||
using ArgVisitor<Impl, void>::visit_wstring;
|
void operator()(Arg::StringValue<wchar_t> value) {
|
||||||
|
write_str(value);
|
||||||
void visit_wstring(Arg::StringValue<Char> value) {
|
|
||||||
writer_.write_str(value, spec_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit_pointer(const void *value) {
|
void operator()(const void *value) {
|
||||||
if (spec_.type_ && spec_.type_ != 'p')
|
if (spec_.type_ && spec_.type_ != 'p')
|
||||||
report_unknown_type(spec_.type_, "pointer");
|
report_unknown_type(spec_.type_, "pointer");
|
||||||
write_pointer(value);
|
write_pointer(value);
|
||||||
|
16
fmt/printf.h
16
fmt/printf.h
@@ -210,8 +210,10 @@ class BasicPrintfArgFormatter : public internal::ArgFormatterBase<Impl, Char> {
|
|||||||
BasicPrintfArgFormatter(BasicWriter<Char> &writer, FormatSpec &spec)
|
BasicPrintfArgFormatter(BasicWriter<Char> &writer, FormatSpec &spec)
|
||||||
: internal::ArgFormatterBase<Impl, Char>(writer, spec) {}
|
: internal::ArgFormatterBase<Impl, Char>(writer, spec) {}
|
||||||
|
|
||||||
|
using Base::operator();
|
||||||
|
|
||||||
/** Formats an argument of type ``bool``. */
|
/** Formats an argument of type ``bool``. */
|
||||||
void visit_bool(bool value) {
|
void operator()(bool value) {
|
||||||
FormatSpec &fmt_spec = this->spec();
|
FormatSpec &fmt_spec = this->spec();
|
||||||
if (fmt_spec.type_ != 's')
|
if (fmt_spec.type_ != 's')
|
||||||
return this->visit_any_int(value);
|
return this->visit_any_int(value);
|
||||||
@@ -220,7 +222,7 @@ class BasicPrintfArgFormatter : public internal::ArgFormatterBase<Impl, Char> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Formats a character. */
|
/** Formats a character. */
|
||||||
void visit_char(int value) {
|
void operator()(wchar_t value) {
|
||||||
const FormatSpec &fmt_spec = this->spec();
|
const FormatSpec &fmt_spec = this->spec();
|
||||||
BasicWriter<Char> &w = this->writer();
|
BasicWriter<Char> &w = this->writer();
|
||||||
if (fmt_spec.type_ && fmt_spec.type_ != 'c')
|
if (fmt_spec.type_ && fmt_spec.type_ != 'c')
|
||||||
@@ -243,9 +245,9 @@ class BasicPrintfArgFormatter : public internal::ArgFormatterBase<Impl, Char> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Formats a null-terminated C string. */
|
/** Formats a null-terminated C string. */
|
||||||
void visit_cstring(const char *value) {
|
void operator()(const char *value) {
|
||||||
if (value)
|
if (value)
|
||||||
Base::visit_cstring(value);
|
Base::operator()(value);
|
||||||
else if (this->spec().type_ == 'p')
|
else if (this->spec().type_ == 'p')
|
||||||
write_null_pointer();
|
write_null_pointer();
|
||||||
else
|
else
|
||||||
@@ -253,15 +255,15 @@ class BasicPrintfArgFormatter : public internal::ArgFormatterBase<Impl, Char> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Formats a pointer. */
|
/** Formats a pointer. */
|
||||||
void visit_pointer(const void *value) {
|
void operator()(const void *value) {
|
||||||
if (value)
|
if (value)
|
||||||
return Base::visit_pointer(value);
|
return Base::operator()(value);
|
||||||
this->spec().type_ = 0;
|
this->spec().type_ = 0;
|
||||||
write_null_pointer();
|
write_null_pointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Formats an argument of a custom (user-defined) type. */
|
/** Formats an argument of a custom (user-defined) type. */
|
||||||
void visit_custom(internal::Arg::CustomValue c) {
|
void operator()(internal::Arg::CustomValue c) {
|
||||||
const Char format_str[] = {'}', '\0'};
|
const Char format_str[] = {'}', '\0'};
|
||||||
auto args = basic_format_args<basic_format_context<Char>>();
|
auto args = basic_format_args<basic_format_context<Char>>();
|
||||||
basic_format_context<Char> ctx(format_str, args);
|
basic_format_context<Char> ctx(format_str, args);
|
||||||
|
Reference in New Issue
Block a user