From 89bf932c2ee362ebab66de6982c508861a02dcd9 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 6 Jul 2019 17:57:57 -0700 Subject: [PATCH] Refactor format_specs for #1109 and #940 Refactor `format_specs` and related APIs to support variable-width fill (#1109), improve naming consistency, remove legacy setters (#940), and optimize layout. --- include/fmt/chrono.h | 10 +- include/fmt/format-inl.h | 2 +- include/fmt/format.h | 214 +++++++++++++++++++++------------------ include/fmt/prepare.h | 21 +--- include/fmt/printf.h | 38 +++---- test/format | 2 +- test/format-test.cc | 46 ++++----- test/prepare-test.cc | 20 ++-- 8 files changed, 177 insertions(+), 176 deletions(-) diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index 848d3722a03b6..95a6f46f18592 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -715,7 +715,7 @@ struct chrono_formatter { template struct formatter, Char> { private: - align_spec spec; + basic_format_specs spec; int precision; typedef internal::arg_ref arg_ref_type; arg_ref_type width_ref; @@ -744,9 +744,9 @@ struct formatter, Char> { } void on_error(const char* msg) { FMT_THROW(format_error(msg)); } - void on_fill(Char fill) { f.spec.fill_ = fill; } - void on_align(alignment align) { f.spec.align_ = align; } - void on_width(unsigned width) { f.spec.width_ = width; } + void on_fill(Char fill) { f.spec.fill[0] = fill; } + void on_align(align_t align) { f.spec.align = align; } + void on_width(unsigned width) { f.spec.width = width; } void on_precision(unsigned precision) { f.precision = precision; } void end_precision() {} @@ -804,7 +804,7 @@ struct formatter, Char> { using range = internal::output_range; internal::basic_writer w(range(ctx.out())); internal::handle_dynamic_spec( - spec.width_, width_ref, ctx, format_str.begin()); + spec.width, width_ref, ctx, format_str.begin()); internal::handle_dynamic_spec( precision, precision_ref, ctx, format_str.begin()); if (begin == end || *begin == '}') { diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index c1120e4c1a86d..622a03e35d22c 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -763,7 +763,7 @@ char* sprintf_format(Double value, internal::buffer& buf, char format[max_format_size]; char* format_ptr = format; *format_ptr++ = '%'; - if (spec.has(HASH_FLAG) || !spec.type) *format_ptr++ = '#'; + if (spec.alt || !spec.type) *format_ptr++ = '#'; if (spec.precision >= 0) { *format_ptr++ = '.'; *format_ptr++ = '*'; diff --git a/include/fmt/format.h b/include/fmt/format.h index 1d58823a8fc66..5d269e6403419 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -900,51 +900,54 @@ FMT_API void format_windows_error(fmt::internal::buffer& out, template struct null {}; } // namespace internal -enum alignment { - ALIGN_DEFAULT, - ALIGN_LEFT, - ALIGN_RIGHT, - ALIGN_CENTER, - ALIGN_NUMERIC -}; +// We cannot use enum classes as bit fields because of a gcc bug +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414. +namespace align { +enum type { none, left, right, center, numeric }; +} +using align_t = align::type; + +namespace sign { +enum type { none, minus, plus, space }; +} +using sign_t = sign::type; -// Flags. -enum { SIGN_FLAG = 1, PLUS_FLAG = 2, MINUS_FLAG = 4, HASH_FLAG = 8 }; - -// An alignment specifier. -struct align_spec { - unsigned width_; - // Fill is always wchar_t and cast to char if necessary to avoid having - // two specialization of align_spec and its subclasses. - wchar_t fill_; - alignment align_; - - FMT_CONSTEXPR align_spec() : width_(0), fill_(' '), align_(ALIGN_DEFAULT) {} - FMT_CONSTEXPR unsigned width() const { return width_; } - FMT_CONSTEXPR wchar_t fill() const { return fill_; } - FMT_CONSTEXPR alignment align() const { return align_; } +// Format specifiers for built-in and string types. +template struct basic_format_specs { + int width; + int precision; + char type; + align_t align : 3; + sign_t sign : 2; + bool alt : 1; // Alternate form ('#'). + unsigned : 2; + Char fill[6] = {Char(' ')}; + + FMT_CONSTEXPR basic_format_specs() + : width(0), + precision(-1), + type(0), + align(align::none), + sign(sign::none), + alt(false) {} }; +using format_specs = basic_format_specs; + +namespace internal { + struct core_format_specs { int precision; - uint_least8_t flags; char type; + bool alt : 1; - FMT_CONSTEXPR core_format_specs() : precision(-1), flags(0), type(0) {} - FMT_CONSTEXPR bool has(unsigned f) const { return (flags & f) != 0; } - FMT_CONSTEXPR bool has_precision() const { return precision != -1; } -}; + template + constexpr core_format_specs(basic_format_specs specs) + : precision(specs.precision), type(specs.type), alt(specs.alt) {} -// Format specifiers. -template -struct basic_format_specs : align_spec, core_format_specs { - FMT_CONSTEXPR basic_format_specs() {} + constexpr bool has_precision() const { return precision >= 0; } }; -typedef basic_format_specs format_specs; - -namespace internal { - namespace grisu_options { enum { fixed = 1, grisu3 = 2 }; } @@ -1117,7 +1120,7 @@ FMT_CONSTEXPR void handle_char_specs(const basic_format_specs* specs, Handler&& handler) { if (!specs) return handler.on_char(); if (specs->type && specs->type != 'c') return handler.on_int(); - if (specs->align() == ALIGN_NUMERIC || specs->flags != 0) + if (specs->align == align::numeric || specs->sign != sign::none || specs->alt) handler.on_error("invalid format specifier for char"); handler.on_char(); } @@ -1262,20 +1265,20 @@ template class basic_writer { template void write_int(int num_digits, string_view prefix, const Spec& spec, F f) { std::size_t size = prefix.size() + internal::to_unsigned(num_digits); - char_type fill = static_cast(spec.fill()); + char_type fill = spec.fill[0]; std::size_t padding = 0; - if (spec.align() == ALIGN_NUMERIC) { - if (spec.width() > size) { - padding = spec.width() - size; - size = spec.width(); + if (spec.align == align::numeric) { + if (internal::to_unsigned(spec.width) > size) { + padding = spec.width - size; + size = spec.width; } } else if (spec.precision > num_digits) { size = prefix.size() + internal::to_unsigned(spec.precision); padding = internal::to_unsigned(spec.precision - num_digits); fill = static_cast('0'); } - align_spec as = spec; - if (spec.align() == ALIGN_DEFAULT) as.align_ = ALIGN_RIGHT; + format_specs as = spec; + if (spec.align == align::none) as.align = align::right; write_padded(as, padded_int_writer{size, prefix, fill, padding, f}); } @@ -1312,8 +1315,8 @@ template class basic_writer { prefix[0] = '-'; ++prefix_size; abs_value = 0 - abs_value; - } else if (spec.has(SIGN_FLAG)) { - prefix[0] = spec.has(PLUS_FLAG) ? '+' : ' '; + } else if (spec.sign != sign::none && spec.sign != sign::minus) { + prefix[0] = spec.sign == sign::plus ? '+' : ' '; ++prefix_size; } } @@ -1344,9 +1347,9 @@ template class basic_writer { }; void on_hex() { - if (spec.has(HASH_FLAG)) { + if (spec.alt) { prefix[prefix_size++] = '0'; - prefix[prefix_size++] = static_cast(spec.type); + prefix[prefix_size++] = spec.type; } int num_digits = internal::count_digits<4>(abs_value); writer.write_int(num_digits, get_prefix(), spec, @@ -1363,7 +1366,7 @@ template class basic_writer { }; void on_bin() { - if (spec.has(HASH_FLAG)) { + if (spec.alt) { prefix[prefix_size++] = '0'; prefix[prefix_size++] = static_cast(spec.type); } @@ -1374,7 +1377,7 @@ template class basic_writer { void on_oct() { int num_digits = internal::count_digits<3>(abs_value); - if (spec.has(HASH_FLAG) && spec.precision <= num_digits) { + if (spec.alt && spec.precision <= num_digits) { // Octal prefix '0' is counted as a digit, so only add it if precision // is not greater than the number of digits. prefix[prefix_size++] = '0'; @@ -1538,18 +1541,18 @@ template class basic_writer { // Writes a value in the format // // where is written by f(it). - template void write_padded(const align_spec& spec, F&& f) { - unsigned width = spec.width(); // User-perceived width (in code points). - size_t size = f.size(); // The number of code units. + template void write_padded(const format_specs& spec, F&& f) { + unsigned width = spec.width; // User-perceived width (in code points). + size_t size = f.size(); // The number of code units. size_t num_code_points = width != 0 ? f.width() : size; if (width <= num_code_points) return f(reserve(size)); auto&& it = reserve(width + (size - num_code_points)); - char_type fill = static_cast(spec.fill()); + char_type fill = spec.fill[0]; std::size_t padding = width - num_code_points; - if (spec.align() == ALIGN_RIGHT) { + if (spec.align == align::right) { it = std::fill_n(it, padding, fill); f(it); - } else if (spec.align() == ALIGN_CENTER) { + } else if (spec.align == align::center) { std::size_t left_padding = padding / 2; it = std::fill_n(it, left_padding, fill); f(it); @@ -1584,7 +1587,7 @@ template class basic_writer { FMT_ENABLE_IF(std::is_integral::value)> void write(T value, FormatSpec spec, FormatSpecs... specs) { format_specs s(spec, specs...); - s.align_ = ALIGN_RIGHT; + s.align = align::right; write_int(value, s); } @@ -1635,7 +1638,7 @@ template class basic_writer { // Writes a formatted string. template - void write(const Char* s, std::size_t size, const align_spec& spec) { + void write(const Char* s, std::size_t size, const format_specs& spec) { write_padded(spec, str_writer{s, size}); } @@ -1650,12 +1653,12 @@ template class basic_writer { } template - void write_pointer(UIntPtr value, const align_spec* spec) { + void write_pointer(UIntPtr value, const format_specs* spec) { int num_digits = internal::count_digits<4>(value); auto pw = pointer_writer{value, num_digits}; if (!spec) return pw(reserve(num_digits + 2)); - align_spec as = *spec; - if (as.align() == ALIGN_DEFAULT) as.align_ = ALIGN_RIGHT; + format_specs as = *spec; + if (as.align == align::none) as.align = align::right; write_padded(as, pw); } }; @@ -1907,19 +1910,19 @@ template class specs_setter { FMT_CONSTEXPR specs_setter(const specs_setter& other) : specs_(other.specs_) {} - FMT_CONSTEXPR void on_align(alignment align) { specs_.align_ = align; } - FMT_CONSTEXPR void on_fill(Char fill) { specs_.fill_ = fill; } - FMT_CONSTEXPR void on_plus() { specs_.flags |= SIGN_FLAG | PLUS_FLAG; } - FMT_CONSTEXPR void on_minus() { specs_.flags |= MINUS_FLAG; } - FMT_CONSTEXPR void on_space() { specs_.flags |= SIGN_FLAG; } - FMT_CONSTEXPR void on_hash() { specs_.flags |= HASH_FLAG; } + FMT_CONSTEXPR void on_align(align_t align) { specs_.align = align; } + FMT_CONSTEXPR void on_fill(Char fill) { specs_.fill[0] = fill; } + FMT_CONSTEXPR void on_plus() { specs_.sign = sign::plus; } + FMT_CONSTEXPR void on_minus() { specs_.sign = sign::minus; } + FMT_CONSTEXPR void on_space() { specs_.sign = sign::space; } + FMT_CONSTEXPR void on_hash() { specs_.alt = true; } FMT_CONSTEXPR void on_zero() { - specs_.align_ = ALIGN_NUMERIC; - specs_.fill_ = '0'; + specs_.align = align::numeric; + specs_.fill[0] = Char('0'); } - FMT_CONSTEXPR void on_width(unsigned width) { specs_.width_ = width; } + FMT_CONSTEXPR void on_width(unsigned width) { specs_.width = width; } FMT_CONSTEXPR void on_precision(unsigned precision) { specs_.precision = static_cast(precision); } @@ -1971,8 +1974,8 @@ template class specs_checker : public Handler { FMT_CONSTEXPR specs_checker(const specs_checker& other) : Handler(other), checker_(*this, other.arg_type_) {} - FMT_CONSTEXPR void on_align(alignment align) { - if (align == ALIGN_NUMERIC) checker_.require_numeric_argument(); + FMT_CONSTEXPR void on_align(align_t align) { + if (align == align::numeric) checker_.require_numeric_argument(); Handler::on_align(align); } @@ -2039,7 +2042,7 @@ class specs_handler : public specs_setter { context_(ctx) {} template FMT_CONSTEXPR void on_dynamic_width(Id arg_id) { - set_dynamic_spec(this->specs_.width_, get_arg(arg_id), + set_dynamic_spec(this->specs_.width, get_arg(arg_id), context_.error_handler()); } @@ -2242,25 +2245,25 @@ template FMT_CONSTEXPR const Char* parse_align(const Char* begin, const Char* end, Handler&& handler) { FMT_ASSERT(begin != end, ""); - alignment align = ALIGN_DEFAULT; + auto align = align::none; int i = 0; if (begin + 1 != end) ++i; do { switch (static_cast(begin[i])) { case '<': - align = ALIGN_LEFT; + align = align::left; break; case '>': - align = ALIGN_RIGHT; + align = align::right; break; case '=': - align = ALIGN_NUMERIC; + align = align::numeric; break; case '^': - align = ALIGN_CENTER; + align = align::center; break; } - if (align != ALIGN_DEFAULT) { + if (align != align::none) { if (i > 0) { auto c = *begin; if (c == '{') @@ -2715,8 +2718,11 @@ void internal::basic_writer::write_double(T value, if (std::signbit(value)) { sign = '-'; value = -value; - } else if (spec.has(SIGN_FLAG)) { - sign = spec.has(PLUS_FLAG) ? '+' : ' '; + } else if (spec.sign != sign::none) { + if (spec.sign == sign::plus) + sign = '+'; + else if (spec.sign == sign::space) + sign = ' '; } if (!std::isfinite(value)) { @@ -2732,7 +2738,7 @@ void internal::basic_writer::write_double(T value, memory_buffer buffer; int exp = 0; - int precision = spec.has_precision() || !spec.type ? spec.precision : 6; + int precision = spec.precision >= 0 || !spec.type ? spec.precision : 6; unsigned options = handler.fixed ? internal::grisu_options::fixed : 0; bool use_grisu = USE_GRISU && (spec.type != 'a' && spec.type != 'A' && spec.type != 'e' && @@ -2747,17 +2753,17 @@ void internal::basic_writer::write_double(T value, buffer.push_back('%'); --exp; // Adjust decimal place position. } - align_spec as = spec; - if (spec.align() == ALIGN_NUMERIC) { + format_specs as = spec; + if (spec.align == align::numeric) { if (sign) { auto&& it = reserve(1); *it++ = static_cast(sign); sign = 0; - if (as.width_) --as.width_; + if (as.width) --as.width; } - as.align_ = ALIGN_RIGHT; - } else if (spec.align() == ALIGN_DEFAULT) { - as.align_ = ALIGN_RIGHT; + as.align = align::right; + } else if (spec.align == align::none) { + as.align = align::right; } char_type decimal_point = handler.use_locale ? internal::decimal_point(locale_) @@ -2766,8 +2772,8 @@ void internal::basic_writer::write_double(T value, auto params = internal::gen_digits_params(); params.fixed = handler.fixed; params.num_digits = precision; - params.trailing_zeros = (precision != 0 && (handler.fixed || !spec.type)) || - spec.has(HASH_FLAG); + params.trailing_zeros = + (precision != 0 && (handler.fixed || !spec.type)) || spec.alt; write_padded(as, grisu_writer(sign, buffer, exp, params, decimal_point)); } else { write_padded(as, @@ -2966,7 +2972,7 @@ struct formatter auto format(const T& val, FormatContext& ctx) -> decltype(ctx.out()) { internal::handle_dynamic_spec( - specs_.width_, specs_.width_ref, ctx, format_str_); + specs_.width, specs_.width_ref, ctx, format_str_); internal::handle_dynamic_spec( specs_.precision, specs_.precision_ref, ctx, format_str_); using range_type = @@ -3031,7 +3037,7 @@ struct formatter : formatter, Char> { template class dynamic_formatter { private: struct null_handler : internal::error_handler { - void on_align(alignment) {} + void on_align(align_t) {} void on_plus() {} void on_minus() {} void on_space() {} @@ -3053,16 +3059,22 @@ template class dynamic_formatter { internal::specs_checker checker( null_handler(), internal::mapped_type_constant::value); - checker.on_align(specs_.align()); - if (specs_.flags == 0) - ; // Do nothing. - else if (specs_.has(SIGN_FLAG)) - specs_.has(PLUS_FLAG) ? checker.on_plus() : checker.on_space(); - else if (specs_.has(MINUS_FLAG)) + checker.on_align(specs_.align); + switch (specs_.sign) { + case sign::none: + break; + case sign::plus: + checker.on_plus(); + break; + case sign::minus: checker.on_minus(); - else if (specs_.has(HASH_FLAG)) - checker.on_hash(); - if (specs_.precision != -1) checker.end_precision(); + break; + case sign::space: + checker.on_space(); + break; + } + if (specs_.alt) checker.on_hash(); + if (specs_.precision >= 0) checker.end_precision(); typedef internal::output_range range; @@ -3074,7 +3086,7 @@ template class dynamic_formatter { private: template void handle_specs(Context& ctx) { internal::handle_dynamic_spec( - specs_.width_, specs_.width_ref, ctx, format_str_); + specs_.width, specs_.width_ref, ctx, format_str_); internal::handle_dynamic_spec( specs_.precision, specs_.precision_ref, ctx, format_str_); } diff --git a/include/fmt/prepare.h b/include/fmt/prepare.h index 734184f869787..6183e7bdab087 100644 --- a/include/fmt/prepare.h +++ b/include/fmt/prepare.h @@ -293,7 +293,7 @@ class prepared_format { auto specs = value.spec.parsed_specs; handle_dynamic_spec( - specs.width_, specs.width_ref, ctx, format_view.begin()); + specs.width, specs.width_ref, ctx, format_view.begin()); handle_dynamic_spec( specs.precision, specs.precision_ref, ctx, format_view.begin()); @@ -330,21 +330,10 @@ class prepared_format { internal::type arg_type) const { internal::error_handler h; numeric_specs_checker checker(h, arg_type); - if (specs.align_ == ALIGN_NUMERIC) { - checker.require_numeric_argument(); - } - - if (specs.has(PLUS_FLAG | MINUS_FLAG | SIGN_FLAG)) { - checker.check_sign(); - } - - if (specs.has(HASH_FLAG)) { - checker.require_numeric_argument(); - } - - if (specs.has_precision()) { - checker.check_precision(); - } + if (specs.align == align::numeric) checker.require_numeric_argument(); + if (specs.sign != sign::none) checker.check_sign(); + if (specs.alt) checker.require_numeric_argument(); + if (specs.precision >= 0) checker.check_precision(); } private: diff --git a/include/fmt/printf.h b/include/fmt/printf.h index fbca84ad99b9f..4392d1c4ec636 100644 --- a/include/fmt/printf.h +++ b/include/fmt/printf.h @@ -160,7 +160,7 @@ template class printf_width_handler { unsigned operator()(T value) { auto width = static_cast>(value); if (internal::is_negative(value)) { - spec_.align_ = ALIGN_LEFT; + spec_.align = align::left; width = 0 - width; } unsigned int_max = std::numeric_limits::max(); @@ -248,8 +248,9 @@ class printf_arg_formatter : public internal::arg_formatter_base { format_specs& fmt_spec = *this->spec(); if (fmt_spec.type && fmt_spec.type != 'c') return (*this)(static_cast(value)); - fmt_spec.flags = 0; - fmt_spec.align_ = ALIGN_RIGHT; + fmt_spec.sign = sign::none; + fmt_spec.alt = false; + fmt_spec.align = align::right; return base::operator()(value); } else { return base::operator()(value); @@ -378,19 +379,19 @@ void basic_printf_context::parse_flags(format_specs& spec, for (; it != end; ++it) { switch (*it) { case '-': - spec.align_ = ALIGN_LEFT; + spec.align = align::left; break; case '+': - spec.flags |= SIGN_FLAG | PLUS_FLAG; + spec.sign = sign::plus; break; case '0': - spec.fill_ = '0'; + spec.fill[0] = '0'; break; case ' ': - spec.flags |= SIGN_FLAG; + spec.sign = sign::space; break; case '#': - spec.flags |= HASH_FLAG; + spec.alt = true; break; default: return; @@ -422,11 +423,11 @@ unsigned basic_printf_context::parse_header( ++it; arg_index = value; } else { - if (c == '0') spec.fill_ = '0'; + if (c == '0') spec.fill[0] = '0'; if (value != 0) { // Nonzero value means that we parsed width and don't need to // parse it or flags again, so return now. - spec.width_ = value; + spec.width = value; return arg_index; } } @@ -436,10 +437,10 @@ unsigned basic_printf_context::parse_header( if (it != end) { if (*it >= '0' && *it <= '9') { internal::error_handler eh; - spec.width_ = parse_nonnegative_int(it, end, eh); + spec.width = parse_nonnegative_int(it, end, eh); } else if (*it == '*') { ++it; - spec.width_ = visit_format_arg( + spec.width = visit_format_arg( internal::printf_width_handler(spec), get_arg()); } } @@ -464,7 +465,7 @@ OutputIt basic_printf_context::format() { out = std::copy(start, it - 1, out); format_specs spec; - spec.align_ = ALIGN_RIGHT; + spec.align = align::right; // Parse argument index, flags and width. unsigned arg_index = parse_header(it, end, spec); @@ -486,14 +487,13 @@ OutputIt basic_printf_context::format() { } format_arg arg = get_arg(arg_index); - if (spec.has(HASH_FLAG) && visit_format_arg(internal::is_zero_int(), arg)) - spec.flags = static_cast( - spec.flags & (~internal::to_unsigned(HASH_FLAG))); - if (spec.fill_ == '0') { + if (spec.alt && visit_format_arg(internal::is_zero_int(), arg)) + spec.alt = false; + if (spec.fill[0] == '0') { if (arg.is_arithmetic()) - spec.align_ = ALIGN_NUMERIC; + spec.align = align::numeric; else - spec.fill_ = ' '; // Ignore '0' flag for non-numeric types. + spec.fill[0] = ' '; // Ignore '0' flag for non-numeric types. } // Parse length and convert the argument to the required type. diff --git a/test/format b/test/format index 2ad5941ef38a4..d9472f924e9c6 100644 --- a/test/format +++ b/test/format @@ -690,7 +690,7 @@ struct formatter { template auto format(const T& val, FormatContext& ctx) -> decltype(ctx.out()) { fmt::internal::handle_dynamic_spec( - specs_.width_, specs_.width_ref, ctx, nullptr); + specs_.width, specs_.width_ref, ctx, nullptr); fmt::internal::handle_dynamic_spec( specs_.precision, specs_.precision_ref, ctx, nullptr); using range_type = fmt::internal::output_range width_ref; @@ -2117,7 +2117,7 @@ struct test_format_specs_handler { FMT_CONSTEXPR test_format_specs_handler( const test_format_specs_handler& other) : res(other.res), - align_(other.align_), + align(other.align), fill(other.fill), width(other.width), width_ref(other.width_ref), @@ -2125,7 +2125,7 @@ struct test_format_specs_handler { precision_ref(other.precision_ref), type(other.type) {} - FMT_CONSTEXPR void on_align(fmt::alignment a) { align_ = a; } + FMT_CONSTEXPR void on_align(fmt::align_t a) { align = a; } FMT_CONSTEXPR void on_fill(char f) { fill = f; } FMT_CONSTEXPR void on_plus() { res = PLUS; } FMT_CONSTEXPR void on_minus() { res = MINUS; } @@ -2159,7 +2159,7 @@ FMT_CONSTEXPR test_format_specs_handler parse_test_specs(const char (&s)[N]) { TEST(FormatTest, ConstexprParseFormatSpecs) { typedef test_format_specs_handler handler; - static_assert(parse_test_specs("<").align_ == fmt::ALIGN_LEFT, ""); + static_assert(parse_test_specs("<").align == fmt::align::left, ""); static_assert(parse_test_specs("*^").fill == '*', ""); static_assert(parse_test_specs("+").res == handler::PLUS, ""); static_assert(parse_test_specs("-").res == handler::MINUS, ""); @@ -2216,16 +2216,16 @@ FMT_CONSTEXPR fmt::format_specs parse_specs(const char (&s)[N]) { } TEST(FormatTest, ConstexprSpecsHandler) { - static_assert(parse_specs("<").align() == fmt::ALIGN_LEFT, ""); - static_assert(parse_specs("*^").fill() == '*', ""); - static_assert(parse_specs("+").has(fmt::PLUS_FLAG), ""); - static_assert(parse_specs("-").has(fmt::MINUS_FLAG), ""); - static_assert(parse_specs(" ").has(fmt::SIGN_FLAG), ""); - static_assert(parse_specs("#").has(fmt::HASH_FLAG), ""); - static_assert(parse_specs("0").align() == fmt::ALIGN_NUMERIC, ""); - static_assert(parse_specs("42").width() == 42, ""); - static_assert(parse_specs("{}").width() == 11, ""); - static_assert(parse_specs("{22}").width() == 22, ""); + static_assert(parse_specs("<").align == fmt::align::left, ""); + static_assert(parse_specs("*^").fill[0] == '*', ""); + static_assert(parse_specs("+").sign == fmt::sign::plus, ""); + static_assert(parse_specs("-").sign == fmt::sign::minus, ""); + static_assert(parse_specs(" ").sign == fmt::sign::space, ""); + static_assert(parse_specs("#").alt, ""); + static_assert(parse_specs("0").align == fmt::align::numeric, ""); + static_assert(parse_specs("42").width == 42, ""); + static_assert(parse_specs("{}").width == 11, ""); + static_assert(parse_specs("{22}").width == 22, ""); static_assert(parse_specs(".42").precision == 42, ""); static_assert(parse_specs(".{}").precision == 11, ""); static_assert(parse_specs(".{22}").precision == 22, ""); @@ -2243,14 +2243,14 @@ FMT_CONSTEXPR fmt::internal::dynamic_format_specs parse_dynamic_specs( } TEST(FormatTest, ConstexprDynamicSpecsHandler) { - static_assert(parse_dynamic_specs("<").align() == fmt::ALIGN_LEFT, ""); - static_assert(parse_dynamic_specs("*^").fill() == '*', ""); - static_assert(parse_dynamic_specs("+").has(fmt::PLUS_FLAG), ""); - static_assert(parse_dynamic_specs("-").has(fmt::MINUS_FLAG), ""); - static_assert(parse_dynamic_specs(" ").has(fmt::SIGN_FLAG), ""); - static_assert(parse_dynamic_specs("#").has(fmt::HASH_FLAG), ""); - static_assert(parse_dynamic_specs("0").align() == fmt::ALIGN_NUMERIC, ""); - static_assert(parse_dynamic_specs("42").width() == 42, ""); + static_assert(parse_dynamic_specs("<").align == fmt::align::left, ""); + static_assert(parse_dynamic_specs("*^").fill[0] == '*', ""); + static_assert(parse_dynamic_specs("+").sign == fmt::sign::plus, ""); + static_assert(parse_dynamic_specs("-").sign == fmt::sign::minus, ""); + static_assert(parse_dynamic_specs(" ").sign == fmt::sign::space, ""); + static_assert(parse_dynamic_specs("#").alt, ""); + static_assert(parse_dynamic_specs("0").align == fmt::align::numeric, ""); + static_assert(parse_dynamic_specs("42").width == 42, ""); static_assert(parse_dynamic_specs("{}").width_ref.val.index == 11, ""); static_assert(parse_dynamic_specs("{42}").width_ref.val.index == 42, ""); static_assert(parse_dynamic_specs(".42").precision == 42, ""); @@ -2269,7 +2269,7 @@ FMT_CONSTEXPR test_format_specs_handler check_specs(const char (&s)[N]) { TEST(FormatTest, ConstexprSpecsChecker) { typedef test_format_specs_handler handler; - static_assert(check_specs("<").align_ == fmt::ALIGN_LEFT, ""); + static_assert(check_specs("<").align == fmt::align::left, ""); static_assert(check_specs("*^").fill == '*', ""); static_assert(check_specs("+").res == handler::PLUS, ""); static_assert(check_specs("-").res == handler::MINUS, ""); diff --git a/test/prepare-test.cc b/test/prepare-test.cc index a210178b50b46..1839807e4af67 100644 --- a/test/prepare-test.cc +++ b/test/prepare-test.cc @@ -71,12 +71,12 @@ bool operator==(const format_part::specification& lhs, } break; } - return std::tie(lhs.parsed_specs.width_, lhs.parsed_specs.fill_, - lhs.parsed_specs.align_, lhs.parsed_specs.precision, - lhs.parsed_specs.flags, lhs.parsed_specs.type) == - std::tie(rhs.parsed_specs.width_, rhs.parsed_specs.fill_, - rhs.parsed_specs.align_, rhs.parsed_specs.precision, - rhs.parsed_specs.flags, rhs.parsed_specs.type); + return std::tie(lhs.parsed_specs.width, lhs.parsed_specs.fill[0], + lhs.parsed_specs.align, lhs.parsed_specs.precision, + lhs.parsed_specs.sign, lhs.parsed_specs.type) == + std::tie(rhs.parsed_specs.width, rhs.parsed_specs.fill[0], + rhs.parsed_specs.align, rhs.parsed_specs.precision, + rhs.parsed_specs.sign, rhs.parsed_specs.type); } bool operator!=(const format_part::specification& lhs, @@ -352,8 +352,8 @@ TEST( const auto last_part = format_part(0u); format_part::specification expected_specification(0u); fmt::internal::dynamic_format_specs specs{}; - specs.align_ = fmt::alignment::ALIGN_LEFT; - specs.width_ = 10; + specs.align = fmt::align::left; + specs.width = 10; expected_specification.parsed_specs = specs; auto expected_substitution_part = format_part(expected_specification); @@ -384,8 +384,8 @@ TEST( const auto last_part = format_part(format_part::named_argument_id(arg_id)); format_part::specification expected_specification(arg_id); fmt::internal::dynamic_format_specs specs{}; - specs.align_ = fmt::alignment::ALIGN_LEFT; - specs.width_ = 10; + specs.align = fmt::align::left; + specs.width = 10; expected_specification.parsed_specs = specs; auto expected_substitution_part = format_part(expected_specification);