| 14250 | |
| 14251 | template <uint64_t base> |
| 14252 | TOML_NODISCARD |
| 14253 | TOML_NEVER_INLINE |
| 14254 | int64_t parse_integer() |
| 14255 | { |
| 14256 | return_if_error({}); |
| 14257 | assert_not_eof(); |
| 14258 | using traits = parse_integer_traits<base>; |
| 14259 | push_parse_scope(traits::scope_qualifier); |
| 14260 | |
| 14261 | [[maybe_unused]] int64_t sign = 1; |
| 14262 | if constexpr (traits::is_signed) |
| 14263 | { |
| 14264 | sign = *cp == U'-' ? -1 : 1; |
| 14265 | if (is_match(*cp, U'+', U'-')) |
| 14266 | advance_and_return_if_error_or_eof({}); |
| 14267 | } |
| 14268 | |
| 14269 | if constexpr (base == 10) |
| 14270 | { |
| 14271 | if (!traits::is_digit(*cp)) |
| 14272 | set_error_and_return_default("expected expected digit or sign, saw '"sv, to_sv(*cp), "'"sv); |
| 14273 | } |
| 14274 | else |
| 14275 | { |
| 14276 | // '0' |
| 14277 | if (*cp != U'0') |
| 14278 | set_error_and_return_default("expected '0', saw '"sv, to_sv(*cp), "'"sv); |
| 14279 | advance_and_return_if_error_or_eof({}); |
| 14280 | |
| 14281 | // 'b', 'o', 'x' |
| 14282 | if (*cp != traits::prefix_codepoint) |
| 14283 | set_error_and_return_default("expected '"sv, traits::prefix, "', saw '"sv, to_sv(*cp), "'"sv); |
| 14284 | advance_and_return_if_error_or_eof({}); |
| 14285 | |
| 14286 | if (!traits::is_digit(*cp)) |
| 14287 | set_error_and_return_default("expected digit, saw '"sv, to_sv(*cp), "'"sv); |
| 14288 | } |
| 14289 | |
| 14290 | // consume digits |
| 14291 | char digits[utf8_buffered_reader::max_history_length]; |
| 14292 | size_t length = {}; |
| 14293 | const utf8_codepoint* prev = {}; |
| 14294 | while (!is_eof() && !is_value_terminator(*cp)) |
| 14295 | { |
| 14296 | if (*cp == U'_') |
| 14297 | { |
| 14298 | if (!prev || !traits::is_digit(*prev)) |
| 14299 | set_error_and_return_default("underscores may only follow digits"sv); |
| 14300 | |
| 14301 | prev = cp; |
| 14302 | advance_and_return_if_error_or_eof({}); |
| 14303 | continue; |
| 14304 | } |
| 14305 | else if TOML_UNLIKELY(prev && *prev == U'_' && !traits::is_digit(*cp)) |
| 14306 | set_error_and_return_default("underscores must be followed by digits"sv); |
| 14307 | else if TOML_UNLIKELY(!traits::is_digit(*cp)) |
| 14308 | set_error_and_return_default("expected digit, saw '"sv, to_sv(*cp), "'"sv); |
| 14309 | else if TOML_UNLIKELY(length == sizeof(digits)) |
nothing calls this directly
no outgoing calls
no test coverage detected