diff --git a/src/core/include/mp-units/bits/fmt.h b/src/core/include/mp-units/bits/fmt.h index d55633a6..8e5e5321 100644 --- a/src/core/include/mp-units/bits/fmt.h +++ b/src/core/include/mp-units/bits/fmt.h @@ -209,8 +209,8 @@ MP_UNITS_EXPORT_END // Parses the range [begin, end) as an unsigned integer. This function assumes // that the range is non-empty and the first character is a digit. -template -[[nodiscard]] constexpr int parse_nonnegative_int(const Char*& begin, const Char* end, int error_value) +template +[[nodiscard]] constexpr int parse_nonnegative_int(It& begin, It end, int error_value) { MP_UNITS_EXPECTS(begin != end && '0' <= *begin && *begin <= '9'); unsigned value = 0, prev = 0; @@ -236,10 +236,10 @@ template return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '_'; } -template -[[nodiscard]] constexpr const Char* do_parse_arg_id(const Char* begin, const Char* end, Handler& handler) +template +[[nodiscard]] constexpr const It do_parse_arg_id(It begin, It end, Handler& handler) { - Char c = *begin; + auto c = *begin; if (c >= '0' && c <= '9') { int index = 0; constexpr int max = (std::numeric_limits::max)(); @@ -269,11 +269,11 @@ template return it; } -template -[[nodiscard]] constexpr const Char* parse_arg_id(const Char* begin, const Char* end, Handler& handler) +template +[[nodiscard]] constexpr It parse_arg_id(It begin, It end, Handler& handler) { MP_UNITS_EXPECTS(begin != end); - Char c = *begin; + auto c = *begin; if (c != '}' && c != ':') return ::mp_units::detail::do_parse_arg_id(begin, end, handler); handler.on_auto(); return begin; @@ -309,10 +309,9 @@ struct dynamic_spec_id_handler { #endif }; -template -[[nodiscard]] constexpr const Char* parse_dynamic_spec(const Char* begin, const Char* end, int& value, - fmt_arg_ref& ref, - MP_UNITS_STD_FMT::basic_format_parse_context& ctx) +template> +[[nodiscard]] constexpr It parse_dynamic_spec(It begin, It end, int& value, fmt_arg_ref& ref, + MP_UNITS_STD_FMT::basic_format_parse_context& ctx) { MP_UNITS_EXPECTS(begin != end); if ('0' <= *begin && *begin <= '9') { @@ -347,9 +346,8 @@ constexpr int code_point_length(It begin) } // Parses fill and alignment. -template -[[nodiscard]] constexpr const Char* parse_align(const Char* begin, const Char* end, Specs& specs, - fmt_align default_align = fmt_align::none) +template +[[nodiscard]] constexpr It parse_align(It begin, It end, Specs& specs, fmt_align default_align = fmt_align::none) { MP_UNITS_EXPECTS(begin != end); auto align = fmt_align::none; @@ -371,10 +369,8 @@ template if (p != begin) { auto c = *begin; if (c == '}') return begin; - if (c == '{') { - MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("invalid fill character '{'")); - } - specs.fill = {begin, to_unsigned(p - begin)}; + if (c == '{') MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("invalid fill character '{'")); + specs.fill = {begin, p}; begin = p + 1; } else { ++begin; diff --git a/src/core/include/mp-units/format.h b/src/core/include/mp-units/format.h index 6c76b5f8..aeaa5201 100644 --- a/src/core/include/mp-units/format.h +++ b/src/core/include/mp-units/format.h @@ -44,10 +44,10 @@ import std; namespace mp_units::detail { -template -[[nodiscard]] constexpr const Char* at_most_one_of(const Char* begin, const Char* end, std::string_view modifiers) +template +[[nodiscard]] constexpr It at_most_one_of(It begin, It end, std::string_view modifiers) { - const Char* const it = mp_units::detail::find_first_of(begin, end, modifiers.begin(), modifiers.end()); + const It it = mp_units::detail::find_first_of(begin, end, modifiers.begin(), modifiers.end()); if (it != end && mp_units::detail::find_first_of(it + 1, end, modifiers.begin(), modifiers.end()) != end) throw MP_UNITS_STD_FMT::format_error("only one of '" + std::string(modifiers) + "' unit modifiers may be used in the format spec"); @@ -65,10 +65,10 @@ struct fill_align_width_format_specs { fmt_arg_ref width_ref; }; -template -[[nodiscard]] constexpr const Char* parse_fill_align_width(MP_UNITS_STD_FMT::basic_format_parse_context& ctx, - const Char* begin, const Char* end, Specs& specs, - fmt_align default_align = fmt_align::none) +template +[[nodiscard]] constexpr It parse_fill_align_width( + MP_UNITS_STD_FMT::basic_format_parse_context>& ctx, It begin, It end, Specs& specs, + fmt_align default_align = fmt_align::none) { auto it = begin; if (it == end || *it == '}') return it; @@ -79,8 +79,8 @@ template return mp_units::detail::parse_dynamic_spec(it, end, specs.width, specs.width_ref, ctx); } -template -constexpr OutputIt format_global_buffer(OutputIt out, const fill_align_width_format_specs& specs) +template It> +constexpr It format_global_buffer(It out, const fill_align_width_format_specs& specs) { MP_UNITS_STD_FMT::format_to(out, "{{:"); if (specs.fill.size() != 1 || specs.fill[0] != ' ') { @@ -120,7 +120,8 @@ class MP_UNITS_STD_FMT::formatter { format_specs specs_{}; std::basic_string_view fill_align_width_format_str_; - constexpr const Char* parse_dimension_specs(const Char* begin, const Char* end) + template + constexpr It parse_dimension_specs(It begin, It end) { auto it = begin; if (it == end || *it == '}') return begin; @@ -191,7 +192,8 @@ class MP_UNITS_STD_FMT::formatter { std::basic_string_view fill_align_width_format_str_; - constexpr const Char* parse_unit_specs(const Char* begin, const Char* end) + template + constexpr It parse_unit_specs(It begin, It end) { auto it = begin; if (it == end || *it == '}') return begin; @@ -307,7 +309,10 @@ class MP_UNITS_STD_FMT::formatter, Char> { constexpr void on_maybe_space() const {} constexpr void on_unit() const {} constexpr void on_dimension() const {} - constexpr void on_text(const Char*, const Char*) const {} + template + constexpr void on_text(It, It) const + { + } }; template @@ -335,13 +340,17 @@ class MP_UNITS_STD_FMT::formatter, Char> { out = MP_UNITS_STD_FMT::vformat_to(out, locale, f.dimension_format_str_, MP_UNITS_STD_FMT::make_format_args(q.dimension)); } - void on_text(const Char* begin, const Char* end) const { mp_units::detail::copy(begin, end, out); } + template + void on_text(It begin, It end) const + { + mp_units::detail::copy(begin, end, out); + } }; template quantity_formatter(const formatter&, OutputIt, Args...) -> quantity_formatter; - template - constexpr const Char* parse_quantity_specs(const Char* begin, const Char* end, Handler& handler) const + template + constexpr const It parse_quantity_specs(It begin, It end, Handler& handler) const { if (begin == end || *begin == ':' || *begin == '}') return begin; if (*begin != '%') @@ -394,8 +403,8 @@ class MP_UNITS_STD_FMT::formatter, Char> { return ptr; } - template - constexpr const Char* parse_default_spec(const Char* begin, const Char* end, Formatter& f, std::string& format_str) + template + constexpr It parse_default_spec(It begin, It end, Formatter& f, std::string& format_str) { if (begin == end || *begin != '[') throw MP_UNITS_STD_FMT::format_error("`default-spec` should contain a `[` character"); @@ -415,7 +424,8 @@ class MP_UNITS_STD_FMT::formatter, Char> { return ++it; // skip `]` } - [[nodiscard]] constexpr const Char* parse_defaults_specs(const Char* begin, const Char* end) + template + [[nodiscard]] constexpr It parse_defaults_specs(It begin, It end) { if (begin == end || *begin == '}') return begin; if (*begin++ != ':') throw MP_UNITS_STD_FMT::format_error("`defaults-specs` should start with a `:`");