diff --git a/src/core/include/mp-units/bits/fmt.h b/src/core/include/mp-units/bits/fmt.h index 5957cbd3..626a3bc8 100644 --- a/src/core/include/mp-units/bits/fmt.h +++ b/src/core/include/mp-units/bits/fmt.h @@ -252,31 +252,6 @@ template return begin; } -template -[[nodiscard]] constexpr const Char* parse_subentity_replacement_field(const Char* begin, const Char* end, - Handler&& handler) -{ - if (end - begin++ < 4) - return MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("`subentity-replacement-field` too short")), end; - if (*begin++ != '%') - MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("`subentity-replacement-field` should start with '%'")); - if (*begin == '}') - MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("`subentity-replacement-field` should have an identifier")); - auto it = begin; - for (; it != end; ++it) { - if (*it == '{' || *it == '%') - MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("invalid `subentity-replacement-field` format")); - if (*it == '}' || *it == ':') break; - } - if (it == end) MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("`subentity-replacement-field` too short")); - std::string_view id{begin, it}; - if (*it == ':') ++it; - it = handler.on_replacement_field(id, it); - if (it == end || *it != '}') - MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("`subentity-replacement-field` should end with '}'")); - return ++it; -} - template struct dynamic_spec_id_handler { MP_UNITS_STD_FMT::basic_format_parse_context& ctx; diff --git a/src/core/include/mp-units/format.h b/src/core/include/mp-units/format.h index 246ea629..1775deaf 100644 --- a/src/core/include/mp-units/format.h +++ b/src/core/include/mp-units/format.h @@ -40,6 +40,41 @@ struct fill_align_width_format_specs { fmt_arg_ref width_ref; }; +template +[[nodiscard]] constexpr const Char* at_most_one_of(const Char* begin, const Char* end, std::string_view modifiers) +{ + auto it = find_first_of(begin, end, modifiers.begin(), modifiers.end()); + if (it != end && 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"); + return it; +} + +template +[[nodiscard]] constexpr const Char* parse_subentity_replacement_field(const Char* begin, const Char* end, + Handler&& handler) +{ + if (end - begin++ < 4) + return MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("`subentity-replacement-field` too short")), end; + if (*begin++ != '%') + MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("`subentity-replacement-field` should start with '%'")); + if (*begin == '}') + MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("`subentity-replacement-field` should have an identifier")); + auto it = begin; + for (; it != end; ++it) { + if (*it == '{' || *it == '%') + MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("invalid `subentity-replacement-field` format")); + if (*it == '}' || *it == ':') break; + } + if (it == end) MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("`subentity-replacement-field` too short")); + std::string_view id{begin, it}; + if (*it == ':') ++it; + it = handler.on_replacement_field(id, it); + if (it == end || *it != '}') + MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("`subentity-replacement-field` should end with '}'")); + return ++it; +} + template OutputIt format_global_buffer(OutputIt out, const fill_align_width_format_specs& specs) { @@ -64,16 +99,6 @@ OutputIt format_global_buffer(OutputIt out, const fill_align_width_format_specs< return MP_UNITS_STD_FMT::format_to(out, "}}"); } -template -[[nodiscard]] constexpr const Char* at_most_one_of(const Char* begin, const Char* end, std::string_view modifiers) -{ - auto it = find_first_of(begin, end, modifiers.begin(), modifiers.end()); - if (it != end && 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"); - return it; -} - } // namespace mp_units::detail //