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;
}