Replace multiple error reporting mechanisms with report_error
This commit is contained in:
parent
f9294f0e60
commit
fe0d910a7d
@ -683,8 +683,17 @@ enum {
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
/** Throws ``format_error`` with a given message. */
|
||||
FMT_NORETURN FMT_API void throw_format_error(const char* message);
|
||||
/**
|
||||
Reports a format error at compile time or, via a ``format_error`` exception,
|
||||
at runtime.
|
||||
*/
|
||||
// This function is intentionally not constexpr to give a compile-time error.
|
||||
FMT_NORETURN FMT_API void report_error(const char* message);
|
||||
|
||||
FMT_DEPRECATED FMT_NORETURN inline void throw_format_error(
|
||||
const char* message) {
|
||||
report_error(message);
|
||||
}
|
||||
|
||||
/** String's character (code unit) type. */
|
||||
template <typename S,
|
||||
@ -738,8 +747,7 @@ template <typename Char> class basic_format_parse_context {
|
||||
*/
|
||||
FMT_CONSTEXPR auto next_arg_id() -> int {
|
||||
if (next_arg_id_ < 0) {
|
||||
throw_format_error(
|
||||
"cannot switch from manual to automatic argument indexing");
|
||||
report_error("cannot switch from manual to automatic argument indexing");
|
||||
return 0;
|
||||
}
|
||||
int id = next_arg_id_++;
|
||||
@ -753,8 +761,7 @@ template <typename Char> class basic_format_parse_context {
|
||||
*/
|
||||
FMT_CONSTEXPR void check_arg_id(int id) {
|
||||
if (next_arg_id_ > 0) {
|
||||
throw_format_error(
|
||||
"cannot switch from automatic to manual argument indexing");
|
||||
report_error("cannot switch from automatic to manual argument indexing");
|
||||
return;
|
||||
}
|
||||
next_arg_id_ = -1;
|
||||
@ -787,20 +794,20 @@ class compile_parse_context : public basic_format_parse_context<Char> {
|
||||
|
||||
FMT_CONSTEXPR auto next_arg_id() -> int {
|
||||
int id = base::next_arg_id();
|
||||
if (id >= num_args_) throw_format_error("argument not found");
|
||||
if (id >= num_args_) report_error("argument not found");
|
||||
return id;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void check_arg_id(int id) {
|
||||
base::check_arg_id(id);
|
||||
if (id >= num_args_) throw_format_error("argument not found");
|
||||
if (id >= num_args_) report_error("argument not found");
|
||||
}
|
||||
using base::check_arg_id;
|
||||
|
||||
FMT_CONSTEXPR void check_dynamic_spec(int arg_id) {
|
||||
detail::ignore_unused(arg_id);
|
||||
if (arg_id < num_args_ && types_ && !is_integral_type(types_[arg_id]))
|
||||
throw_format_error("width/precision is not integer");
|
||||
report_error("width/precision is not integer");
|
||||
}
|
||||
};
|
||||
|
||||
@ -1081,7 +1088,7 @@ FMT_CONSTEXPR void basic_format_parse_context<Char>::do_check_arg_id(int id) {
|
||||
(!FMT_GCC_VERSION || FMT_GCC_VERSION >= 1200)) {
|
||||
using context = detail::compile_parse_context<Char>;
|
||||
if (id >= static_cast<context*>(this)->num_args())
|
||||
throw_format_error("argument not found");
|
||||
report_error("argument not found");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1916,9 +1923,6 @@ class context {
|
||||
}
|
||||
auto args() const -> const basic_format_args<context>& { return args_; }
|
||||
|
||||
// This function is intentionally not constexpr to give a compile-time error.
|
||||
void on_error(const char* message) { throw_format_error(message); }
|
||||
|
||||
// Returns an iterator to the beginning of the output range.
|
||||
FMT_CONSTEXPR auto out() -> iterator { return out_; }
|
||||
|
||||
@ -2215,13 +2219,13 @@ FMT_CONSTEXPR auto do_parse_arg_id(const Char* begin, const Char* end,
|
||||
else
|
||||
++begin;
|
||||
if (begin == end || (*begin != '}' && *begin != ':'))
|
||||
throw_format_error("invalid format string");
|
||||
report_error("invalid format string");
|
||||
else
|
||||
handler.on_index(index);
|
||||
return begin;
|
||||
}
|
||||
if (!is_name_start(c)) {
|
||||
throw_format_error("invalid format string");
|
||||
report_error("invalid format string");
|
||||
return begin;
|
||||
}
|
||||
auto it = begin;
|
||||
@ -2274,13 +2278,13 @@ FMT_CONSTEXPR auto parse_dynamic_spec(const Char* begin, const Char* end,
|
||||
if (val != -1)
|
||||
value = val;
|
||||
else
|
||||
throw_format_error("number is too big");
|
||||
report_error("number is too big");
|
||||
} else if (*begin == '{') {
|
||||
++begin;
|
||||
auto handler = dynamic_spec_id_handler<Char>{ctx, ref};
|
||||
if (begin != end) begin = parse_arg_id(begin, end, handler);
|
||||
if (begin != end && *begin == '}') return ++begin;
|
||||
throw_format_error("invalid format string");
|
||||
report_error("invalid format string");
|
||||
}
|
||||
return begin;
|
||||
}
|
||||
@ -2292,7 +2296,7 @@ FMT_CONSTEXPR auto parse_precision(const Char* begin, const Char* end,
|
||||
-> const Char* {
|
||||
++begin;
|
||||
if (begin == end || *begin == '}') {
|
||||
throw_format_error("invalid precision");
|
||||
report_error("invalid precision");
|
||||
return begin;
|
||||
}
|
||||
return parse_dynamic_spec(begin, end, value, ref, ctx);
|
||||
@ -2319,7 +2323,7 @@ FMT_CONSTEXPR auto parse_format_specs(const Char* begin, const Char* end,
|
||||
state current_state = state::start;
|
||||
FMT_CONSTEXPR void operator()(state s, bool valid = true) {
|
||||
if (current_state >= s || !valid)
|
||||
throw_format_error("invalid format specifier");
|
||||
report_error("invalid format specifier");
|
||||
current_state = s;
|
||||
}
|
||||
} enter_state;
|
||||
@ -2334,7 +2338,7 @@ FMT_CONSTEXPR auto parse_format_specs(const Char* begin, const Char* end,
|
||||
FMT_CONSTEXPR auto operator()(pres pres_type, int set) -> const Char* {
|
||||
if (!in(arg_type, set)) {
|
||||
if (arg_type == type::none_type) return begin;
|
||||
throw_format_error("invalid format specifier");
|
||||
report_error("invalid format specifier");
|
||||
}
|
||||
specs.type = pres_type;
|
||||
return begin + 1;
|
||||
@ -2378,7 +2382,7 @@ FMT_CONSTEXPR auto parse_format_specs(const Char* begin, const Char* end,
|
||||
enter_state(state::zero);
|
||||
if (!is_arithmetic_type(arg_type)) {
|
||||
if (arg_type == type::none_type) return begin;
|
||||
throw_format_error("format specifier requires numeric argument");
|
||||
report_error("format specifier requires numeric argument");
|
||||
}
|
||||
if (specs.align == align::none) {
|
||||
// Ignore 0 if align is specified for compatibility with std::format.
|
||||
@ -2448,8 +2452,7 @@ FMT_CONSTEXPR auto parse_format_specs(const Char* begin, const Char* end,
|
||||
case 'a':
|
||||
return parse_presentation_type(pres::hexfloat, float_set);
|
||||
case 'c':
|
||||
if (arg_type == type::bool_type)
|
||||
throw_format_error("invalid format specifier");
|
||||
if (arg_type == type::bool_type) report_error("invalid format specifier");
|
||||
return parse_presentation_type(pres::chr, integral_set);
|
||||
case 's':
|
||||
return parse_presentation_type(pres::string,
|
||||
@ -2466,11 +2469,11 @@ FMT_CONSTEXPR auto parse_format_specs(const Char* begin, const Char* end,
|
||||
// Parse fill and alignment.
|
||||
auto fill_end = begin + code_point_length(begin);
|
||||
if (end - fill_end <= 0) {
|
||||
throw_format_error("invalid format specifier");
|
||||
report_error("invalid format specifier");
|
||||
return begin;
|
||||
}
|
||||
if (*begin == '{') {
|
||||
throw_format_error("invalid fill character '{'");
|
||||
report_error("invalid fill character '{'");
|
||||
return begin;
|
||||
}
|
||||
auto align = parse_align(to_ascii(*fill_end));
|
||||
@ -2610,7 +2613,7 @@ FMT_CONSTEXPR auto check_char_specs(const format_specs<Char>& specs) -> bool {
|
||||
return false;
|
||||
}
|
||||
if (specs.align == align::numeric || specs.sign != sign::none || specs.alt)
|
||||
throw_format_error("invalid format specifier for char");
|
||||
report_error("invalid format specifier for char");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2687,9 +2690,7 @@ template <typename Char, typename... Args> class format_string_checker {
|
||||
return id >= 0 && id < num_args ? parse_funcs_[id](context_) : begin;
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void on_error(const char* message) {
|
||||
throw_format_error(message);
|
||||
}
|
||||
FMT_CONSTEXPR void on_error(const char* message) { report_error(message); }
|
||||
};
|
||||
|
||||
// A base class for compile-time strings.
|
||||
|
@ -123,7 +123,7 @@ FMT_FUNC auto write_loc(appender out, loc_value value,
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
FMT_FUNC void throw_format_error(const char* message) {
|
||||
FMT_FUNC void report_error(const char* message) {
|
||||
FMT_THROW(format_error(message));
|
||||
}
|
||||
|
||||
|
@ -1033,8 +1033,6 @@ template <typename OutputIt, typename Char> class generic_context {
|
||||
return args_;
|
||||
}
|
||||
|
||||
void on_error(const char* message) { throw_format_error(message); }
|
||||
|
||||
FMT_CONSTEXPR auto out() -> iterator { return out_; }
|
||||
|
||||
void advance_to(iterator it) {
|
||||
@ -2333,7 +2331,7 @@ FMT_CONSTEXPR auto write(OutputIt out, const Char* s,
|
||||
-> OutputIt {
|
||||
if (specs.type == presentation_type::pointer)
|
||||
return write_ptr<Char>(out, bit_cast<uintptr_t>(s), &specs);
|
||||
if (!s) throw_format_error("string pointer is null");
|
||||
if (!s) report_error("string pointer is null");
|
||||
return write(out, basic_string_view<Char>(s), specs, {});
|
||||
}
|
||||
|
||||
@ -2384,7 +2382,7 @@ FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end,
|
||||
auto c = *begin;
|
||||
if (c == '}') return begin;
|
||||
if (c == '{') {
|
||||
throw_format_error("invalid fill character '{'");
|
||||
report_error("invalid fill character '{'");
|
||||
return begin;
|
||||
}
|
||||
specs.fill = {begin, to_unsigned(p - begin)};
|
||||
@ -3600,7 +3598,7 @@ FMT_CONSTEXPR20 auto write_float(OutputIt out, T value,
|
||||
: 6;
|
||||
if (fspecs.format == float_format::exp) {
|
||||
if (precision == max_value<int>())
|
||||
throw_format_error("number is too big");
|
||||
report_error("number is too big");
|
||||
else
|
||||
++precision;
|
||||
} else if (fspecs.format != float_format::fixed && precision == 0) {
|
||||
@ -3707,7 +3705,7 @@ FMT_CONSTEXPR auto write(OutputIt out, Char value) -> OutputIt {
|
||||
template <typename Char, typename OutputIt>
|
||||
FMT_CONSTEXPR20 auto write(OutputIt out, const Char* value) -> OutputIt {
|
||||
if (value) return write(out, basic_string_view<Char>(value));
|
||||
throw_format_error("string pointer is null");
|
||||
report_error("string pointer is null");
|
||||
return out;
|
||||
}
|
||||
|
||||
@ -3785,13 +3783,13 @@ template <typename Char> struct arg_formatter {
|
||||
struct width_checker {
|
||||
template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
|
||||
FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
|
||||
if (is_negative(value)) throw_format_error("negative width");
|
||||
if (is_negative(value)) report_error("negative width");
|
||||
return static_cast<unsigned long long>(value);
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
|
||||
FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
|
||||
throw_format_error("width is not integer");
|
||||
report_error("width is not integer");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
@ -3799,13 +3797,13 @@ struct width_checker {
|
||||
struct precision_checker {
|
||||
template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
|
||||
FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
|
||||
if (is_negative(value)) throw_format_error("negative precision");
|
||||
if (is_negative(value)) report_error("negative precision");
|
||||
return static_cast<unsigned long long>(value);
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
|
||||
FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
|
||||
throw_format_error("precision is not integer");
|
||||
report_error("precision is not integer");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
@ -3813,15 +3811,14 @@ struct precision_checker {
|
||||
template <typename Handler, typename FormatArg>
|
||||
FMT_CONSTEXPR auto get_dynamic_spec(FormatArg arg) -> int {
|
||||
unsigned long long value = arg.visit(Handler());
|
||||
if (value > to_unsigned(max_value<int>()))
|
||||
throw_format_error("number is too big");
|
||||
if (value > to_unsigned(max_value<int>())) report_error("number is too big");
|
||||
return static_cast<int>(value);
|
||||
}
|
||||
|
||||
template <typename Context, typename ID>
|
||||
FMT_CONSTEXPR auto get_arg(Context& ctx, ID id) -> decltype(ctx.arg(id)) {
|
||||
auto arg = ctx.arg(id);
|
||||
if (!arg) ctx.on_error("argument not found");
|
||||
if (!arg) report_error("argument not found");
|
||||
return arg;
|
||||
}
|
||||
|
||||
@ -3893,6 +3890,7 @@ using format_func = void (*)(detail::buffer<char>&, int, const char*);
|
||||
FMT_API void format_error_code(buffer<char>& out, int error_code,
|
||||
string_view message) noexcept;
|
||||
|
||||
using fmt::report_error;
|
||||
FMT_API void report_error(format_func func, int error_code,
|
||||
const char* message) noexcept;
|
||||
} // namespace detail
|
||||
@ -4253,7 +4251,7 @@ void vformat_to(buffer<Char>& buf, basic_string_view<Char> fmt,
|
||||
auto out = basic_appender<Char>(buf);
|
||||
if (fmt.size() == 2 && equal2(fmt.data(), "{}")) {
|
||||
auto arg = args.get(0);
|
||||
if (!arg) throw_format_error("argument not found");
|
||||
if (!arg) report_error("argument not found");
|
||||
arg.visit(default_arg_formatter<Char>{out, args, loc});
|
||||
return;
|
||||
}
|
||||
@ -4280,7 +4278,7 @@ void vformat_to(buffer<Char>& buf, basic_string_view<Char> fmt,
|
||||
}
|
||||
FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int {
|
||||
int arg_id = context.arg_id(id);
|
||||
if (arg_id < 0) throw_format_error("argument not found");
|
||||
if (arg_id < 0) report_error("argument not found");
|
||||
return arg_id;
|
||||
}
|
||||
|
||||
@ -4303,13 +4301,13 @@ void vformat_to(buffer<Char>& buf, basic_string_view<Char> fmt,
|
||||
detail::handle_dynamic_spec<detail::precision_checker>(
|
||||
specs.precision, specs.precision_ref, context);
|
||||
if (begin == end || *begin != '}')
|
||||
throw_format_error("missing '}' in format string");
|
||||
report_error("missing '}' in format string");
|
||||
context.advance_to(arg.visit(
|
||||
arg_formatter<Char>{context.out(), specs, context.locale()}));
|
||||
return begin;
|
||||
}
|
||||
|
||||
void on_error(const char* message) { throw_format_error(message); }
|
||||
void on_error(const char* message) { report_error(message); }
|
||||
};
|
||||
detail::parse_format_string<false>(fmt, format_handler(out, fmt, args, loc));
|
||||
}
|
||||
|
@ -52,8 +52,6 @@ template <typename Char> class basic_printf_context {
|
||||
auto arg(int id) const -> basic_format_arg<basic_printf_context> {
|
||||
return args_.get(id);
|
||||
}
|
||||
|
||||
void on_error(const char* message) { throw_format_error(message); }
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
@ -80,13 +78,13 @@ struct printf_precision_handler {
|
||||
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
||||
auto operator()(T value) -> int {
|
||||
if (!int_checker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
|
||||
throw_format_error("number is too big");
|
||||
report_error("number is too big");
|
||||
return (std::max)(static_cast<int>(value), 0);
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
auto operator()(T) -> int {
|
||||
throw_format_error("precision is not integer");
|
||||
report_error("precision is not integer");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
@ -208,13 +206,13 @@ template <typename Char> class printf_width_handler {
|
||||
width = 0 - width;
|
||||
}
|
||||
unsigned int_max = max_value<int>();
|
||||
if (width > int_max) throw_format_error("number is too big");
|
||||
if (width > int_max) report_error("number is too big");
|
||||
return static_cast<unsigned>(width);
|
||||
}
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
||||
auto operator()(T) -> unsigned {
|
||||
throw_format_error("width is not integer");
|
||||
report_error("width is not integer");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
@ -352,7 +350,7 @@ auto parse_header(const Char*& it, const Char* end, format_specs<Char>& specs,
|
||||
if (value != 0) {
|
||||
// Nonzero value means that we parsed width and don't need to
|
||||
// parse it or flags again, so return now.
|
||||
if (value == -1) throw_format_error("number is too big");
|
||||
if (value == -1) report_error("number is too big");
|
||||
specs.width = value;
|
||||
return arg_index;
|
||||
}
|
||||
@ -363,7 +361,7 @@ auto parse_header(const Char*& it, const Char* end, format_specs<Char>& specs,
|
||||
if (it != end) {
|
||||
if (*it >= '0' && *it <= '9') {
|
||||
specs.width = parse_nonnegative_int(it, end, -1);
|
||||
if (specs.width == -1) throw_format_error("number is too big");
|
||||
if (specs.width == -1) report_error("number is too big");
|
||||
} else if (*it == '*') {
|
||||
++it;
|
||||
specs.width = static_cast<int>(
|
||||
@ -457,7 +455,7 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
|
||||
|
||||
// Parse argument index, flags and width.
|
||||
int arg_index = parse_header(it, end, specs, get_arg);
|
||||
if (arg_index == 0) throw_format_error("argument not found");
|
||||
if (arg_index == 0) report_error("argument not found");
|
||||
|
||||
// Parse precision.
|
||||
if (it != end && *it == '.') {
|
||||
@ -539,7 +537,7 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
|
||||
}
|
||||
|
||||
// Parse type.
|
||||
if (it == end) throw_format_error("invalid format string");
|
||||
if (it == end) report_error("invalid format string");
|
||||
char type = static_cast<char>(*it++);
|
||||
if (arg.is_integral()) {
|
||||
// Normalize type.
|
||||
@ -556,7 +554,7 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
|
||||
bool upper = false;
|
||||
specs.type = parse_printf_presentation_type(type, arg.type(), upper);
|
||||
if (specs.type == presentation_type::none)
|
||||
throw_format_error("invalid format specifier");
|
||||
report_error("invalid format specifier");
|
||||
specs.upper = upper;
|
||||
|
||||
start = it;
|
||||
|
@ -310,8 +310,7 @@ struct formatter<Tuple, Char,
|
||||
template <typename ParseContext>
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
auto it = ctx.begin();
|
||||
if (it != ctx.end() && *it != '}')
|
||||
throw_format_error("invalid format specifier");
|
||||
if (it != ctx.end() && *it != '}') report_error("invalid format specifier");
|
||||
detail::for_each(formatters_, detail::parse_empty_specs<ParseContext>{ctx});
|
||||
return it;
|
||||
}
|
||||
@ -417,7 +416,7 @@ struct range_formatter<
|
||||
}
|
||||
|
||||
if (it != end && *it != '}') {
|
||||
if (*it != ':') throw_format_error("invalid format specifier");
|
||||
if (*it != ':') report_error("invalid format specifier");
|
||||
++it;
|
||||
} else {
|
||||
detail::maybe_set_debug_format(underlying_, true);
|
||||
@ -650,7 +649,7 @@ struct formatter<tuple_join_view<Char, T...>, Char> {
|
||||
if (N > 1) {
|
||||
auto end1 = do_parse(ctx, std::integral_constant<size_t, N - 1>());
|
||||
if (end != end1)
|
||||
throw_format_error("incompatible format specs for tuple elements");
|
||||
report_error("incompatible format specs for tuple elements");
|
||||
}
|
||||
#endif
|
||||
return end;
|
||||
|
@ -447,7 +447,7 @@ TEST(memory_buffer_test, max_size_allocator_overflow) {
|
||||
}
|
||||
|
||||
TEST(format_test, exception_from_lib) {
|
||||
EXPECT_THROW_MSG(fmt::throw_format_error("test"), format_error, "test");
|
||||
EXPECT_THROW_MSG(fmt::report_error("test"), format_error, "test");
|
||||
}
|
||||
|
||||
TEST(format_test, escape) {
|
||||
|
@ -87,7 +87,7 @@ template <> struct scanner<num> {
|
||||
hex = true;
|
||||
++it;
|
||||
}
|
||||
if (it != end && *it != '}') throw_format_error("invalid format");
|
||||
if (it != end && *it != '}') report_error("invalid format");
|
||||
return it;
|
||||
}
|
||||
|
||||
|
20
test/scan.h
20
test/scan.h
@ -453,7 +453,7 @@ template <typename T, FMT_ENABLE_IF(std::is_unsigned<T>::value)>
|
||||
auto read(scan_iterator it, T& value) -> scan_iterator {
|
||||
if (it == scan_sentinel()) return it;
|
||||
char c = *it;
|
||||
if (c < '0' || c > '9') throw_format_error("invalid input");
|
||||
if (c < '0' || c > '9') report_error("invalid input");
|
||||
|
||||
int num_digits = 0;
|
||||
T n = 0, prev = 0;
|
||||
@ -477,7 +477,7 @@ auto read(scan_iterator it, T& value) -> scan_iterator {
|
||||
prev * 10ull + unsigned(prev_digit - '0') <= max) {
|
||||
value = n;
|
||||
} else {
|
||||
throw_format_error("number is too big");
|
||||
report_error("number is too big");
|
||||
}
|
||||
return it;
|
||||
}
|
||||
@ -486,7 +486,7 @@ template <typename T, FMT_ENABLE_IF(std::is_unsigned<T>::value)>
|
||||
auto read_hex(scan_iterator it, T& value) -> scan_iterator {
|
||||
if (it == scan_sentinel()) return it;
|
||||
int digit = to_hex_digit(*it);
|
||||
if (digit < 0) throw_format_error("invalid input");
|
||||
if (digit < 0) report_error("invalid input");
|
||||
|
||||
int num_digits = 0;
|
||||
T n = 0;
|
||||
@ -501,7 +501,7 @@ auto read_hex(scan_iterator it, T& value) -> scan_iterator {
|
||||
if (num_digits <= (std::numeric_limits<T>::digits >> 2))
|
||||
value = n;
|
||||
else
|
||||
throw_format_error("number is too big");
|
||||
report_error("number is too big");
|
||||
return it;
|
||||
}
|
||||
|
||||
@ -518,7 +518,7 @@ auto read(scan_iterator it, T& value, const format_specs<>& specs = {})
|
||||
bool negative = it != scan_sentinel() && *it == '-';
|
||||
if (negative) {
|
||||
++it;
|
||||
if (it == scan_sentinel()) throw_format_error("invalid input");
|
||||
if (it == scan_sentinel()) report_error("invalid input");
|
||||
}
|
||||
using unsigned_type = typename std::make_unsigned<T>::type;
|
||||
unsigned_type abs_value = 0;
|
||||
@ -538,7 +538,7 @@ auto read(scan_iterator it, string_view& value, const format_specs<>& = {})
|
||||
-> scan_iterator {
|
||||
auto range = to_contiguous(it);
|
||||
// This could also be checked at compile time in scan.
|
||||
if (!range) throw_format_error("string_view requires contiguous input");
|
||||
if (!range) report_error("string_view requires contiguous input");
|
||||
auto p = range.begin;
|
||||
while (p != range.end && *p != ' ') ++p;
|
||||
size_t size = to_unsigned(p - range.begin);
|
||||
@ -624,7 +624,7 @@ struct scan_handler {
|
||||
return begin;
|
||||
}
|
||||
|
||||
void on_error(const char* message) { throw_format_error(message); }
|
||||
void on_error(const char* message) { report_error(message); }
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
@ -640,7 +640,7 @@ template <typename T> class scan_value {
|
||||
public:
|
||||
scan_value(T value) : value_(std::move(value)) {}
|
||||
|
||||
const T& value() const { return value_; }
|
||||
auto value() const -> const T& { return value_; }
|
||||
};
|
||||
|
||||
// A rudimentary version of std::expected for testing the API shape.
|
||||
@ -651,7 +651,7 @@ template <typename T> class expected {
|
||||
public:
|
||||
expected(T value) : value_(std::move(value)) {}
|
||||
|
||||
const T* operator->() const { return &value_; }
|
||||
auto operator->() const -> const T* { return &value_; }
|
||||
};
|
||||
|
||||
template <typename T> using scan_result = expected<scan_value<T>>;
|
||||
@ -688,7 +688,7 @@ auto scan_to(InputRange&& input, string_view fmt, T&... args)
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
bool scan_to(FILE* f, string_view fmt, T&... args) {
|
||||
auto scan_to(FILE* f, string_view fmt, T&... args) -> bool {
|
||||
auto&& buf = detail::file_scan_buffer(f);
|
||||
vscan(buf, fmt, make_scan_args(args...));
|
||||
return buf.begin() != buf.end();
|
||||
|
Loading…
Reference in New Issue
Block a user