| 13918 | TOML_NODISCARD |
| 13919 | TOML_NEVER_INLINE |
| 13920 | double parse_float() |
| 13921 | { |
| 13922 | return_if_error({}); |
| 13923 | assert_not_eof(); |
| 13924 | TOML_ASSERT_ASSUME(is_match(*cp, U'+', U'-', U'.') || is_decimal_digit(*cp)); |
| 13925 | push_parse_scope("floating-point"sv); |
| 13926 | |
| 13927 | // sign |
| 13928 | const int sign = *cp == U'-' ? -1 : 1; |
| 13929 | if (is_match(*cp, U'+', U'-')) |
| 13930 | advance_and_return_if_error_or_eof({}); |
| 13931 | |
| 13932 | // consume value chars |
| 13933 | char chars[utf8_buffered_reader::max_history_length]; |
| 13934 | size_t length = {}; |
| 13935 | const utf8_codepoint* prev = {}; |
| 13936 | bool seen_decimal = false, seen_exponent = false; |
| 13937 | char first_integer_part = '\0'; |
| 13938 | while (!is_eof() && !is_value_terminator(*cp)) |
| 13939 | { |
| 13940 | if (*cp == U'_') |
| 13941 | { |
| 13942 | if (!prev || !is_decimal_digit(*prev)) |
| 13943 | set_error_and_return_default("underscores may only follow digits"sv); |
| 13944 | |
| 13945 | prev = cp; |
| 13946 | advance_and_return_if_error_or_eof({}); |
| 13947 | continue; |
| 13948 | } |
| 13949 | else if TOML_UNLIKELY(prev && *prev == U'_' && !is_decimal_digit(*cp)) |
| 13950 | set_error_and_return_default("underscores must be followed by digits"sv); |
| 13951 | else if TOML_UNLIKELY(length == sizeof(chars)) |
| 13952 | set_error_and_return_default("exceeds length limit of "sv, |
| 13953 | sizeof(chars), |
| 13954 | " digits"sv, |
| 13955 | (seen_exponent ? ""sv : " (consider using exponent notation)"sv)); |
| 13956 | else if (*cp == U'.') |
| 13957 | { |
| 13958 | // .1 |
| 13959 | // -.1 |
| 13960 | // +.1 (no integer part) |
| 13961 | if (!first_integer_part) |
| 13962 | set_error_and_return_default("expected decimal digit, saw '.'"sv); |
| 13963 | |
| 13964 | // 1.0e+.10 (exponent cannot have '.') |
| 13965 | else if (seen_exponent) |
| 13966 | set_error_and_return_default("expected exponent decimal digit or sign, saw '.'"sv); |
| 13967 | |
| 13968 | // 1.0.e+.10 |
| 13969 | // 1..0 |
| 13970 | // (multiple '.') |
| 13971 | else if (seen_decimal) |
| 13972 | set_error_and_return_default("expected decimal digit or exponent, saw '.'"sv); |
| 13973 | |
| 13974 | seen_decimal = true; |
| 13975 | } |
| 13976 | else if (is_match(*cp, U'e', U'E')) |
| 13977 | { |
nothing calls this directly
no outgoing calls
no test coverage detected