fix: quantity alignment formatting fixed

This commit is contained in:
Mateusz Pusz
2024-01-23 21:19:45 +01:00
parent 1e43758b54
commit 0ce6fed70d
2 changed files with 31 additions and 7 deletions

View File

@@ -341,7 +341,8 @@ constexpr int code_point_length(It begin)
// Parses fill and alignment. // Parses fill and alignment.
template<typename Char, typename Specs> template<typename Char, typename Specs>
[[nodiscard]] constexpr const Char* parse_align(const Char* begin, const Char* end, Specs& specs) [[nodiscard]] constexpr const Char* parse_align(const Char* begin, const Char* end, Specs& specs,
fmt_align default_align = fmt_align::none)
{ {
gsl_Expects(begin != end); gsl_Expects(begin != end);
auto align = fmt_align::none; auto align = fmt_align::none;
@@ -378,6 +379,7 @@ template<typename Char, typename Specs>
} }
p = begin; p = begin;
} }
if (align == fmt_align::none) align = default_align; // mp-units extension
specs.align = align; specs.align = align;
return begin; return begin;
} }

View File

@@ -40,6 +40,30 @@ struct fill_align_width_format_specs {
fmt_arg_ref<Char> width_ref; fmt_arg_ref<Char> width_ref;
}; };
template<typename OutputIt, typename Char>
OutputIt format_global_buffer(OutputIt out, const fill_align_width_format_specs<Char>& specs)
{
MP_UNITS_STD_FMT::format_to(out, "{{:");
if (specs.fill.size() != 1 || specs.fill[0] != ' ') {
MP_UNITS_STD_FMT::format_to(out, "{}", specs.fill.data());
}
switch (specs.align) {
case fmt_align::left:
MP_UNITS_STD_FMT::format_to(out, "<");
break;
case fmt_align::right:
MP_UNITS_STD_FMT::format_to(out, ">");
break;
case fmt_align::center:
MP_UNITS_STD_FMT::format_to(out, "^");
break;
default:
break;
}
if (specs.width >= 1) MP_UNITS_STD_FMT::format_to(out, "{}", specs.width);
return MP_UNITS_STD_FMT::format_to(out, "}}");
}
template<typename Char> template<typename Char>
[[nodiscard]] constexpr const Char* at_most_one_of(const Char* begin, const Char* end, std::string_view modifiers) [[nodiscard]] constexpr const Char* at_most_one_of(const Char* begin, const Char* end, std::string_view modifiers)
{ {
@@ -215,7 +239,6 @@ class MP_UNITS_STD_FMT::formatter<mp_units::quantity<Reference, Rep>, Char> {
using format_specs = mp_units::detail::fill_align_width_format_specs<Char>; using format_specs = mp_units::detail::fill_align_width_format_specs<Char>;
std::basic_string_view<Char> fill_align_width_format_str_;
std::basic_string_view<Char> modifiers_format_str_; std::basic_string_view<Char> modifiers_format_str_;
std::vector<size_t> format_str_lengths_; std::vector<size_t> format_str_lengths_;
format_specs specs_{}; format_specs specs_{};
@@ -370,14 +393,12 @@ public:
auto it = begin, end = ctx.end(); auto it = begin, end = ctx.end();
if (it == end || *it == '}') return it; if (it == end || *it == '}') return it;
it = mp_units::detail::parse_align(it, end, specs_); it = mp_units::detail::parse_align(it, end, specs_, mp_units::detail::fmt_align::right);
if (it == end) return it; if (it == end) return it;
it = mp_units::detail::parse_dynamic_spec(it, end, specs_.width, specs_.width_ref, ctx); it = mp_units::detail::parse_dynamic_spec(it, end, specs_.width, specs_.width_ref, ctx);
if (it == end) return it; if (it == end) return it;
fill_align_width_format_str_ = {begin, it};
format_checker checker(ctx, format_str_lengths_); format_checker checker(ctx, format_str_lengths_);
end = parse_quantity_specs(it, end, checker); end = parse_quantity_specs(it, end, checker);
modifiers_format_str_ = {it, end}; modifiers_format_str_ = {it, end};
@@ -397,8 +418,9 @@ public:
std::basic_string<Char> quantity_buffer; std::basic_string<Char> quantity_buffer;
format_quantity(std::back_inserter(quantity_buffer), q, ctx); format_quantity(std::back_inserter(quantity_buffer), q, ctx);
std::basic_string<Char> global_format_buffer = "{:" + std::basic_string<Char>{fill_align_width_format_str_} + "}"; std::basic_string<Char> fill_align_width_format_str;
return MP_UNITS_STD_FMT::vformat_to(ctx.out(), global_format_buffer, mp_units::detail::format_global_buffer(std::back_inserter(fill_align_width_format_str), specs);
return MP_UNITS_STD_FMT::vformat_to(ctx.out(), fill_align_width_format_str,
MP_UNITS_STD_FMT::make_format_args(quantity_buffer)); MP_UNITS_STD_FMT::make_format_args(quantity_buffer));
} }
} }