From bf0f107564743528215d7ba741ab6e25ac321260 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 28 Jan 2017 13:17:47 +0000 Subject: [PATCH] Parameterize format_specs on character type --- fmt/format.h | 29 ++++++++++++++++++++++------- fmt/printf.h | 8 +++++++- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/fmt/format.h b/fmt/format.h index d4009910..ebf36025 100644 --- a/fmt/format.h +++ b/fmt/format.h @@ -1739,10 +1739,13 @@ struct AlignTypeSpec : AlignSpec { }; // Format specifiers. -class format_specs : public AlignSpec { +template +class basic_format_specs : public AlignSpec { private: - template - void set(fill_spec fill) { + template + typename std::enable_if::value || + std::is_same::value, void>::type + set(fill_spec fill) { fill_ = fill.value(); } @@ -1765,11 +1768,11 @@ class format_specs : public AlignSpec { int precision_; char type_; - format_specs(unsigned width = 0, char type = 0, wchar_t fill = ' ') + basic_format_specs(unsigned width = 0, char type = 0, wchar_t fill = ' ') : AlignSpec(width, fill), flags_(0), precision_(-1), type_(type) {} template - explicit format_specs(FormatSpecs... specs) + explicit basic_format_specs(FormatSpecs... specs) : AlignSpec(0, ' '), flags_(0), precision_(-1), type_(0){ set(specs...); } @@ -1779,6 +1782,8 @@ class format_specs : public AlignSpec { char type() const { return type_; } }; +typedef basic_format_specs format_specs; + namespace internal { template @@ -1853,6 +1858,9 @@ void ArgMap::init(const basic_format_args &args) { template class ArgFormatterBase { + public: + typedef basic_format_specs format_specs; + private: basic_writer &writer_; format_specs &spec_; @@ -2035,7 +2043,11 @@ class ArgFormatter : public internal::ArgFormatterBase { private: basic_format_context &ctx_; + typedef internal::ArgFormatterBase Base; + public: + typedef typename Base::format_specs format_specs; + /** \rst Constructs an argument formatter object. @@ -2186,6 +2198,9 @@ constexpr named_format_spec width; */ template class basic_writer { + public: + typedef basic_format_specs format_specs; + private: // Output buffer. Buffer &buffer_; @@ -2461,7 +2476,7 @@ typename basic_writer::CharPtr basic_writer::write_str( template template void basic_writer::write_str( - BasicStringRef s, const format_specs &spec) { + BasicStringRef s, const basic_writer::format_specs &spec) { // Check if StrChar is convertible to Char. internal::CharTraits::convert(StrChar()); if (spec.type_ && spec.type_ != 's') @@ -3366,7 +3381,7 @@ template void do_format_arg(basic_writer &writer, basic_format_arg arg, Context &ctx) { const Char *&s = ctx.ptr(); - format_specs spec; + basic_format_specs spec; if (*s == ':') { if (visit(internal::CustomFormatter(writer, ctx), arg)) return; diff --git a/fmt/printf.h b/fmt/printf.h index c2694e43..3316887a 100644 --- a/fmt/printf.h +++ b/fmt/printf.h @@ -168,8 +168,11 @@ class CharConverter { // Checks if an argument is a valid printf width specifier and sets // left alignment if it is negative. +template class PrintfWidthHandler { private: + typedef basic_format_specs format_specs; + format_specs &spec_; FMT_DISALLOW_COPY_AND_ASSIGN(PrintfWidthHandler); @@ -217,6 +220,8 @@ class PrintfArgFormatter : public internal::ArgFormatterBase { typedef internal::ArgFormatterBase Base; public: + typedef typename Base::format_specs format_specs; + /** \rst Constructs an argument formatter object. @@ -301,6 +306,7 @@ class printf_context : private: typedef internal::format_context_base Base; typedef typename Base::format_arg format_arg; + typedef basic_format_specs format_specs; void parse_flags(format_specs &spec, const Char *&s); @@ -396,7 +402,7 @@ unsigned printf_context::parse_header( spec.width_ = internal::parse_nonnegative_int(s); } else if (*s == '*') { ++s; - spec.width_ = visit(internal::PrintfWidthHandler(spec), get_arg(s)); + spec.width_ = visit(internal::PrintfWidthHandler(spec), get_arg(s)); } return arg_index; }