mirror of
https://github.com/fmtlib/fmt.git
synced 2025-01-05 20:41:06 +00:00
Add FormatterBase.
This commit is contained in:
parent
9144a8fbbe
commit
4edc88f609
95
format.cc
95
format.cc
@ -415,13 +415,14 @@ template <typename Char>
|
||||
class fmt::internal::ArgFormatter :
|
||||
public fmt::internal::ArgVisitor<fmt::internal::ArgFormatter<Char>, void> {
|
||||
private:
|
||||
fmt::BasicFormatter<Char> &formatter_;
|
||||
fmt::BasicWriter<Char> &writer_;
|
||||
fmt::FormatSpec &spec_;
|
||||
const Char *format_;
|
||||
|
||||
public:
|
||||
ArgFormatter(fmt::BasicWriter<Char> &w, fmt::FormatSpec &s, const Char *fmt)
|
||||
: writer_(w), spec_(s), format_(fmt) {}
|
||||
ArgFormatter(fmt::BasicFormatter<Char> &f, fmt::FormatSpec &s, const Char *fmt)
|
||||
: formatter_(f), writer_(f.writer()), spec_(s), format_(fmt) {}
|
||||
|
||||
template <typename T>
|
||||
void visit_any_int(T value) { writer_.FormatInt(value, spec_); }
|
||||
@ -467,7 +468,7 @@ class fmt::internal::ArgFormatter :
|
||||
}
|
||||
|
||||
void visit_custom(Arg::CustomValue c) {
|
||||
c.format(this, c.value, format_);
|
||||
c.format(&formatter_, c.value, format_);
|
||||
}
|
||||
};
|
||||
|
||||
@ -670,22 +671,20 @@ inline const Arg
|
||||
if (*s < '0' || *s > '9') {
|
||||
if (*s != '}' && *s != ':')
|
||||
report_error_(s, "invalid argument index in format string");
|
||||
if (next_arg_index_ < 0) {
|
||||
report_error_(s,
|
||||
"cannot switch from manual to automatic argument indexing");
|
||||
}
|
||||
arg_index = next_arg_index_++;
|
||||
} else {
|
||||
if (next_arg_index_ > 0) {
|
||||
report_error_(s,
|
||||
"cannot switch from automatic to manual argument indexing");
|
||||
}
|
||||
next_arg_index_ = -1;
|
||||
const char *error = 0;
|
||||
arg_index = ParseNonnegativeInt(s, error);
|
||||
if (error)
|
||||
report_error_(s, error); // TODO
|
||||
const Arg &arg = next_arg();
|
||||
if (error_)
|
||||
report_error_(s, error_);
|
||||
return arg;
|
||||
}
|
||||
if (next_arg_index_ > 0) {
|
||||
report_error_(s,
|
||||
"cannot switch from automatic to manual argument indexing");
|
||||
}
|
||||
next_arg_index_ = -1;
|
||||
const char *error = 0;
|
||||
arg_index = ParseNonnegativeInt(s, error);
|
||||
if (error)
|
||||
report_error_(s, error); // TODO
|
||||
if (arg_index >= args_.size())
|
||||
report_error_(s, "argument index is out of range in format");
|
||||
return args_[arg_index];
|
||||
@ -706,6 +705,41 @@ void fmt::BasicFormatter<Char>::CheckSign(
|
||||
++s;
|
||||
}
|
||||
|
||||
const Arg &fmt::internal::FormatterBase::next_arg() {
|
||||
if (next_arg_index_ < 0) {
|
||||
if (!error_)
|
||||
error_ = "cannot switch from manual to automatic argument indexing";
|
||||
return DUMMY_ARG;
|
||||
}
|
||||
unsigned arg_index = next_arg_index_++;
|
||||
if (arg_index < args_.size())
|
||||
return args_[arg_index];
|
||||
if (!error_)
|
||||
error_ = "argument index is out of range in format";
|
||||
return DUMMY_ARG;
|
||||
}
|
||||
|
||||
const Arg &fmt::internal::FormatterBase::HandleArgIndex(
|
||||
unsigned arg_index, const char *&error) {
|
||||
if (arg_index != UINT_MAX) {
|
||||
if (next_arg_index_ <= 0) {
|
||||
next_arg_index_ = -1;
|
||||
--arg_index;
|
||||
} else if (!error) {
|
||||
error = "cannot switch from automatic to manual argument indexing";
|
||||
}
|
||||
} else if (next_arg_index_ >= 0) {
|
||||
arg_index = next_arg_index_++;
|
||||
} else if (!error) {
|
||||
error = "cannot switch from manual to automatic argument indexing";
|
||||
}
|
||||
if (arg_index < args_.size())
|
||||
return args_[arg_index];
|
||||
if (!error)
|
||||
error = "argument index is out of range in format";
|
||||
return DUMMY_ARG;
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
void fmt::internal::PrintfFormatter<Char>::ParseFlags(
|
||||
FormatSpec &spec, const Char *&s) {
|
||||
@ -767,29 +801,6 @@ unsigned fmt::internal::PrintfFormatter<Char>::ParseHeader(
|
||||
return arg_index;
|
||||
}
|
||||
|
||||
// TODO: move to a base class that doesn't depend on template argument
|
||||
template <typename Char>
|
||||
const Arg &fmt::internal::PrintfFormatter<Char>::HandleArgIndex(
|
||||
unsigned arg_index, const char *&error) {
|
||||
if (arg_index != UINT_MAX) {
|
||||
if (next_arg_index_ <= 0) {
|
||||
next_arg_index_ = -1;
|
||||
--arg_index;
|
||||
} else if (!error) {
|
||||
error = "cannot switch from automatic to manual argument indexing";
|
||||
}
|
||||
} else if (next_arg_index_ >= 0) {
|
||||
arg_index = next_arg_index_++;
|
||||
} else if (!error) {
|
||||
error = "cannot switch from manual to automatic argument indexing";
|
||||
}
|
||||
if (arg_index < args_.size())
|
||||
return args_[arg_index];
|
||||
if (!error)
|
||||
error = "argument index is out of range in format";
|
||||
return DUMMY_ARG;
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
void fmt::internal::PrintfFormatter<Char>::Format(
|
||||
BasicWriter<Char> &writer, BasicStringRef<Char> format,
|
||||
@ -1083,7 +1094,7 @@ const Char *fmt::BasicFormatter<Char>::format(
|
||||
start_ = s;
|
||||
|
||||
// Format argument.
|
||||
internal::ArgFormatter<Char>(writer_, spec, s - 1).visit(arg);
|
||||
internal::ArgFormatter<Char>(*this, spec, s - 1).visit(arg);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
63
format.h
63
format.h
@ -845,13 +845,44 @@ class ArgList {
|
||||
|
||||
struct FormatSpec;
|
||||
|
||||
// A formatter.
|
||||
template <typename Char>
|
||||
class BasicFormatter {
|
||||
private:
|
||||
BasicWriter<Char> &writer_;
|
||||
namespace internal {
|
||||
|
||||
class FormatterBase {
|
||||
protected:
|
||||
ArgList args_;
|
||||
int next_arg_index_;
|
||||
const char *error_;
|
||||
|
||||
FormatterBase() : error_(0) {}
|
||||
|
||||
const Arg &next_arg();
|
||||
|
||||
const Arg &HandleArgIndex(unsigned arg_index, const char *&error);
|
||||
|
||||
// TODO
|
||||
};
|
||||
|
||||
// A printf formatter.
|
||||
template <typename Char>
|
||||
class PrintfFormatter : private FormatterBase {
|
||||
private:
|
||||
void ParseFlags(FormatSpec &spec, const Char *&s);
|
||||
|
||||
// Parses argument index, flags and width and returns the parsed
|
||||
// argument index.
|
||||
unsigned ParseHeader(const Char *&s, FormatSpec &spec, const char *&error);
|
||||
|
||||
public:
|
||||
void Format(BasicWriter<Char> &writer,
|
||||
BasicStringRef<Char> format, const ArgList &args);
|
||||
};
|
||||
} // namespace internal
|
||||
|
||||
// A formatter.
|
||||
template <typename Char>
|
||||
class BasicFormatter : private internal::FormatterBase {
|
||||
private:
|
||||
BasicWriter<Char> &writer_;
|
||||
const Char *start_;
|
||||
internal::FormatErrorReporter<Char> report_error_;
|
||||
|
||||
@ -870,28 +901,6 @@ public:
|
||||
const Char *format(const Char *format_str, const internal::Arg &arg);
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
// A printf formatter.
|
||||
template <typename Char>
|
||||
class PrintfFormatter {
|
||||
private:
|
||||
ArgList args_;
|
||||
int next_arg_index_;
|
||||
|
||||
void ParseFlags(FormatSpec &spec, const Char *&s);
|
||||
|
||||
// Parses argument index, flags and width and returns the parsed
|
||||
// argument index.
|
||||
unsigned ParseHeader(const Char *&s, FormatSpec &spec, const char *&error);
|
||||
|
||||
const internal::Arg &HandleArgIndex(unsigned arg_index, const char *&error);
|
||||
|
||||
public:
|
||||
void Format(BasicWriter<Char> &writer,
|
||||
BasicStringRef<Char> format, const ArgList &args);
|
||||
};
|
||||
} // namespace internal
|
||||
|
||||
enum Alignment {
|
||||
ALIGN_DEFAULT, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER, ALIGN_NUMERIC
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user