-template <class Tgt>
-inline typename std::enable_if<
- std::is_floating_point<Tgt>::value,
- Tgt>::type
-to(StringPiece *const src) {
- using namespace double_conversion;
- static StringToDoubleConverter
- conv(StringToDoubleConverter::ALLOW_TRAILING_JUNK
- | StringToDoubleConverter::ALLOW_LEADING_SPACES,
- 0.0,
- // return this for junk input string
- std::numeric_limits<double>::quiet_NaN(),
- nullptr, nullptr);
-
- FOLLY_RANGE_CHECK_STRINGPIECE(!src->empty(),
- "No digits found in input string", *src);
-
- int length;
- auto result = conv.StringToDouble(src->data(),
- static_cast<int>(src->size()),
- &length); // processed char count
-
- if (!std::isnan(result)) {
- src->advance(length);
- return result;
- }
-
- for (;; src->advance(1)) {
- if (src->empty()) {
- throw std::range_error("Unable to convert an empty string"
- " to a floating point value.");
- }
- if (!isspace(src->front())) {
- break;
- }
- }
-
- // Was that "inf[inity]"?
- if (src->size() >= 3 && toupper((*src)[0]) == 'I'
- && toupper((*src)[1]) == 'N' && toupper((*src)[2]) == 'F') {
- if (src->size() >= 8 &&
- toupper((*src)[3]) == 'I' &&
- toupper((*src)[4]) == 'N' &&
- toupper((*src)[5]) == 'I' &&
- toupper((*src)[6]) == 'T' &&
- toupper((*src)[7]) == 'Y') {
- src->advance(8);
- } else {
- src->advance(3);
- }
- return std::numeric_limits<Tgt>::infinity();
- }
-
- // Was that "-inf[inity]"?
- if (src->size() >= 4 && toupper((*src)[0]) == '-'
- && toupper((*src)[1]) == 'I' && toupper((*src)[2]) == 'N'
- && toupper((*src)[3]) == 'F') {
- if (src->size() >= 9 &&
- toupper((*src)[4]) == 'I' &&
- toupper((*src)[5]) == 'N' &&
- toupper((*src)[6]) == 'I' &&
- toupper((*src)[7]) == 'T' &&
- toupper((*src)[8]) == 'Y') {
- src->advance(9);
- } else {
- src->advance(4);
- }
- return -std::numeric_limits<Tgt>::infinity();
- }