Replace formatter with context
diff --git a/fmt/format.cc b/fmt/format.cc
index 55ece67..5ec8e41 100644
--- a/fmt/format.cc
+++ b/fmt/format.cc
@@ -446,7 +446,7 @@
format_args args);
FMT_FUNC int vfprintf(std::FILE *f, CStringRef format,
- basic_format_args<PrintfFormatter<char>> args) {
+ basic_format_args<printf_context<char>> args) {
MemoryWriter w;
printf(w, format, args);
std::size_t size = w.size();
@@ -463,7 +463,7 @@
template void internal::ArgMap<char>::init(const format_args &args);
-template void PrintfFormatter<char>::format(Writer &writer, CStringRef format);
+template void printf_context<char>::format(Writer &writer);
template int internal::CharTraits<char>::format_float(
char *buffer, std::size_t size, const char *format,
@@ -479,8 +479,7 @@
template void internal::ArgMap<wchar_t>::init(const format_args &args);
-template void PrintfFormatter<wchar_t>::format(WWriter &writer,
- WCStringRef format);
+template void printf_context<wchar_t>::format(WWriter &writer);
template int internal::CharTraits<wchar_t>::format_float(
wchar_t *buffer, std::size_t size, const wchar_t *format,
diff --git a/fmt/format.h b/fmt/format.h
index 9d9359b..303091f 100644
--- a/fmt/format.h
+++ b/fmt/format.h
@@ -377,8 +377,11 @@
template <typename Impl, typename Char>
class BasicPrintfArgFormatter;
-template <typename Char, typename ArgFormatter = fmt::ArgFormatter<Char> >
-class basic_formatter;
+template <typename Char>
+class basic_format_context;
+
+typedef basic_format_context<char> format_context;
+typedef basic_format_context<wchar_t> wformat_context;
/**
\rst
@@ -993,7 +996,7 @@
};
typedef void (*FormatFunc)(
- void *writer, const void *arg, void *formatter, void *format_str_ptr);
+ void *writer, const void *arg, void *ctx);
struct CustomValue {
const void *value;
@@ -1230,10 +1233,10 @@
constexpr Type type() { return gettype<typename std::decay<T>::type>(); }
// Makes an Arg object from any type.
-template <typename Formatter>
+template <typename Context>
class MakeValue : public Arg {
public:
- typedef typename Formatter::char_type Char;
+ typedef typename Context::char_type Char;
private:
// The following two methods are private to disallow formatting of
@@ -1271,12 +1274,10 @@
// Formats an argument of a custom type, such as a user-defined class.
template <typename T>
static void format_custom_arg(
- void *writer, const void *arg, void *formatter, void *format_str_ptr) {
- typedef BasicWriter<typename Formatter::char_type> Writer;
- format_value(*static_cast<Writer*>(writer),
+ void *writer, const void *arg, void *context) {
+ format_value(*static_cast<BasicWriter<Char>*>(writer),
*static_cast<const T*>(arg),
- *static_cast<Formatter*>(formatter),
- *static_cast<const Char**>(format_str_ptr));
+ *static_cast<Context*>(context));
}
public:
@@ -1406,7 +1407,7 @@
template <typename T>
NamedArg(BasicStringRef<Char> argname, const T &value)
- : Arg(MakeArg< basic_formatter<Char> >(value)), name(argname) {}
+ : Arg(MakeArg< basic_format_context<Char> >(value)), name(argname) {}
};
class RuntimeError : public std::runtime_error {
@@ -1430,7 +1431,7 @@
enum { MAX_PACKED_ARGS = 16 };
} // namespace internal
-template <typename Formatter, typename ...Args>
+template <typename Context, typename ...Args>
class format_arg_store {
private:
static const size_t NUM_ARGS = sizeof...(Args);
@@ -1443,26 +1444,25 @@
std::array<value_type, NUM_ARGS + (IS_PACKED ? 0 : 1)> data_;
template <typename ...A>
- friend format_arg_store<Formatter, A...> make_format_args(const A & ... args);
+ friend format_arg_store<Context, A...> make_format_args(const A & ... args);
public:
static const uint64_t TYPES = internal::make_type<Args..., void>();
- format_arg_store(const Args &... args, Formatter *)
- : data_{{internal::MakeValue<Formatter>(args)...}} {}
+ format_arg_store(const Args &... args)
+ : data_{{internal::MakeValue<Context>(args)...}} {}
const value_type *data() const { return data_.data(); }
};
-template <typename Formatter, typename ...Args>
-inline format_arg_store<Formatter, Args...>
+template <typename Context, typename ...Args>
+inline format_arg_store<Context, Args...>
make_format_args(const Args & ... args) {
- Formatter *f = nullptr;
- return format_arg_store<Formatter, Args...>(args..., f);
+ return format_arg_store<Context, Args...>(args...);
}
/** Formatting arguments. */
-template <typename Formatter>
+template <typename Context>
class basic_format_args {
private:
// To reduce compiled code size per formatting function call, types of first
@@ -1496,7 +1496,7 @@
basic_format_args() : types_(0) {}
template <typename... Args>
- basic_format_args(const format_arg_store<Formatter, Args...> &store)
+ basic_format_args(const format_arg_store<Context, Args...> &store)
: types_(store.TYPES) {
set_data(store.data());
}
@@ -1527,8 +1527,8 @@
}
};
-typedef basic_format_args<basic_formatter<char>> format_args;
-typedef basic_format_args<basic_formatter<wchar_t>> wformat_args;
+typedef basic_format_args<basic_format_context<char>> format_args;
+typedef basic_format_args<basic_format_context<wchar_t>> wformat_args;
#define FMT_DISPATCH(call) static_cast<Impl*>(this)->call
@@ -2014,6 +2014,8 @@
}
public:
+ typedef Char char_type;
+
ArgFormatterBase(BasicWriter<Char> &w, FormatSpec &s)
: writer_(w), spec_(s) {}
@@ -2082,21 +2084,35 @@
}
};
-template <typename Formatter>
-class FormatterBase {
-private:
- basic_format_args<Formatter> args_;
+template <typename Char>
+inline void write(BasicWriter<Char> &w, const Char *start, const Char *end) {
+ if (start != end)
+ w << BasicStringRef<Char>(start, internal::to_unsigned(end - start));
+}
+
+template <typename Char, typename Context>
+class format_context_base {
+ private:
+ const Char *ptr_;
+ basic_format_args<Context> args_;
int next_arg_index_;
+ protected:
+ format_context_base(const Char *format_str, basic_format_args<Context> args)
+ : ptr_(format_str), args_(args), next_arg_index_(0) {}
+ ~format_context_base() {}
+
+ basic_format_args<Context> args() const { return args_; }
+
// Returns the argument with specified index.
- Arg do_get_arg(unsigned arg_index, const char *&error) {
- Arg arg = args_[arg_index];
+ format_arg do_get_arg(unsigned arg_index, const char *&error) {
+ format_arg arg = args_[arg_index];
switch (arg.type) {
- case Arg::NONE:
+ case format_arg::NONE:
error = "argument index out of range";
break;
- case Arg::NAMED_ARG:
- arg = *static_cast<const internal::Arg*>(arg.pointer);
+ case format_arg::NAMED_ARG:
+ arg = *static_cast<const format_arg*>(arg.pointer);
break;
default:
/*nothing*/;
@@ -2104,24 +2120,19 @@
return arg;
}
- protected:
- FormatterBase(basic_format_args<Formatter> args)
- : args_(args), next_arg_index_(0) {}
-
- const basic_format_args<Formatter> &args() const { return args_; }
-
- // Returns the next argument.
- Arg next_arg(const char *&error) {
- if (next_arg_index_ >= 0)
- return do_get_arg(internal::to_unsigned(next_arg_index_++), error);
- error = "cannot switch from manual to automatic argument indexing";
- return Arg();
- }
-
// Checks if manual indexing is used and returns the argument with
// specified index.
- Arg get_arg(unsigned arg_index, const char *&error) {
- return check_no_auto_index(error) ? do_get_arg(arg_index, error) : Arg();
+ format_arg get_arg(unsigned arg_index, const char *&error) {
+ return this->check_no_auto_index(error) ?
+ this->do_get_arg(arg_index, error) : format_arg();
+ }
+
+ // Returns the next argument.
+ format_arg next_arg(const char *&error) {
+ if (next_arg_index_ >= 0)
+ return this->do_get_arg(internal::to_unsigned(next_arg_index_++), error);
+ error = "cannot switch from manual to automatic argument indexing";
+ return format_arg();
}
bool check_no_auto_index(const char *&error) {
@@ -2132,13 +2143,11 @@
next_arg_index_ = -1;
return true;
}
-};
-template <typename Char>
-inline void write(BasicWriter<Char> &w, const Char *start, const Char *end) {
- if (start != end)
- w << BasicStringRef<Char>(start, internal::to_unsigned(end - start));
-}
+ public:
+ // Returns a pointer to the current position in the format string.
+ const Char *&ptr() { return ptr_; }
+};
} // namespace internal
/**
@@ -2161,8 +2170,7 @@
template <typename Impl, typename Char>
class BasicArgFormatter : public internal::ArgFormatterBase<Impl, Char> {
private:
- basic_formatter<Char, Impl> &formatter_;
- const Char *format_;
+ basic_format_context<Char> &ctx_;
public:
/**
@@ -2173,15 +2181,13 @@
to the part of the format string being parsed for custom argument types.
\endrst
*/
- BasicArgFormatter(BasicWriter<Char> &writer,
- basic_formatter<Char, Impl> &formatter,
- FormatSpec &spec, const Char *fmt)
- : internal::ArgFormatterBase<Impl, Char>(writer, spec),
- formatter_(formatter), format_(fmt) {}
+ BasicArgFormatter(BasicWriter<Char> &writer, basic_format_context<Char> &ctx,
+ FormatSpec &spec)
+ : internal::ArgFormatterBase<Impl, Char>(writer, spec), ctx_(ctx) {}
/** Formats an argument of a custom (user-defined) type. */
void visit_custom(internal::Arg::CustomValue c) {
- c.format(&this->writer(), c.value, &formatter_, &format_);
+ c.format(&this->writer(), c.value, &ctx_);
}
};
@@ -2190,49 +2196,45 @@
class ArgFormatter : public BasicArgFormatter<ArgFormatter<Char>, Char> {
public:
/** Constructs an argument formatter object. */
- ArgFormatter(BasicWriter<Char> &writer, basic_formatter<Char> &formatter,
- FormatSpec &spec, const Char *fmt)
- : BasicArgFormatter<ArgFormatter<Char>, Char>(writer, formatter, spec, fmt) {}
+ ArgFormatter(BasicWriter<Char> &writer, basic_format_context<Char> &ctx,
+ FormatSpec &spec)
+ : BasicArgFormatter<ArgFormatter<Char>, Char>(writer, ctx, spec) {}
};
-/** This template formats data and writes the output to a writer. */
-template <typename Char, typename ArgFormatter>
-class basic_formatter :
- private internal::FormatterBase<basic_formatter<Char, ArgFormatter>> {
- public:
- /** The character type for the output. */
- typedef Char char_type;
-
+template <typename Char>
+class basic_format_context :
+ public internal::format_context_base<Char, basic_format_context<Char>> {
private:
internal::ArgMap<Char> map_;
- FMT_DISALLOW_COPY_AND_ASSIGN(basic_formatter);
+ FMT_DISALLOW_COPY_AND_ASSIGN(basic_format_context);
- typedef internal::FormatterBase<basic_formatter> Base;
+ typedef internal::format_context_base<Char, basic_format_context> Base;
+
using Base::get_arg;
// Checks if manual indexing is used and returns the argument with
// specified name.
- internal::Arg get_arg(BasicStringRef<Char> arg_name, const char *&error);
+ format_arg get_arg(BasicStringRef<Char> name, const char *&error);
public:
+ /** The character type for the output. */
+ typedef Char char_type;
+
/**
\rst
- Constructs a ``basic_formatter`` object. References to the arguments are
- stored in the formatter object so make sure they have appropriate lifetimes.
+ Constructs a ``basic_format_context`` object. References to the arguments are
+ stored in the object so make sure they have appropriate lifetimes.
\endrst
*/
- basic_formatter(basic_format_args<basic_formatter> args) : Base(args) {}
+ basic_format_context(const Char *format_str,
+ basic_format_args<basic_format_context> args)
+ : Base(format_str, args) {}
- // 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);
+ // Parses argument id and returns corresponding argument.
+ format_arg parse_arg_id();
- // Formats a single argument and advances format_str, a format string pointer.
- const Char *format(BasicWriter<Char> &writer, const Char *&format_str,
- const internal::Arg &arg);
+ using Base::ptr;
};
/**
@@ -2269,7 +2271,7 @@
*/
template <typename... Args>
SystemError(int error_code, CStringRef message, const Args & ... args) {
- init(error_code, message, make_format_args<basic_formatter<char>>(args...));
+ init(error_code, message, make_format_args<format_context>(args...));
}
~SystemError() throw();
@@ -2464,10 +2466,7 @@
}
void vwrite(BasicCStringRef<Char> format,
- basic_format_args<basic_formatter<Char>> args) {
- vformat(*this, format, args);
- }
-
+ basic_format_args<basic_format_context<Char>> args);
/**
\rst
Writes formatted data.
@@ -2495,7 +2494,7 @@
*/
template <typename... Args>
void write(BasicCStringRef<Char> format, const Args & ... args) {
- vwrite(format, make_format_args<fmt::basic_formatter<Char>>(args...));
+ vwrite(format, make_format_args<basic_format_context<Char>>(args...));
}
BasicWriter &operator<<(int value) {
@@ -3123,7 +3122,7 @@
*/
template <typename... Args>
WindowsError(int error_code, CStringRef message, const Args & ... args) {
- init(error_code, message, make_format_args<basic_formatter<char>>(args...));
+ init(error_code, message, make_format_args<format_context>(args...));
}
};
@@ -3147,8 +3146,7 @@
template <typename... Args>
inline void print_colored(Color c, CStringRef format_str,
const Args & ... args) {
- vprint_colored(c, format_str,
- make_format_args<basic_formatter<char>>(args...));
+ vprint_colored(c, format_str, make_format_args<format_context>(args...));
}
inline std::string vformat(CStringRef format_str, format_args args) {
@@ -3168,7 +3166,7 @@
*/
template <typename... Args>
inline std::string format(CStringRef format_str, const Args & ... args) {
- return vformat(format_str, make_format_args<basic_formatter<char>>(args...));
+ return vformat(format_str, make_format_args<format_context>(args...));
}
inline std::wstring vformat(WCStringRef format_str, wformat_args args) {
@@ -3179,7 +3177,7 @@
template <typename... Args>
inline std::wstring format(WCStringRef format_str, const Args & ... args) {
- auto vargs = make_format_args<basic_formatter<wchar_t>>(args...);
+ auto vargs = make_format_args<wformat_context>(args...);
return vformat(format_str, vargs);
}
@@ -3196,7 +3194,7 @@
*/
template <typename... Args>
inline void print(std::FILE *f, CStringRef format_str, const Args & ... args) {
- vprint(f, format_str, make_format_args<basic_formatter<char>>(args...));
+ vprint(f, format_str, make_format_args<format_context>(args...));
}
FMT_API void vprint(CStringRef format_str, format_args args);
@@ -3212,7 +3210,7 @@
*/
template <typename... Args>
inline void print(CStringRef format_str, const Args & ... args) {
- vprint(format_str, make_format_args<basic_formatter<char>>(args...));
+ vprint(format_str, make_format_args<format_context>(args...));
}
/**
@@ -3405,57 +3403,55 @@
}
} // namespace internal
-template <typename Char, typename AF>
-inline internal::Arg basic_formatter<Char, AF>::get_arg(
- BasicStringRef<Char> arg_name, const char *&error) {
+template <typename Char>
+inline format_arg basic_format_context<Char>::get_arg(
+ BasicStringRef<Char> name, const char *&error) {
if (this->check_no_auto_index(error)) {
map_.init(this->args());
- const internal::Arg *arg = map_.find(arg_name);
+ const internal::Arg *arg = map_.find(name);
if (arg)
return *arg;
error = "argument not found";
}
- return internal::Arg();
+ return format_arg();
}
-template <typename Char, typename AF>
-inline internal::Arg basic_formatter<Char, AF>::parse_arg_index(
- const Char *&s) {
- const char *error = 0;
- internal::Arg arg = *s < '0' || *s > '9' ?
- this->next_arg(error) : get_arg(internal::parse_nonnegative_int(s), error);
- if (error) {
- FMT_THROW(format_error(
- *s != '}' && *s != ':' ? "invalid format string" : error));
+template <typename Char>
+inline format_arg basic_format_context<Char>::parse_arg_id() {
+ const Char *&s = this->ptr();
+ if (!internal::is_name_start(*s)) {
+ const char *error = 0;
+ format_arg arg = *s < '0' || *s > '9' ?
+ this->next_arg(error) : get_arg(internal::parse_nonnegative_int(s), error);
+ if (error) {
+ FMT_THROW(format_error(
+ *s != '}' && *s != ':' ? "invalid format string" : error));
+ }
+ return arg;
}
- return arg;
-}
-
-template <typename Char, typename AF>
-inline internal::Arg basic_formatter<Char, AF>::parse_arg_name(const Char *&s) {
- assert(internal::is_name_start(*s));
const Char *start = s;
Char c;
do {
c = *++s;
} while (internal::is_name_start(c) || ('0' <= c && c <= '9'));
const char *error = 0;
- internal::Arg arg = get_arg(BasicStringRef<Char>(start, s - start), error);
+ format_arg arg = get_arg(BasicStringRef<Char>(start, s - start), error);
if (error)
FMT_THROW(format_error(error));
return arg;
}
-template <typename Char, typename ArgFormatter>
-const Char *basic_formatter<Char, ArgFormatter>::format(
- BasicWriter<Char> &writer, const Char *&format_str, const internal::Arg &arg) {
+// Formats a single argument.
+template <typename ArgFormatter, typename Char, typename Context>
+void format_arg(BasicWriter<Char> &writer, const internal::Arg &arg,
+ Context &ctx) {
using internal::Arg;
- const Char *s = format_str;
+ const Char *&s = ctx.ptr();
FormatSpec spec;
if (*s == ':') {
if (arg.type == Arg::CUSTOM) {
- arg.custom.format(&writer, arg.custom.value, this, &s);
- return s;
+ arg.custom.format(&writer, arg.custom.value, &ctx);
+ return;
}
++s;
// Parse fill and alignment.
@@ -3527,8 +3523,7 @@
spec.width_ = internal::parse_nonnegative_int(s);
} else if (*s == '{') {
++s;
- Arg width_arg = internal::is_name_start(*s) ?
- parse_arg_name(s) : parse_arg_index(s);
+ Arg width_arg = ctx.parse_arg_id();
if (*s++ != '}')
FMT_THROW(format_error("invalid format string"));
ULongLong value = 0;
@@ -3565,8 +3560,7 @@
spec.precision_ = internal::parse_nonnegative_int(s);
} else if (*s == '{') {
++s;
- Arg precision_arg = internal::is_name_start(*s) ?
- parse_arg_name(s) : parse_arg_index(s);
+ Arg precision_arg = ctx.parse_arg_id();
if (*s++ != '}')
FMT_THROW(format_error("invalid format string"));
ULongLong value = 0;
@@ -3608,20 +3602,19 @@
spec.type_ = static_cast<char>(*s++);
}
- if (*s++ != '}')
+ if (*s != '}')
FMT_THROW(format_error("missing '}' in format string"));
// Format argument.
- ArgFormatter(writer, *this, spec, s - 1).visit(arg);
- return s;
+ ArgFormatter(writer, ctx, spec).visit(arg);
}
/** Formats arguments and writes the output to the writer. */
-template <typename ArgFormatter, typename Char = typename ArgFormatter::Char>
+template <typename ArgFormatter, typename Char, typename Context>
void vformat(BasicWriter<Char> &writer, BasicCStringRef<Char> format_str,
- basic_format_args<basic_formatter<Char, ArgFormatter>> args) {
- basic_formatter<Char, ArgFormatter> formatter(args);
- const Char *s = format_str.c_str();
+ basic_format_args<Context> args) {
+ basic_format_context<Char> ctx(format_str.c_str(), args);
+ const Char *&s = ctx.ptr();
const Char *start = s;
while (*s) {
Char c = *s++;
@@ -3634,12 +3627,19 @@
if (c == '}')
FMT_THROW(format_error("unmatched '}' in format string"));
internal::write(writer, start, s - 1);
- internal::Arg arg = internal::is_name_start(*s) ?
- formatter.parse_arg_name(s) : formatter.parse_arg_index(s);
- start = s = formatter.format(writer, s, arg);
+ format_arg<ArgFormatter>(writer, ctx.parse_arg_id(), ctx);
+ assert(*s == '}');
+ start = ++s;
}
internal::write(writer, start, s);
}
+
+template <typename Char>
+inline void BasicWriter<Char>::vwrite(
+ BasicCStringRef<Char> format,
+ basic_format_args<basic_format_context<Char>> args) {
+ vformat<ArgFormatter<Char>>(*this, format, args);
+}
} // namespace fmt
#if FMT_USE_USER_DEFINED_LITERALS
diff --git a/fmt/ostream.h b/fmt/ostream.h
index 6173e68..feafc3b 100644
--- a/fmt/ostream.h
+++ b/fmt/ostream.h
@@ -82,14 +82,13 @@
} // namespace internal
// Formats a value.
-template <typename Char, typename ArgFormatter, typename T>
+template <typename Char, typename T>
void format_value(BasicWriter<Char> &w, const T &value,
- basic_formatter<Char, ArgFormatter> &f,
- const Char *&format_str) {
+ basic_format_context<Char> &ctx) {
internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer;
auto str = internal::format_value(buffer, value);
- typedef internal::MakeArg< basic_formatter<Char> > MakeArg;
- format_str = f.format(w, format_str, MakeArg(str));
+ typedef internal::MakeArg< basic_format_context<Char> > MakeArg;
+ format_arg< ArgFormatter<Char> >(w, MakeArg(str), ctx);
}
FMT_API void vprint(std::ostream &os, CStringRef format_str, format_args args);
@@ -106,7 +105,7 @@
template <typename... Args>
inline void print(std::ostream &os, CStringRef format_str,
const Args & ... args) {
- vprint(os, format_str, make_format_args<basic_formatter<char>>(args...));
+ vprint(os, format_str, make_format_args<format_context>(args...));
}
} // namespace fmt
diff --git a/fmt/posix.h b/fmt/posix.h
index 5fd1785..c6c6c13 100644
--- a/fmt/posix.h
+++ b/fmt/posix.h
@@ -172,7 +172,7 @@
template <typename... Args>
inline void print(CStringRef format_str, const Args & ... args) {
- vprint(format_str, make_format_args<basic_formatter<char>>(args...));
+ vprint(format_str, make_format_args<format_context>(args...));
}
};
diff --git a/fmt/printf.h b/fmt/printf.h
index 7d17125..42728b7 100644
--- a/fmt/printf.h
+++ b/fmt/printf.h
@@ -262,11 +262,10 @@
/** Formats an argument of a custom (user-defined) type. */
void visit_custom(internal::Arg::CustomValue c) {
- typedef basic_formatter<Char> Formatter;
- Formatter formatter((basic_format_args<Formatter>()));
- const Char format_str[] = {'}', 0};
- const Char *format = format_str;
- c.format(&this->writer(), c.value, &formatter, &format);
+ const Char format_str[] = {'}', '\0'};
+ auto args = basic_format_args<basic_format_context<Char>>();
+ basic_format_context<Char> ctx(format_str, args);
+ c.format(&this->writer(), c.value, &ctx);
}
};
@@ -283,14 +282,15 @@
/** This template formats data and writes the output to a writer. */
template <typename Char,
typename ArgFormatter = PrintfArgFormatter<Char> >
-class PrintfFormatter :
- private internal::FormatterBase<PrintfFormatter<Char, ArgFormatter>> {
+class printf_context :
+ private internal::format_context_base<
+ Char, printf_context<Char, ArgFormatter>> {
public:
/** The character type for the output. */
typedef Char char_type;
private:
- typedef internal::FormatterBase<PrintfFormatter> Base;
+ typedef internal::format_context_base<Char, printf_context> Base;
void parse_flags(FormatSpec &spec, const Char *&s);
@@ -306,21 +306,21 @@
public:
/**
\rst
- Constructs a ``PrintfFormatter`` object. References to the arguments and
- the writer are stored in the formatter object so make sure they have
+ Constructs a ``printf_context`` object. References to the arguments and
+ the writer are stored in the context object so make sure they have
appropriate lifetimes.
\endrst
*/
- explicit PrintfFormatter(basic_format_args<PrintfFormatter> args)
- : Base(args) {}
-
+ explicit printf_context(BasicCStringRef<Char> format_str,
+ basic_format_args<printf_context> args)
+ : Base(format_str.c_str(), args) {}
+
/** Formats stored arguments and writes the output to the writer. */
- FMT_API void format(BasicWriter<Char> &writer,
- BasicCStringRef<Char> format_str);
+ FMT_API void format(BasicWriter<Char> &writer);
};
template <typename Char, typename AF>
-void PrintfFormatter<Char, AF>::parse_flags(FormatSpec &spec, const Char *&s) {
+void printf_context<Char, AF>::parse_flags(FormatSpec &spec, const Char *&s) {
for (;;) {
switch (*s++) {
case '-':
@@ -346,8 +346,8 @@
}
template <typename Char, typename AF>
-internal::Arg PrintfFormatter<Char, AF>::get_arg(const Char *s,
- unsigned arg_index) {
+internal::Arg printf_context<Char, AF>::get_arg(const Char *s,
+ unsigned arg_index) {
(void)s;
const char *error = 0;
internal::Arg arg = arg_index == std::numeric_limits<unsigned>::max() ?
@@ -358,7 +358,7 @@
}
template <typename Char, typename AF>
-unsigned PrintfFormatter<Char, AF>::parse_header(
+unsigned printf_context<Char, AF>::parse_header(
const Char *&s, FormatSpec &spec) {
unsigned arg_index = std::numeric_limits<unsigned>::max();
Char c = *s;
@@ -392,9 +392,8 @@
}
template <typename Char, typename AF>
-void PrintfFormatter<Char, AF>::format(BasicWriter<Char> &writer,
- BasicCStringRef<Char> format_str) {
- const Char *start = format_str.c_str();
+void printf_context<Char, AF>::format(BasicWriter<Char> &writer) {
+ const Char *start = this->ptr();
const Char *s = start;
while (*s) {
Char c = *s++;
@@ -495,19 +494,19 @@
// Formats a value.
template <typename Char, typename T>
void format_value(BasicWriter<Char> &w, const T &value,
- PrintfFormatter<Char> &f, const Char *&) {
+ printf_context<Char>& ctx) {
internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer;
w << internal::format_value(buffer, value);
}
template <typename Char>
void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format,
- basic_format_args<PrintfFormatter<Char>> args) {
- PrintfFormatter<Char>(args).format(w, format);
+ basic_format_args<printf_context<Char>> args) {
+ printf_context<Char>(format, args).format(w);
}
inline std::string vsprintf(CStringRef format,
- basic_format_args<PrintfFormatter<char>> args) {
+ basic_format_args<printf_context<char>> args) {
MemoryWriter w;
printf(w, format, args);
return w.str();
@@ -524,11 +523,11 @@
*/
template <typename... Args>
inline std::string sprintf(CStringRef format_str, const Args & ... args) {
- return vsprintf(format_str, make_format_args<PrintfFormatter<char>>(args...));
+ return vsprintf(format_str, make_format_args<printf_context<char>>(args...));
}
inline std::wstring vsprintf(WCStringRef format,
- basic_format_args<PrintfFormatter<wchar_t>> args) {
+ basic_format_args<printf_context<wchar_t>> args) {
WMemoryWriter w;
printf(w, format, args);
return w.str();
@@ -536,12 +535,12 @@
template <typename... Args>
inline std::wstring sprintf(WCStringRef format_str, const Args & ... args) {
- auto vargs = make_format_args<PrintfFormatter<wchar_t>>(args...);
+ auto vargs = make_format_args<printf_context<wchar_t>>(args...);
return vsprintf(format_str, vargs);
}
FMT_API int vfprintf(std::FILE *f, CStringRef format,
- basic_format_args<PrintfFormatter<char>> args);
+ basic_format_args<printf_context<char>> args);
/**
\rst
@@ -554,12 +553,12 @@
*/
template <typename... Args>
inline int fprintf(std::FILE *f, CStringRef format_str, const Args & ... args) {
- auto vargs = make_format_args<PrintfFormatter<char>>(args...);
+ auto vargs = make_format_args<printf_context<char>>(args...);
return vfprintf(f, format_str, vargs);
}
inline int vprintf(CStringRef format,
- basic_format_args<PrintfFormatter<char>> args) {
+ basic_format_args<printf_context<char>> args) {
return vfprintf(stdout, format, args);
}
@@ -574,11 +573,11 @@
*/
template <typename... Args>
inline int printf(CStringRef format_str, const Args & ... args) {
- return vprintf(format_str, make_format_args<PrintfFormatter<char>>(args...));
+ return vprintf(format_str, make_format_args<printf_context<char>>(args...));
}
inline int vfprintf(std::ostream &os, CStringRef format_str,
- basic_format_args<PrintfFormatter<char>> args) {
+ basic_format_args<printf_context<char>> args) {
MemoryWriter w;
printf(w, format_str, args);
internal::write(os, w);
@@ -597,7 +596,7 @@
template <typename... Args>
inline int fprintf(std::ostream &os, CStringRef format_str,
const Args & ... args) {
- auto vargs = make_format_args<PrintfFormatter<char>>(args...);
+ auto vargs = make_format_args<printf_context<char>>(args...);
return vfprintf(os, format_str, vargs);
}
} // namespace fmt
diff --git a/fmt/time.h b/fmt/time.h
index 5b40a93..ad7ab9c 100644
--- a/fmt/time.h
+++ b/fmt/time.h
@@ -15,19 +15,17 @@
namespace fmt {
-template <typename ArgFormatter>
-void format_value(Writer &w, const std::tm &tm,
- basic_formatter<char, ArgFormatter> &f,
- const char *&format_str) {
- if (*format_str == ':')
- ++format_str;
- const char *end = format_str;
+void format_value(Writer &w, const std::tm &tm, format_context &ctx) {
+ const char *&s = ctx.ptr();
+ if (*s == ':')
+ ++s;
+ const char *end = s;
while (*end && *end != '}')
++end;
if (*end != '}')
FMT_THROW(format_error("missing '}' in format string"));
internal::MemoryBuffer<char, internal::INLINE_BUFFER_SIZE> format;
- format.append(format_str, end + 1);
+ format.append(s, end + 1);
format[format.size() - 1] = '\0';
Buffer<char> &buffer = w.buffer();
std::size_t start = buffer.size();
@@ -48,7 +46,7 @@
const std::size_t MIN_GROWTH = 10;
buffer.reserve(buffer.capacity() + (size > MIN_GROWTH ? size : MIN_GROWTH));
}
- format_str = end + 1;
+ s = end;
}
}
diff --git a/test/custom-formatter-test.cc b/test/custom-formatter-test.cc
index 499e07a..65888b2 100644
--- a/test/custom-formatter-test.cc
+++ b/test/custom-formatter-test.cc
@@ -17,10 +17,9 @@
class CustomArgFormatter
: public fmt::BasicArgFormatter<CustomArgFormatter, char> {
public:
- CustomArgFormatter(fmt::Writer &w,
- fmt::basic_formatter<char, CustomArgFormatter> &f,
- fmt::FormatSpec &s, const char *fmt)
- : fmt::BasicArgFormatter<CustomArgFormatter, char>(w, f, s, fmt) {}
+ CustomArgFormatter(fmt::Writer &w, fmt::basic_format_context<char> &ctx,
+ fmt::FormatSpec &s)
+ : fmt::BasicArgFormatter<CustomArgFormatter, char>(w, ctx, s) {}
void visit_double(double value) {
if (round(value * pow(10, spec().precision())) == 0)
@@ -46,10 +45,7 @@
}
};
-typedef fmt::basic_formatter<char, CustomArgFormatter> CustomFormatter;
-
-std::string custom_vformat(fmt::CStringRef format_str,
- fmt::basic_format_args<CustomFormatter> args) {
+std::string custom_vformat(fmt::CStringRef format_str, fmt::format_args args) {
fmt::MemoryWriter writer;
// Pass custom argument formatter as a template arg to vformat.
fmt::vformat<CustomArgFormatter>(writer, format_str, args);
@@ -58,19 +54,19 @@
template <typename... Args>
std::string custom_format(const char *format_str, const Args & ... args) {
- auto va = fmt::make_format_args<CustomFormatter>(args...);
+ auto va = fmt::make_format_args<fmt::format_context>(args...);
return custom_vformat(format_str, va);
}
-typedef fmt::PrintfFormatter<char, CustomPrintfArgFormatter>
+typedef fmt::printf_context<char, CustomPrintfArgFormatter>
CustomPrintfFormatter;
std::string custom_vsprintf(
const char* format_str,
fmt::basic_format_args<CustomPrintfFormatter> args) {
fmt::MemoryWriter writer;
- CustomPrintfFormatter formatter(args);
- formatter.format(writer, format_str);
+ CustomPrintfFormatter formatter(format_str, args);
+ formatter.format(writer);
return writer.str();
}
diff --git a/test/format-test.cc b/test/format-test.cc
index 4493d00..1e919b7 100644
--- a/test/format-test.cc
+++ b/test/format-test.cc
@@ -1355,8 +1355,7 @@
EXPECT_EQ("test", format("{0}", CStringRef("test")));
}
-void format_value(fmt::Writer &w, const Date &d, fmt::basic_formatter<char> &f,
- const char *) {
+void format_value(fmt::Writer &w, const Date &d, fmt::format_context &) {
w << d.year() << '-' << d.month() << '-' << d.day();
}
@@ -1369,8 +1368,7 @@
class Answer {};
template <typename Char>
-void format_value(BasicWriter<Char> &w, Answer, fmt::basic_formatter<Char> &f,
- const Char *) {
+void format_value(BasicWriter<Char> &w, Answer, fmt::format_context &) {
w << "42";
}
@@ -1561,7 +1559,7 @@
template <typename... Args>
std::string format_message(int id, const char *format, const Args & ... args) {
- auto va = fmt::make_format_args<fmt::basic_formatter<char>>(args...);
+ auto va = fmt::make_format_args<fmt::format_context>(args...);
return vformat_message(id, format, va);
}
@@ -1626,9 +1624,8 @@
public:
typedef fmt::internal::ArgFormatterBase<MockArgFormatter, char> Base;
- MockArgFormatter(fmt::Writer &w,
- fmt::basic_formatter<char, MockArgFormatter> &f,
- fmt::FormatSpec &s, const char *)
+ MockArgFormatter(fmt::Writer &w, fmt::format_context &ctx,
+ fmt::FormatSpec &s)
: fmt::internal::ArgFormatterBase<MockArgFormatter, char>(w, s) {
EXPECT_CALL(*this, visit_int(42));
}
@@ -1636,17 +1633,14 @@
MOCK_METHOD1(visit_int, void (int value));
};
-typedef fmt::basic_formatter<char, MockArgFormatter> CustomFormatter;
-
-void custom_vformat(fmt::CStringRef format_str,
- fmt::basic_format_args<CustomFormatter> args) {
+void custom_vformat(fmt::CStringRef format_str, fmt::format_args args) {
fmt::MemoryWriter writer;
- vformat(writer, format_str, args);
+ fmt::vformat<MockArgFormatter>(writer, format_str, args);
}
template <typename... Args>
void custom_format(const char *format_str, const Args & ... args) {
- auto va = fmt::make_format_args<CustomFormatter>(args...);
+ auto va = fmt::make_format_args<fmt::format_context>(args...);
return custom_vformat(format_str, va);
}
diff --git a/test/ostream-test.cc b/test/ostream-test.cc
index 17c9d07..2d1ace6 100644
--- a/test/ostream-test.cc
+++ b/test/ostream-test.cc
@@ -59,19 +59,17 @@
}
struct TestArgFormatter : fmt::BasicArgFormatter<TestArgFormatter, char> {
- TestArgFormatter(fmt::Writer &w,
- fmt::basic_formatter<char, TestArgFormatter> &f,
- fmt::FormatSpec &s, const char *fmt)
- : fmt::BasicArgFormatter<TestArgFormatter, char>(w, f, s, fmt) {}
+ TestArgFormatter(fmt::Writer &w, fmt::format_context &ctx,
+ fmt::FormatSpec &s)
+ : fmt::BasicArgFormatter<TestArgFormatter, char>(w, ctx, s) {}
};
TEST(OStreamTest, CustomArg) {
fmt::MemoryWriter writer;
- typedef fmt::basic_formatter<char, TestArgFormatter> Formatter;
- Formatter formatter((fmt::basic_format_args<Formatter>()));
+ fmt::format_context ctx("}", fmt::format_args());
fmt::FormatSpec spec;
- TestArgFormatter af(writer, formatter, spec, "}");
- af.visit(fmt::internal::MakeArg<Formatter>(TestEnum()));
+ TestArgFormatter af(writer, ctx, spec);
+ af.visit(fmt::internal::MakeArg<fmt::format_context>(TestEnum()));
EXPECT_EQ("TestEnum", writer.str());
}
diff --git a/test/util-test.cc b/test/util-test.cc
index 87ad25e..b553427 100644
--- a/test/util-test.cc
+++ b/test/util-test.cc
@@ -65,13 +65,13 @@
template <typename Char>
void format_value(fmt::BasicWriter<Char> &w, Test,
- fmt::basic_formatter<Char> &f, const Char *) {
+ fmt::basic_format_context<Char> &) {
w << "test";
}
template <typename Char, typename T>
Arg make_arg(const T &value) {
- typedef fmt::internal::MakeValue< fmt::basic_formatter<Char> > MakeValue;
+ typedef fmt::internal::MakeValue< fmt::basic_format_context<Char> > MakeValue;
Arg arg = MakeValue(value);
arg.type = fmt::internal::type<T>();
return arg;
@@ -567,9 +567,8 @@
EXPECT_EQ(fmt::internal::Arg::CUSTOM, arg.type);
EXPECT_EQ(&t, arg.custom.value);
fmt::MemoryWriter w;
- fmt::basic_formatter<char> formatter((fmt::format_args()));
- const char *s = "}";
- arg.custom.format(&w, &formatter, &t, &s);
+ fmt::format_context ctx("}", fmt::format_args());
+ arg.custom.format(&w, &t, &ctx);
EXPECT_EQ("test", w.str());
}
@@ -580,21 +579,20 @@
struct CustomFormatter {
typedef char char_type;
+ bool called;
};
-void format_value(fmt::Writer &, const Test &, CustomFormatter &,
- const char *&s) {
- s = "custom_format";
+void format_value(fmt::Writer &, const Test &, CustomFormatter &ctx) {
+ ctx.called = true;
}
TEST(UtilTest, MakeValueWithCustomFormatter) {
::Test t;
Arg arg = fmt::internal::MakeValue<CustomFormatter>(t);
- CustomFormatter formatter;
- const char *s = "";
+ CustomFormatter ctx = {false};
fmt::MemoryWriter w;
- arg.custom.format(&w, &formatter, &t, &s);
- EXPECT_STREQ("custom_format", s);
+ arg.custom.format(&w, &t, &ctx);
+ EXPECT_TRUE(ctx.called);
}
struct Result {