from_chars_result parse_infnan()

in include/ylt/standalone/iguana/detail/fast_float.h [3084:3130]


from_chars_result parse_infnan(const char* first, const char* last,
                               T& value) noexcept {
  from_chars_result answer;
  answer.ptr = first;
  answer.ec = std::errc();  // be optimistic
  bool minusSign = false;
  if (*first == '-') {  // assume first < last, so dereference without checks;
                        // C++17 20.19.3.(7.1) explicitly forbids '+' here
    minusSign = true;
    ++first;
  }
  if (last - first >= 3) {
    if (fastfloat_strncasecmp(first, "nan", 3)) {
      answer.ptr = (first += 3);
      value = minusSign ? -std::numeric_limits<T>::quiet_NaN()
                        : std::numeric_limits<T>::quiet_NaN();
      // Check for possible nan(n-char-seq-opt), C++17 20.19.3.7,
      // C11 7.20.1.3.3. At least MSVC produces nan(ind) and nan(snan).
      if (first != last && *first == '(') {
        for (const char* ptr = first + 1; ptr != last; ++ptr) {
          if (*ptr == ')') {
            answer.ptr = ptr + 1;  // valid nan(n-char-seq-opt)
            break;
          }
          else if (!(('a' <= *ptr && *ptr <= 'z') ||
                     ('A' <= *ptr && *ptr <= 'Z') ||
                     ('0' <= *ptr && *ptr <= '9') || *ptr == '_'))
            break;  // forbidden char, not nan(n-char-seq-opt)
        }
      }
      return answer;
    }
    if (fastfloat_strncasecmp(first, "inf", 3)) {
      if ((last - first >= 8) && fastfloat_strncasecmp(first + 3, "inity", 5)) {
        answer.ptr = first + 8;
      }
      else {
        answer.ptr = first + 3;
      }
      value = minusSign ? -std::numeric_limits<T>::infinity()
                        : std::numeric_limits<T>::infinity();
      return answer;
    }
  }
  answer.ec = std::errc::invalid_argument;
  return answer;
}