diff --git a/fmt/format.cc b/fmt/format.cc index 55ece67c..5ec8e41b 100644 --- a/fmt/format.cc +++ b/fmt/format.cc @@ -446,7 +446,7 @@ void printf(BasicWriter &w, BasicCStringRef format, format_args args); FMT_FUNC int vfprintf(std::FILE *f, CStringRef format, - basic_format_args> args) { + basic_format_args> args) { MemoryWriter w; printf(w, format, args); std::size_t size = w.size(); @@ -463,7 +463,7 @@ template void internal::FixedBuffer::grow(std::size_t); template void internal::ArgMap::init(const format_args &args); -template void PrintfFormatter::format(Writer &writer, CStringRef format); +template void printf_context::format(Writer &writer); template int internal::CharTraits::format_float( char *buffer, std::size_t size, const char *format, @@ -479,8 +479,7 @@ template void internal::FixedBuffer::grow(std::size_t); template void internal::ArgMap::init(const format_args &args); -template void PrintfFormatter::format(WWriter &writer, - WCStringRef format); +template void printf_context::format(WWriter &writer); template int internal::CharTraits::format_float( wchar_t *buffer, std::size_t size, const wchar_t *format, diff --git a/fmt/format.h b/fmt/format.h index 9d9359bc..303091fa 100644 --- a/fmt/format.h +++ b/fmt/format.h @@ -377,8 +377,11 @@ class ArgFormatter; template class BasicPrintfArgFormatter; -template > -class basic_formatter; +template +class basic_format_context; + +typedef basic_format_context format_context; +typedef basic_format_context wformat_context; /** \rst @@ -993,7 +996,7 @@ struct Value { }; 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 @@ template constexpr Type type() { return gettype::type>(); } // Makes an Arg object from any type. -template +template 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 @@ class MakeValue : public Arg { // Formats an argument of a custom type, such as a user-defined class. template static void format_custom_arg( - void *writer, const void *arg, void *formatter, void *format_str_ptr) { - typedef BasicWriter Writer; - format_value(*static_cast(writer), + void *writer, const void *arg, void *context) { + format_value(*static_cast*>(writer), *static_cast(arg), - *static_cast(formatter), - *static_cast(format_str_ptr)); + *static_cast(context)); } public: @@ -1406,7 +1407,7 @@ struct NamedArg : Arg { template NamedArg(BasicStringRef argname, const T &value) - : Arg(MakeArg< basic_formatter >(value)), name(argname) {} + : Arg(MakeArg< basic_format_context >(value)), name(argname) {} }; class RuntimeError : public std::runtime_error { @@ -1430,7 +1431,7 @@ constexpr uint64_t make_type() { return 0; } enum { MAX_PACKED_ARGS = 16 }; } // namespace internal -template +template class format_arg_store { private: static const size_t NUM_ARGS = sizeof...(Args); @@ -1443,26 +1444,25 @@ class format_arg_store { std::array data_; template - friend format_arg_store make_format_args(const A & ... args); + friend format_arg_store make_format_args(const A & ... args); public: static const uint64_t TYPES = internal::make_type(); - format_arg_store(const Args &... args, Formatter *) - : data_{{internal::MakeValue(args)...}} {} + format_arg_store(const Args &... args) + : data_{{internal::MakeValue(args)...}} {} const value_type *data() const { return data_.data(); } }; -template -inline format_arg_store +template +inline format_arg_store make_format_args(const Args & ... args) { - Formatter *f = nullptr; - return format_arg_store(args..., f); + return format_arg_store(args...); } /** Formatting arguments. */ -template +template class basic_format_args { private: // To reduce compiled code size per formatting function call, types of first @@ -1496,7 +1496,7 @@ class basic_format_args { basic_format_args() : types_(0) {} template - basic_format_args(const format_arg_store &store) + basic_format_args(const format_arg_store &store) : types_(store.TYPES) { set_data(store.data()); } @@ -1527,8 +1527,8 @@ class basic_format_args { } }; -typedef basic_format_args> format_args; -typedef basic_format_args> wformat_args; +typedef basic_format_args> format_args; +typedef basic_format_args> wformat_args; #define FMT_DISPATCH(call) static_cast(this)->call @@ -2014,6 +2014,8 @@ class ArgFormatterBase : public ArgVisitor { } public: + typedef Char char_type; + ArgFormatterBase(BasicWriter &w, FormatSpec &s) : writer_(w), spec_(s) {} @@ -2082,21 +2084,35 @@ class ArgFormatterBase : public ArgVisitor { } }; -template -class FormatterBase { -private: - basic_format_args args_; +template +inline void write(BasicWriter &w, const Char *start, const Char *end) { + if (start != end) + w << BasicStringRef(start, internal::to_unsigned(end - start)); +} + +template +class format_context_base { + private: + const Char *ptr_; + basic_format_args args_; int next_arg_index_; + protected: + format_context_base(const Char *format_str, basic_format_args args) + : ptr_(format_str), args_(args), next_arg_index_(0) {} + ~format_context_base() {} + + basic_format_args 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(arg.pointer); + case format_arg::NAMED_ARG: + arg = *static_cast(arg.pointer); break; default: /*nothing*/; @@ -2104,24 +2120,19 @@ private: return arg; } - protected: - FormatterBase(basic_format_args args) - : args_(args), next_arg_index_(0) {} - - const basic_format_args &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 @@ private: next_arg_index_ = -1; return true; } -}; -template -inline void write(BasicWriter &w, const Char *start, const Char *end) { - if (start != end) - w << BasicStringRef(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 @@ inline void write(BasicWriter &w, const Char *start, const Char *end) { template class BasicArgFormatter : public internal::ArgFormatterBase { private: - basic_formatter &formatter_; - const Char *format_; + basic_format_context &ctx_; public: /** @@ -2173,15 +2181,13 @@ class BasicArgFormatter : public internal::ArgFormatterBase { to the part of the format string being parsed for custom argument types. \endrst */ - BasicArgFormatter(BasicWriter &writer, - basic_formatter &formatter, - FormatSpec &spec, const Char *fmt) - : internal::ArgFormatterBase(writer, spec), - formatter_(formatter), format_(fmt) {} + BasicArgFormatter(BasicWriter &writer, basic_format_context &ctx, + FormatSpec &spec) + : internal::ArgFormatterBase(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 @@ template class ArgFormatter : public BasicArgFormatter, Char> { public: /** Constructs an argument formatter object. */ - ArgFormatter(BasicWriter &writer, basic_formatter &formatter, - FormatSpec &spec, const Char *fmt) - : BasicArgFormatter, Char>(writer, formatter, spec, fmt) {} + ArgFormatter(BasicWriter &writer, basic_format_context &ctx, + FormatSpec &spec) + : BasicArgFormatter, Char>(writer, ctx, spec) {} }; -/** This template formats data and writes the output to a writer. */ -template -class basic_formatter : - private internal::FormatterBase> { - public: - /** The character type for the output. */ - typedef Char char_type; - +template +class basic_format_context : + public internal::format_context_base> { private: internal::ArgMap map_; - FMT_DISALLOW_COPY_AND_ASSIGN(basic_formatter); + FMT_DISALLOW_COPY_AND_ASSIGN(basic_format_context); + + typedef internal::format_context_base Base; - typedef internal::FormatterBase Base; using Base::get_arg; // Checks if manual indexing is used and returns the argument with // specified name. - internal::Arg get_arg(BasicStringRef arg_name, const char *&error); + format_arg get_arg(BasicStringRef 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 args) : Base(args) {} + basic_format_context(const Char *format_str, + basic_format_args 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 &writer, const Char *&format_str, - const internal::Arg &arg); + using Base::ptr; }; /** @@ -2269,7 +2271,7 @@ class SystemError : public internal::RuntimeError { */ template SystemError(int error_code, CStringRef message, const Args & ... args) { - init(error_code, message, make_format_args>(args...)); + init(error_code, message, make_format_args(args...)); } ~SystemError() throw(); @@ -2464,10 +2466,7 @@ class BasicWriter { } void vwrite(BasicCStringRef format, - basic_format_args> args) { - vformat(*this, format, args); - } - + basic_format_args> args); /** \rst Writes formatted data. @@ -2495,7 +2494,7 @@ class BasicWriter { */ template void write(BasicCStringRef format, const Args & ... args) { - vwrite(format, make_format_args>(args...)); + vwrite(format, make_format_args>(args...)); } BasicWriter &operator<<(int value) { @@ -3123,7 +3122,7 @@ class WindowsError : public SystemError { */ template WindowsError(int error_code, CStringRef message, const Args & ... args) { - init(error_code, message, make_format_args>(args...)); + init(error_code, message, make_format_args(args...)); } }; @@ -3147,8 +3146,7 @@ FMT_API void vprint_colored(Color c, CStringRef format, format_args args); template inline void print_colored(Color c, CStringRef format_str, const Args & ... args) { - vprint_colored(c, format_str, - make_format_args>(args...)); + vprint_colored(c, format_str, make_format_args(args...)); } inline std::string vformat(CStringRef format_str, format_args args) { @@ -3168,7 +3166,7 @@ inline std::string vformat(CStringRef format_str, format_args args) { */ template inline std::string format(CStringRef format_str, const Args & ... args) { - return vformat(format_str, make_format_args>(args...)); + return vformat(format_str, make_format_args(args...)); } inline std::wstring vformat(WCStringRef format_str, wformat_args args) { @@ -3179,7 +3177,7 @@ inline std::wstring vformat(WCStringRef format_str, wformat_args args) { template inline std::wstring format(WCStringRef format_str, const Args & ... args) { - auto vargs = make_format_args>(args...); + auto vargs = make_format_args(args...); return vformat(format_str, vargs); } @@ -3196,7 +3194,7 @@ FMT_API void vprint(std::FILE *f, CStringRef format_str, format_args args); */ template inline void print(std::FILE *f, CStringRef format_str, const Args & ... args) { - vprint(f, format_str, make_format_args>(args...)); + vprint(f, format_str, make_format_args(args...)); } FMT_API void vprint(CStringRef format_str, format_args args); @@ -3212,7 +3210,7 @@ FMT_API void vprint(CStringRef format_str, format_args args); */ template inline void print(CStringRef format_str, const Args & ... args) { - vprint(format_str, make_format_args>(args...)); + vprint(format_str, make_format_args(args...)); } /** @@ -3405,57 +3403,55 @@ void check_sign(const Char *&s, const Arg &arg) { } } // namespace internal -template -inline internal::Arg basic_formatter::get_arg( - BasicStringRef arg_name, const char *&error) { +template +inline format_arg basic_format_context::get_arg( + BasicStringRef 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 -inline internal::Arg basic_formatter::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 +inline format_arg basic_format_context::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 -inline internal::Arg basic_formatter::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(start, s - start), error); + format_arg arg = get_arg(BasicStringRef(start, s - start), error); if (error) FMT_THROW(format_error(error)); return arg; } -template -const Char *basic_formatter::format( - BasicWriter &writer, const Char *&format_str, const internal::Arg &arg) { +// Formats a single argument. +template +void format_arg(BasicWriter &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 @@ const Char *basic_formatter::format( 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 @@ const Char *basic_formatter::format( 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 @@ const Char *basic_formatter::format( spec.type_ = static_cast(*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 +template void vformat(BasicWriter &writer, BasicCStringRef format_str, - basic_format_args> args) { - basic_formatter formatter(args); - const Char *s = format_str.c_str(); + basic_format_args args) { + basic_format_context ctx(format_str.c_str(), args); + const Char *&s = ctx.ptr(); const Char *start = s; while (*s) { Char c = *s++; @@ -3634,12 +3627,19 @@ void vformat(BasicWriter &writer, BasicCStringRef format_str, 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(writer, ctx.parse_arg_id(), ctx); + assert(*s == '}'); + start = ++s; } internal::write(writer, start, s); } + +template +inline void BasicWriter::vwrite( + BasicCStringRef format, + basic_format_args> args) { + vformat>(*this, format, args); +} } // namespace fmt #if FMT_USE_USER_DEFINED_LITERALS diff --git a/fmt/ostream.h b/fmt/ostream.h index 6173e688..feafc3b4 100644 --- a/fmt/ostream.h +++ b/fmt/ostream.h @@ -82,14 +82,13 @@ BasicStringRef format_value( } // namespace internal // Formats a value. -template +template void format_value(BasicWriter &w, const T &value, - basic_formatter &f, - const Char *&format_str) { + basic_format_context &ctx) { internal::MemoryBuffer buffer; auto str = internal::format_value(buffer, value); - typedef internal::MakeArg< basic_formatter > MakeArg; - format_str = f.format(w, format_str, MakeArg(str)); + typedef internal::MakeArg< basic_format_context > MakeArg; + format_arg< ArgFormatter >(w, MakeArg(str), ctx); } FMT_API void vprint(std::ostream &os, CStringRef format_str, format_args args); @@ -106,7 +105,7 @@ FMT_API void vprint(std::ostream &os, CStringRef format_str, format_args args); template inline void print(std::ostream &os, CStringRef format_str, const Args & ... args) { - vprint(os, format_str, make_format_args>(args...)); + vprint(os, format_str, make_format_args(args...)); } } // namespace fmt diff --git a/fmt/posix.h b/fmt/posix.h index 5fd17859..c6c6c13a 100644 --- a/fmt/posix.h +++ b/fmt/posix.h @@ -172,7 +172,7 @@ public: template inline void print(CStringRef format_str, const Args & ... args) { - vprint(format_str, make_format_args>(args...)); + vprint(format_str, make_format_args(args...)); } }; diff --git a/fmt/printf.h b/fmt/printf.h index 7d171255..42728b78 100644 --- a/fmt/printf.h +++ b/fmt/printf.h @@ -262,11 +262,10 @@ class BasicPrintfArgFormatter : public internal::ArgFormatterBase { /** Formats an argument of a custom (user-defined) type. */ void visit_custom(internal::Arg::CustomValue c) { - typedef basic_formatter Formatter; - Formatter formatter((basic_format_args())); - 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 ctx(format_str, args); + c.format(&this->writer(), c.value, &ctx); } }; @@ -283,14 +282,15 @@ class PrintfArgFormatter /** This template formats data and writes the output to a writer. */ template > -class PrintfFormatter : - private internal::FormatterBase> { +class printf_context : + private internal::format_context_base< + Char, printf_context> { public: /** The character type for the output. */ typedef Char char_type; private: - typedef internal::FormatterBase Base; + typedef internal::format_context_base Base; void parse_flags(FormatSpec &spec, const Char *&s); @@ -306,21 +306,21 @@ class PrintfFormatter : 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 args) - : Base(args) {} - + explicit printf_context(BasicCStringRef format_str, + basic_format_args args) + : Base(format_str.c_str(), args) {} + /** Formats stored arguments and writes the output to the writer. */ - FMT_API void format(BasicWriter &writer, - BasicCStringRef format_str); + FMT_API void format(BasicWriter &writer); }; template -void PrintfFormatter::parse_flags(FormatSpec &spec, const Char *&s) { +void printf_context::parse_flags(FormatSpec &spec, const Char *&s) { for (;;) { switch (*s++) { case '-': @@ -346,8 +346,8 @@ void PrintfFormatter::parse_flags(FormatSpec &spec, const Char *&s) { } template -internal::Arg PrintfFormatter::get_arg(const Char *s, - unsigned arg_index) { +internal::Arg printf_context::get_arg(const Char *s, + unsigned arg_index) { (void)s; const char *error = 0; internal::Arg arg = arg_index == std::numeric_limits::max() ? @@ -358,7 +358,7 @@ internal::Arg PrintfFormatter::get_arg(const Char *s, } template -unsigned PrintfFormatter::parse_header( +unsigned printf_context::parse_header( const Char *&s, FormatSpec &spec) { unsigned arg_index = std::numeric_limits::max(); Char c = *s; @@ -392,9 +392,8 @@ unsigned PrintfFormatter::parse_header( } template -void PrintfFormatter::format(BasicWriter &writer, - BasicCStringRef format_str) { - const Char *start = format_str.c_str(); +void printf_context::format(BasicWriter &writer) { + const Char *start = this->ptr(); const Char *s = start; while (*s) { Char c = *s++; @@ -495,19 +494,19 @@ void PrintfFormatter::format(BasicWriter &writer, // Formats a value. template void format_value(BasicWriter &w, const T &value, - PrintfFormatter &f, const Char *&) { + printf_context& ctx) { internal::MemoryBuffer buffer; w << internal::format_value(buffer, value); } template void printf(BasicWriter &w, BasicCStringRef format, - basic_format_args> args) { - PrintfFormatter(args).format(w, format); + basic_format_args> args) { + printf_context(format, args).format(w); } inline std::string vsprintf(CStringRef format, - basic_format_args> args) { + basic_format_args> args) { MemoryWriter w; printf(w, format, args); return w.str(); @@ -524,11 +523,11 @@ inline std::string vsprintf(CStringRef format, */ template inline std::string sprintf(CStringRef format_str, const Args & ... args) { - return vsprintf(format_str, make_format_args>(args...)); + return vsprintf(format_str, make_format_args>(args...)); } inline std::wstring vsprintf(WCStringRef format, - basic_format_args> args) { + basic_format_args> args) { WMemoryWriter w; printf(w, format, args); return w.str(); @@ -536,12 +535,12 @@ inline std::wstring vsprintf(WCStringRef format, template inline std::wstring sprintf(WCStringRef format_str, const Args & ... args) { - auto vargs = make_format_args>(args...); + auto vargs = make_format_args>(args...); return vsprintf(format_str, vargs); } FMT_API int vfprintf(std::FILE *f, CStringRef format, - basic_format_args> args); + basic_format_args> args); /** \rst @@ -554,12 +553,12 @@ FMT_API int vfprintf(std::FILE *f, CStringRef format, */ template inline int fprintf(std::FILE *f, CStringRef format_str, const Args & ... args) { - auto vargs = make_format_args>(args...); + auto vargs = make_format_args>(args...); return vfprintf(f, format_str, vargs); } inline int vprintf(CStringRef format, - basic_format_args> args) { + basic_format_args> args) { return vfprintf(stdout, format, args); } @@ -574,11 +573,11 @@ inline int vprintf(CStringRef format, */ template inline int printf(CStringRef format_str, const Args & ... args) { - return vprintf(format_str, make_format_args>(args...)); + return vprintf(format_str, make_format_args>(args...)); } inline int vfprintf(std::ostream &os, CStringRef format_str, - basic_format_args> args) { + basic_format_args> args) { MemoryWriter w; printf(w, format_str, args); internal::write(os, w); @@ -597,7 +596,7 @@ inline int vfprintf(std::ostream &os, CStringRef format_str, template inline int fprintf(std::ostream &os, CStringRef format_str, const Args & ... args) { - auto vargs = make_format_args>(args...); + auto vargs = make_format_args>(args...); return vfprintf(os, format_str, vargs); } } // namespace fmt diff --git a/fmt/time.h b/fmt/time.h index 5b40a93f..ad7ab9cf 100644 --- a/fmt/time.h +++ b/fmt/time.h @@ -15,19 +15,17 @@ namespace fmt { -template -void format_value(Writer &w, const std::tm &tm, - basic_formatter &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 format; - format.append(format_str, end + 1); + format.append(s, end + 1); format[format.size() - 1] = '\0'; Buffer &buffer = w.buffer(); std::size_t start = buffer.size(); @@ -48,7 +46,7 @@ void format_value(Writer &w, const std::tm &tm, 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 499e07a2..65888b28 100644 --- a/test/custom-formatter-test.cc +++ b/test/custom-formatter-test.cc @@ -17,10 +17,9 @@ using fmt::BasicPrintfArgFormatter; class CustomArgFormatter : public fmt::BasicArgFormatter { public: - CustomArgFormatter(fmt::Writer &w, - fmt::basic_formatter &f, - fmt::FormatSpec &s, const char *fmt) - : fmt::BasicArgFormatter(w, f, s, fmt) {} + CustomArgFormatter(fmt::Writer &w, fmt::basic_format_context &ctx, + fmt::FormatSpec &s) + : fmt::BasicArgFormatter(w, ctx, s) {} void visit_double(double value) { if (round(value * pow(10, spec().precision())) == 0) @@ -46,10 +45,7 @@ class CustomPrintfArgFormatter : } }; -typedef fmt::basic_formatter CustomFormatter; - -std::string custom_vformat(fmt::CStringRef format_str, - fmt::basic_format_args 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(writer, format_str, args); @@ -58,19 +54,19 @@ std::string custom_vformat(fmt::CStringRef format_str, template std::string custom_format(const char *format_str, const Args & ... args) { - auto va = fmt::make_format_args(args...); + auto va = fmt::make_format_args(args...); return custom_vformat(format_str, va); } -typedef fmt::PrintfFormatter +typedef fmt::printf_context CustomPrintfFormatter; std::string custom_vsprintf( const char* format_str, fmt::basic_format_args 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 4493d003..1e919b7e 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1355,8 +1355,7 @@ TEST(FormatterTest, FormatCStringRef) { EXPECT_EQ("test", format("{0}", CStringRef("test"))); } -void format_value(fmt::Writer &w, const Date &d, fmt::basic_formatter &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 @@ TEST(FormatterTest, FormatCustom) { class Answer {}; template -void format_value(BasicWriter &w, Answer, fmt::basic_formatter &f, - const Char *) { +void format_value(BasicWriter &w, Answer, fmt::format_context &) { w << "42"; } @@ -1561,7 +1559,7 @@ std::string vformat_message(int id, const char *format, fmt::format_args args) { template std::string format_message(int id, const char *format, const Args & ... args) { - auto va = fmt::make_format_args>(args...); + auto va = fmt::make_format_args(args...); return vformat_message(id, format, va); } @@ -1626,9 +1624,8 @@ class MockArgFormatter : public: typedef fmt::internal::ArgFormatterBase Base; - MockArgFormatter(fmt::Writer &w, - fmt::basic_formatter &f, - fmt::FormatSpec &s, const char *) + MockArgFormatter(fmt::Writer &w, fmt::format_context &ctx, + fmt::FormatSpec &s) : fmt::internal::ArgFormatterBase(w, s) { EXPECT_CALL(*this, visit_int(42)); } @@ -1636,17 +1633,14 @@ class MockArgFormatter : MOCK_METHOD1(visit_int, void (int value)); }; -typedef fmt::basic_formatter CustomFormatter; - -void custom_vformat(fmt::CStringRef format_str, - fmt::basic_format_args args) { +void custom_vformat(fmt::CStringRef format_str, fmt::format_args args) { fmt::MemoryWriter writer; - vformat(writer, format_str, args); + fmt::vformat(writer, format_str, args); } template void custom_format(const char *format_str, const Args & ... args) { - auto va = fmt::make_format_args(args...); + auto va = fmt::make_format_args(args...); return custom_vformat(format_str, va); } diff --git a/test/ostream-test.cc b/test/ostream-test.cc index 17c9d079..2d1ace63 100644 --- a/test/ostream-test.cc +++ b/test/ostream-test.cc @@ -59,19 +59,17 @@ TEST(OStreamTest, Enum) { } struct TestArgFormatter : fmt::BasicArgFormatter { - TestArgFormatter(fmt::Writer &w, - fmt::basic_formatter &f, - fmt::FormatSpec &s, const char *fmt) - : fmt::BasicArgFormatter(w, f, s, fmt) {} + TestArgFormatter(fmt::Writer &w, fmt::format_context &ctx, + fmt::FormatSpec &s) + : fmt::BasicArgFormatter(w, ctx, s) {} }; TEST(OStreamTest, CustomArg) { fmt::MemoryWriter writer; - typedef fmt::basic_formatter Formatter; - Formatter formatter((fmt::basic_format_args())); + fmt::format_context ctx("}", fmt::format_args()); fmt::FormatSpec spec; - TestArgFormatter af(writer, formatter, spec, "}"); - af.visit(fmt::internal::MakeArg(TestEnum())); + TestArgFormatter af(writer, ctx, spec); + af.visit(fmt::internal::MakeArg(TestEnum())); EXPECT_EQ("TestEnum", writer.str()); } diff --git a/test/util-test.cc b/test/util-test.cc index 87ad25e7..b553427c 100644 --- a/test/util-test.cc +++ b/test/util-test.cc @@ -65,13 +65,13 @@ struct Test {}; template void format_value(fmt::BasicWriter &w, Test, - fmt::basic_formatter &f, const Char *) { + fmt::basic_format_context &) { w << "test"; } template Arg make_arg(const T &value) { - typedef fmt::internal::MakeValue< fmt::basic_formatter > MakeValue; + typedef fmt::internal::MakeValue< fmt::basic_format_context > MakeValue; Arg arg = MakeValue(value); arg.type = fmt::internal::type(); return arg; @@ -567,9 +567,8 @@ TEST(ArgTest, MakeArg) { EXPECT_EQ(fmt::internal::Arg::CUSTOM, arg.type); EXPECT_EQ(&t, arg.custom.value); fmt::MemoryWriter w; - fmt::basic_formatter 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 @@ TEST(UtilTest, FormatArgs) { 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(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 {