From d4ddaaf2b1679dd3d159584cc7b7684271e07cee Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Wed, 20 Jul 2016 08:09:14 -0700 Subject: [PATCH] Make PrintfFormatter public (#335, #360) --- doc/api.rst | 12 +++++++--- fmt/format.cc | 4 ++-- fmt/printf.h | 45 ++++++++++++++++++++++------------- test/custom-formatter-test.cc | 2 +- 4 files changed, 41 insertions(+), 22 deletions(-) diff --git a/doc/api.rst b/doc/api.rst index 2cde812b..58c3c77e 100644 --- a/doc/api.rst +++ b/doc/api.rst @@ -125,12 +125,15 @@ custom argument formatter class:: .. doxygenclass:: fmt::ArgFormatter :members: -Printf formatting functions ---------------------------- +Printf formatting +----------------- +The header ``fmt/printf.h`` provides ``printf``-like formatting functionality. The following functions use `printf format string syntax `_ with -a POSIX extension for positional arguments. +the POSIX extension for positional arguments. Unlike their standard +counterparts, the ``fmt`` functions are type-safe and throw an exception if an +argument type doesn't match its format specification. .. doxygenfunction:: printf(CStringRef, ArgList) @@ -138,6 +141,9 @@ a POSIX extension for positional arguments. .. doxygenfunction:: sprintf(CStringRef, ArgList) +.. doxygenclass:: fmt::PrintfFormatter + :members: + Write API ========= diff --git a/fmt/format.cc b/fmt/format.cc index a00a8df6..81d09cfe 100644 --- a/fmt/format.cc +++ b/fmt/format.cc @@ -521,7 +521,7 @@ template void internal::FixedBuffer::grow(std::size_t); template void internal::ArgMap::init(const ArgList &args); -template void internal::PrintfFormatter::format( +template void PrintfFormatter::format( BasicWriter &writer, CStringRef format); template int internal::CharTraits::format_float( @@ -538,7 +538,7 @@ template void internal::FixedBuffer::grow(std::size_t); template void internal::ArgMap::init(const ArgList &args); -template void internal::PrintfFormatter::format( +template void PrintfFormatter::format( BasicWriter &writer, WCStringRef format); template int internal::CharTraits::format_float( diff --git a/fmt/printf.h b/fmt/printf.h index d06aca54..e50f1e4d 100644 --- a/fmt/printf.h +++ b/fmt/printf.h @@ -248,23 +248,34 @@ class PrintfArgFormatter PrintfArgFormatter(BasicWriter &w, FormatSpec &s) : BasicPrintfArgFormatter, Char>(w, s) {} }; +} // namespace internal -// A printf formatter. -template > -class PrintfFormatter : private FormatterBase { +/** This template formats data and writes the output to a writer. */ +template > +class PrintfFormatter : private internal::FormatterBase { private: void parse_flags(FormatSpec &spec, const Char *&s); // Returns the argument with specified index or, if arg_index is equal // to the maximum unsigned value, the next argument. - Arg get_arg(const Char *s, + internal::Arg get_arg( + const Char *s, unsigned arg_index = (std::numeric_limits::max)()); // Parses argument index, flags and width and returns the argument index. unsigned parse_header(const Char *&s, FormatSpec &spec); public: + /** + \rst + Constructs a ``PrintfFormatter`` object. References to the arguments + are stored in the formatter object so make sure they have appropriate + lifetimes. + \endrst + */ explicit PrintfFormatter(const ArgList &args) : FormatterBase(args) {} + FMT_API void format(BasicWriter &writer, BasicCStringRef format_str); }; @@ -296,10 +307,11 @@ void PrintfFormatter::parse_flags(FormatSpec &spec, const Char *&s) { } template -Arg PrintfFormatter::get_arg(const Char *s, unsigned arg_index) { +internal::Arg PrintfFormatter::get_arg(const Char *s, + unsigned arg_index) { (void)s; const char *error = 0; - Arg arg = arg_index == std::numeric_limits::max() ? + internal::Arg arg = arg_index == std::numeric_limits::max() ? next_arg(error) : FormatterBase::get_arg(arg_index - 1, error); if (error) FMT_THROW(FormatError(!*s ? "invalid format string" : error)); @@ -314,7 +326,7 @@ unsigned PrintfFormatter::parse_header( if (c >= '0' && c <= '9') { // Parse an argument index (if followed by '$') or a width possibly // preceded with '0' flag(s). - unsigned value = parse_nonnegative_int(s); + unsigned value = internal::parse_nonnegative_int(s); if (*s == '$') { // value is an argument index ++s; arg_index = value; @@ -332,10 +344,10 @@ unsigned PrintfFormatter::parse_header( parse_flags(spec, s); // Parse width. if (*s >= '0' && *s <= '9') { - spec.width_ = parse_nonnegative_int(s); + spec.width_ = internal::parse_nonnegative_int(s); } else if (*s == '*') { ++s; - spec.width_ = WidthHandler(spec).visit(get_arg(s)); + spec.width_ = internal::WidthHandler(spec).visit(get_arg(s)); } return arg_index; } @@ -365,16 +377,17 @@ void PrintfFormatter::format( if (*s == '.') { ++s; if ('0' <= *s && *s <= '9') { - spec.precision_ = static_cast(parse_nonnegative_int(s)); + spec.precision_ = static_cast(internal::parse_nonnegative_int(s)); } else if (*s == '*') { ++s; - spec.precision_ = PrecisionHandler().visit(get_arg(s)); + spec.precision_ = internal::PrecisionHandler().visit(get_arg(s)); } } + using internal::Arg; Arg arg = get_arg(s, arg_index); - if (spec.flag(HASH_FLAG) && IsZeroInt().visit(arg)) - spec.flags_ &= ~to_unsigned(HASH_FLAG); + if (spec.flag(HASH_FLAG) && internal::IsZeroInt().visit(arg)) + spec.flags_ &= ~internal::to_unsigned(HASH_FLAG); if (spec.fill_ == '0') { if (arg.type <= Arg::LAST_NUMERIC_TYPE) spec.align_ = ALIGN_NUMERIC; @@ -383,6 +396,7 @@ void PrintfFormatter::format( } // Parse length and convert the argument to the required type. + using internal::ArgConverter; switch (*s++) { case 'h': if (*s == 'h') @@ -426,7 +440,7 @@ void PrintfFormatter::format( break; case 'c': // TODO: handle wchar_t - CharConverter(arg).visit(arg); + internal::CharConverter(arg).visit(arg); break; } } @@ -438,11 +452,10 @@ void PrintfFormatter::format( } write(writer, start, s); } -} // namespace internal template void printf(BasicWriter &w, BasicCStringRef format, ArgList args) { - internal::PrintfFormatter(args).format(w, format); + PrintfFormatter(args).format(w, format); } /** diff --git a/test/custom-formatter-test.cc b/test/custom-formatter-test.cc index 9adf8a04..443721eb 100644 --- a/test/custom-formatter-test.cc +++ b/test/custom-formatter-test.cc @@ -53,7 +53,7 @@ FMT_VARIADIC(std::string, custom_format, const char *) std::string custom_sprintf(const char* fstr, fmt::ArgList args){ fmt::MemoryWriter writer; - fmt::internal::PrintfFormatter< char, CustomPAF > pfer( args); + fmt::PrintfFormatter pfer( args); pfer.format(writer, fstr); return writer.str(); }