dynamic parseNumber()

in folly/json.cpp [532:587]


dynamic parseNumber(Input& in) {
  bool const negative = (*in == '-');
  if (negative && in.consume("-Infinity")) {
    if (in.getOpts().parse_numbers_as_strings) {
      return "-Infinity";
    } else {
      return -std::numeric_limits<double>::infinity();
    }
  }

  auto integral = in.skipMinusAndDigits();
  if (negative && integral.size() < 2) {
    in.error("expected digits after `-'");
  }

  auto const wasE = *in == 'e' || *in == 'E';

  if (*in != '.' && !wasE && in.getOpts().parse_numbers_as_strings) {
    return integral;
  }

  constexpr const char* maxIntStr = "9223372036854775807";
  constexpr const char* minIntStr = "-9223372036854775808";
  constexpr auto maxIntLen = constexpr_strlen(maxIntStr);
  constexpr auto minIntLen = constexpr_strlen(minIntStr);
  auto extremaLen = negative ? minIntLen : maxIntLen;
  auto extremaStr = negative ? minIntStr : maxIntStr;
  if (*in != '.' && !wasE) {
    if (LIKELY(!in.getOpts().double_fallback || integral.size() < extremaLen) ||
        (integral.size() == extremaLen && integral <= extremaStr)) {
      auto val = to<int64_t>(integral);
      in.skipWhitespace();
      return val;
    } else {
      auto val = to<double>(integral);
      in.skipWhitespace();
      return val;
    }
  }

  auto end = !wasE ? (++in, in.skipDigits().end()) : in.begin();
  if (*in == 'e' || *in == 'E') {
    ++in;
    if (*in == '+' || *in == '-') {
      ++in;
    }
    auto expPart = in.skipDigits();
    end = expPart.end();
  }
  auto fullNum = range(integral.begin(), end);
  if (in.getOpts().parse_numbers_as_strings) {
    return fullNum;
  }
  auto val = to<double>(fullNum);
  return val;
}