json_never_inline T decode_integer_tricky()

in include/spotify/json/codec/number.hpp [278:321]


json_never_inline T decode_integer_tricky(decode_context &context, const char *int_beg) {
  // Find [xxxx].yyyyE±zzzz
  auto int_end = find_non_digit(int_beg, context.end);
  context.position = int_end;

  // Find xxxx.[yyyy]E±zzzz
  auto dec_beg = int_end;
  auto dec_end = int_end;
  if (peek(context) == '.') {
    skip_unchecked_1(context);
    dec_beg = context.position;
    dec_end = find_non_digit(dec_beg, context.end);
    fail_if(context, dec_beg == dec_end, "Invalid digits after decimal point");
    context.position = dec_end;
  }

  // Find xxxx.yyyyE[±zzzz]
  auto exp_is_positive = true;
  auto exp_beg = dec_end;
  auto exp_end = dec_end;
  const auto e = peek(context);
  if (e == 'e' || e == 'E') {
    skip_unchecked_1(context);
    const auto sign = peek(context);
    if (sign == '-' || sign == '+') {
      exp_is_positive = (sign == '+');
      skip_unchecked_1(context);
    }
    exp_beg = context.position;
    exp_end = find_non_digit(exp_beg, context.end);
    fail_if(context, exp_beg == exp_end, "Exponent symbols should be followed by an optional '+' or '-' and then by at least one number");
    context.position = exp_end;
  }

  bool did_overflow = false;
  const auto exp = decode_integer_range_with_overflow<unsigned, true>(context, exp_beg, exp_end, 0, did_overflow);
  if (json_unlikely(did_overflow)) {
    return handle_overflowing_exponent<T>(context, exp_is_positive, int_beg, int_end, dec_beg, dec_end);
  }

  return (json_likely(exp_is_positive) ?
      decode_with_positive_exponent<T, is_positive>(context, exp, int_beg, int_end, dec_beg, dec_end) :
      decode_with_negative_exponent<T, is_positive>(context, exp, int_beg, int_end));
}