fix: non-std error handling removed from fmt

This commit is contained in:
Mateusz Pusz
2021-09-20 19:54:07 +02:00
parent d325a0b5b5
commit 40d6be9f75
2 changed files with 23 additions and 36 deletions

View File

@@ -164,7 +164,8 @@ template<typename CharT>
template<class Handler, typename FormatContext> template<class Handler, typename FormatContext>
[[nodiscard]] constexpr int get_dynamic_spec(int index, FormatContext& ctx) [[nodiscard]] constexpr int get_dynamic_spec(int index, FormatContext& ctx)
{ {
const unsigned long long value = STD_FMT::visit_format_arg(Handler{}, ctx.arg(FMT_TO_ARG_ID(static_cast<size_t>(index)))); const unsigned long long value =
STD_FMT::visit_format_arg(Handler{}, ctx.arg(FMT_TO_ARG_ID(static_cast<size_t>(index))));
if (value > static_cast<unsigned long long>(std::numeric_limits<int>::max())) { if (value > static_cast<unsigned long long>(std::numeric_limits<int>::max())) {
throw STD_FMT::format_error("number is too big"); throw STD_FMT::format_error("number is too big");
} }
@@ -173,8 +174,8 @@ template<class Handler, typename FormatContext>
// Parses the range [begin, end) as an unsigned integer. This function assumes // 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. // that the range is non-empty and the first character is a digit.
template<std::forward_iterator It, std::sentinel_for<It> S, typename IDHandler> template<std::forward_iterator It, std::sentinel_for<It> S>
[[nodiscard]] constexpr It parse_nonnegative_int(It begin, S end, IDHandler&& handler, size_t& value) noexcept [[nodiscard]] constexpr It parse_nonnegative_int(It begin, S end, size_t& value)
{ {
gsl_Expects(begin != end && '0' <= *begin && *begin <= '9'); gsl_Expects(begin != end && '0' <= *begin && *begin <= '9');
constexpr auto max_int = static_cast<unsigned>(std::numeric_limits<int>::max()); constexpr auto max_int = static_cast<unsigned>(std::numeric_limits<int>::max());
@@ -190,16 +191,16 @@ template<std::forward_iterator It, std::sentinel_for<It> S, typename IDHandler>
++begin; ++begin;
} while (begin != end && '0' <= *begin && *begin <= '9'); } while (begin != end && '0' <= *begin && *begin <= '9');
if (value > max_int) handler.on_error("Number is too big"); if (value > max_int) throw STD_FMT::format_error("Number is too big");
return begin; return begin;
} }
template<std::forward_iterator It, std::sentinel_for<It> S, typename IDHandler> template<std::forward_iterator It, std::sentinel_for<It> S>
[[nodiscard]] constexpr It parse_nonnegative_int(It begin, S end, IDHandler&& handler, int& value) noexcept [[nodiscard]] constexpr It parse_nonnegative_int(It begin, S end, int& value)
{ {
size_t val_unsigned = 0; size_t val_unsigned = 0;
begin = parse_nonnegative_int(begin, end, handler, val_unsigned); begin = parse_nonnegative_int(begin, end, val_unsigned);
// Never invalid because parse_nonnegative_integer throws an error for values that don't fit in signed integers // Never invalid because parse_nonnegative_integer throws an error for values that don't fit in signed integers
value = static_cast<int>(val_unsigned); value = static_cast<int>(val_unsigned);
return begin; return begin;
@@ -213,17 +214,16 @@ template<std::forward_iterator It, std::sentinel_for<It> S, typename IDHandler>
if (c >= '0' && c <= '9') { if (c >= '0' && c <= '9') {
size_t index = 0; size_t index = 0;
if (c != '0') if (c != '0')
begin = parse_nonnegative_int(begin, end, handler, index); begin = parse_nonnegative_int(begin, end, index);
else else
++begin; ++begin;
if (begin == end || (*begin != '}' && *begin != ':')) if (begin == end || (*begin != '}' && *begin != ':'))
handler.on_error("invalid format string"); throw STD_FMT::format_error("invalid format string");
else else
handler(index); handler(index);
return begin; return begin;
} }
handler.on_error("invalid format string"); throw STD_FMT::format_error("invalid format string");
return begin;
} }
template<std::forward_iterator It, std::sentinel_for<It> S, typename IDHandler> template<std::forward_iterator It, std::sentinel_for<It> S, typename IDHandler>
@@ -265,24 +265,20 @@ template<std::forward_iterator It, std::sentinel_for<It> S, typename Handler>
Handler& handler; Handler& handler;
constexpr void operator()() { handler.on_dynamic_width(auto_id{}); } constexpr void operator()() { handler.on_dynamic_width(auto_id{}); }
constexpr void operator()(size_t id) { handler.on_dynamic_width(id); } constexpr void operator()(size_t id) { handler.on_dynamic_width(id); }
constexpr void on_error(const char* message)
{
if (message) handler.on_error(message);
}
}; };
gsl_Expects(begin != end); gsl_Expects(begin != end);
if ('0' <= *begin && *begin <= '9') { if ('0' <= *begin && *begin <= '9') {
int width = 0; int width = 0;
begin = parse_nonnegative_int(begin, end, handler, width); begin = parse_nonnegative_int(begin, end, width);
if (width != -1) if (width != -1)
handler.on_width(width); handler.on_width(width);
else else
handler.on_error("number is too big"); throw STD_FMT::format_error("number is too big");
} else if (*begin == '{') { } else if (*begin == '{') {
++begin; ++begin;
if (begin != end) begin = parse_arg_id(begin, end, width_adapter{handler}); if (begin != end) begin = parse_arg_id(begin, end, width_adapter{handler});
if (begin == end || *begin != '}') return handler.on_error("invalid format string"), begin; if (begin == end || *begin != '}') throw STD_FMT::format_error("invalid format string");
++begin; ++begin;
} }
return begin; return begin;
@@ -295,27 +291,23 @@ template<std::forward_iterator It, std::sentinel_for<It> S, typename Handler>
Handler& handler; Handler& handler;
constexpr void operator()() { handler.on_dynamic_precision(auto_id{}); } constexpr void operator()() { handler.on_dynamic_precision(auto_id{}); }
constexpr void operator()(size_t id) { handler.on_dynamic_precision(id); } constexpr void operator()(size_t id) { handler.on_dynamic_precision(id); }
constexpr void on_error(const char* message)
{
if (message) handler.on_error(message);
}
}; };
++begin; ++begin;
auto c = begin != end ? *begin : std::iter_value_t<It>(); auto c = begin != end ? *begin : std::iter_value_t<It>();
if ('0' <= c && c <= '9') { if ('0' <= c && c <= '9') {
auto precision = 0; auto precision = 0;
begin = parse_nonnegative_int(begin, end, handler, precision); begin = parse_nonnegative_int(begin, end, precision);
if (precision != -1) if (precision != -1)
handler.on_precision(precision); handler.on_precision(precision);
else else
handler.on_error("number is too big"); throw STD_FMT::format_error("number is too big");
} else if (c == '{') { } else if (c == '{') {
++begin; ++begin;
if (begin != end) begin = parse_arg_id(begin, end, precision_adapter{handler}); if (begin != end) begin = parse_arg_id(begin, end, precision_adapter{handler});
if (begin == end || *begin++ != '}') return handler.on_error("invalid format string"), begin; if (begin == end || *begin++ != '}') throw STD_FMT::format_error("invalid format string");
} else { } else {
return handler.on_error("missing precision specifier"), begin; throw STD_FMT::format_error("missing precision specifier");
} }
return begin; return begin;
} }
@@ -359,7 +351,7 @@ template<std::forward_iterator It, std::sentinel_for<It> S, typename Handler>
if (align != fmt_align::none) { if (align != fmt_align::none) {
if (p != begin) { if (p != begin) {
auto c = *begin; auto c = *begin;
if (c == '{') return handler.on_error("invalid fill character '{'"), begin; if (c == '{') throw STD_FMT::format_error("invalid fill character '{'");
handler.on_fill(std::basic_string_view<std::iter_value_t<It>>(begin, static_cast<size_t>(p - begin))); handler.on_fill(std::basic_string_view<std::iter_value_t<It>>(begin, static_cast<size_t>(p - begin)));
begin = p + 1; begin = p + 1;
} else } else
@@ -463,9 +455,6 @@ public:
{ {
specs_.dynamic_precision_index = on_dynamic_arg(t, context_); specs_.dynamic_precision_index = on_dynamic_arg(t, context_);
} }
constexpr void on_error(const char* message) { context_.on_error(message); }
private: private:
dynamic_format_specs<char_type>& specs_; dynamic_format_specs<char_type>& specs_;
ParseContext& context_; ParseContext& context_;

View File

@@ -126,7 +126,7 @@ constexpr const It parse_units_rep(It begin, S end, Handler&& handler, bool trea
if (treat_as_floating_point) { if (treat_as_floating_point) {
begin = parse_precision(begin, end, handler); begin = parse_precision(begin, end, handler);
} else } else
handler.on_error("precision not allowed for integral quantity representation"); throw STD_FMT::format_error("precision not allowed for integral quantity representation");
if (begin == end) return begin; if (begin == end) return begin;
} }
@@ -264,8 +264,7 @@ OutputIt format_global_buffer(OutputIt out, const quantity_global_format_specs<C
return STD_FMT::format_to(out, "}}"); return STD_FMT::format_to(out, "}}");
} }
template<typename Dimension, typename Unit, typename Rep, typename Locale, typename CharT, template<typename Dimension, typename Unit, typename Rep, typename Locale, typename CharT, typename OutputIt>
typename OutputIt>
struct quantity_formatter { struct quantity_formatter {
OutputIt out; OutputIt out;
Rep val; Rep val;
@@ -317,7 +316,6 @@ private:
formatter& f; formatter& f;
STD_FMT::basic_format_parse_context<CharT>& context; STD_FMT::basic_format_parse_context<CharT>& context;
void on_error(const char* msg) { throw STD_FMT::format_error(msg); }
constexpr void on_fill(std::basic_string_view<CharT> fill) { f.specs.global.fill = fill; } constexpr void on_fill(std::basic_string_view<CharT> fill) { f.specs.global.fill = fill; }
constexpr void on_align(units::detail::fmt_align align) { f.specs.global.align = align; } constexpr void on_align(units::detail::fmt_align align) { f.specs.global.align = align; }
constexpr void on_width(int width) { f.specs.global.width = width; } constexpr void on_width(int width) { f.specs.global.width = width; }
@@ -332,7 +330,7 @@ private:
if (valid_rep_types.find(type) != std::string_view::npos) { if (valid_rep_types.find(type) != std::string_view::npos) {
f.specs.rep.type = type; f.specs.rep.type = type;
} else { } else {
on_error("invalid quantity type specifier"); throw STD_FMT::format_error("invalid quantity type specifier");
} }
} }
@@ -342,7 +340,7 @@ private:
if (valid_modifiers.find(mod) != std::string_view::npos) { if (valid_modifiers.find(mod) != std::string_view::npos) {
f.specs.unit.ascii_only = true; f.specs.unit.ascii_only = true;
} else { } else {
on_error("invalid unit modifier specified"); throw STD_FMT::format_error("invalid unit modifier specified");
} }
} }