| 14577 | |
| 14578 | template <uint64_t base> |
| 14579 | TOML_NODISCARD |
| 14580 | TOML_NEVER_INLINE |
| 14581 | int64_t parse_integer() |
| 14582 | { |
| 14583 | return_if_error({}); |
| 14584 | assert_not_eof(); |
| 14585 | using traits = parse_integer_traits<base>; |
| 14586 | push_parse_scope(traits::scope_qualifier); |
| 14587 | |
| 14588 | [[maybe_unused]] int64_t sign = 1; |
| 14589 | if constexpr (traits::is_signed) |
| 14590 | { |
| 14591 | sign = *cp == U'-' ? -1 : 1; |
| 14592 | if (is_match(*cp, U'+', U'-')) |
| 14593 | advance_and_return_if_error_or_eof({}); |
| 14594 | } |
| 14595 | |
| 14596 | if constexpr (base == 10) |
| 14597 | { |
| 14598 | if (!traits::is_digit(*cp)) |
| 14599 | set_error_and_return_default("expected expected digit or sign, saw '"sv, to_sv(*cp), "'"sv); |
| 14600 | } |
| 14601 | else |
| 14602 | { |
| 14603 | // '0' |
| 14604 | if (*cp != U'0') |
| 14605 | set_error_and_return_default("expected '0', saw '"sv, to_sv(*cp), "'"sv); |
| 14606 | advance_and_return_if_error_or_eof({}); |
| 14607 | |
| 14608 | // 'b', 'o', 'x' |
| 14609 | if (*cp != traits::prefix_codepoint) |
| 14610 | set_error_and_return_default("expected '"sv, traits::prefix, "', saw '"sv, to_sv(*cp), "'"sv); |
| 14611 | advance_and_return_if_error_or_eof({}); |
| 14612 | |
| 14613 | if (!traits::is_digit(*cp)) |
| 14614 | set_error_and_return_default("expected digit, saw '"sv, to_sv(*cp), "'"sv); |
| 14615 | } |
| 14616 | |
| 14617 | // consume digits |
| 14618 | char digits[utf8_buffered_reader::max_history_length]; |
| 14619 | size_t length = {}; |
| 14620 | const utf8_codepoint* prev = {}; |
| 14621 | while (!is_eof() && !is_value_terminator(*cp)) |
| 14622 | { |
| 14623 | if (*cp == U'_') |
| 14624 | { |
| 14625 | if (!prev || !traits::is_digit(*prev)) |
| 14626 | set_error_and_return_default("underscores may only follow digits"sv); |
| 14627 | |
| 14628 | prev = cp; |
| 14629 | advance_and_return_if_error_or_eof({}); |
| 14630 | continue; |
| 14631 | } |
| 14632 | else if TOML_UNLIKELY(prev && *prev == U'_' && !traits::is_digit(*cp)) |
| 14633 | set_error_and_return_default("underscores must be followed by digits"sv); |
| 14634 | else if TOML_UNLIKELY(!traits::is_digit(*cp)) |
| 14635 | set_error_and_return_default("expected digit, saw '"sv, to_sv(*cp), "'"sv); |
| 14636 | else if TOML_UNLIKELY(length == sizeof(digits)) |
nothing calls this directly
no outgoing calls
no test coverage detected