// File: /workspace/github_cpp_makefile_star2_O2/alan0201tw[P]RayTracer/include/tiny_obj_loader.h
// Function: tinyobj::tryParseDouble(char const*, char const*, double*)
static bool tryParseDouble(const char *s, const char *s_end, double *result) {
  if (s >= s_end) {
    return false;
  }

  double mantissa = 0.0;
  // This exponent is base 2 rather than 10.
  // However the exponent we parse is supposed to be one of ten,
  // thus we must take care to convert the exponent/and or the
  // mantissa to a * 2^E, where a is the mantissa and E is the
  // exponent.
  // To get the final double we will use ldexp, it requires the
  // exponent to be in base 2.
  int exponent = 0;

  // NOTE: THESE MUST BE DECLARED HERE SINCE WE ARE NOT ALLOWED
  // TO JUMP OVER DEFINITIONS.
  char sign = '+';
  char exp_sign = '+';
  char const *curr = s;

  // How many characters were read in a loop.
  int read = 0;
  // Tells whether a loop terminated due to reaching s_end.
  bool end_not_reached = false;
  bool leading_decimal_dots = false;

  /*
          BEGIN PARSING.
  */

  // Find out what sign we've got.
  if (*curr == '+' || *curr == '-') {
    sign = *curr;
    curr++;
    if ((curr != s_end) && (*curr == '.')) {
      // accept. Somethig like `.7e+2`, `-.5234`
      leading_decimal_dots = true;
    }
  } else if (IS_DIGIT(*curr)) { /* Pass through. */
  } else if (*curr == '.') {
    // accept. Somethig like `.7e+2`, `-.5234`
    leading_decimal_dots = true;
  } else {
    goto fail;
  }

  // Read the integer part.
  end_not_reached = (curr != s_end);
  if (!leading_decimal_dots) {
    while (end_not_reached && IS_DIGIT(*curr)) {
      mantissa *= 10;
      mantissa += static_cast<int>(*curr - 0x30);
      curr++;
      read++;
      end_not_reached = (curr != s_end);
    }
  }

  // We must make sure we actually got something.
  if (!leading_decimal_dots) {
    if (read == 0) goto fail;
  }

  // We allow numbers of form "#", "###" etc.
  if (!end_not_reached) goto assemble;

  // Read the decimal part.
  if (*curr == '.') {
    curr++;
    read = 1;
    end_not_reached = (curr != s_end);
    while (end_not_reached && IS_DIGIT(*curr)) {
      static const double pow_lut[] = {
          1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001,
      };
      const int lut_entries = sizeof pow_lut / sizeof pow_lut[0];

      // NOTE: Don't use powf here, it will absolutely murder precision.
      mantissa += static_cast<int>(*curr - 0x30) *
                  (read < lut_entries ? pow_lut[read] : std::pow(10.0, -read));
      read++;
      curr++;
      end_not_reached = (curr != s_end);
    }
  } else if (*curr == 'e' || *curr == 'E') {
  } else {
    goto assemble;
  }

  if (!end_not_reached) goto assemble;

  // Read the exponent part.
  if (*curr == 'e' || *curr == 'E') {
    curr++;
    // Figure out if a sign is present and if it is.
    end_not_reached = (curr != s_end);
    if (end_not_reached && (*curr == '+' || *curr == '-')) {
      exp_sign = *curr;
      curr++;
    } else if (IS_DIGIT(*curr)) { /* Pass through. */
    } else {
      // Empty E is not allowed.
      goto fail;
    }

    read = 0;
    end_not_reached = (curr != s_end);
    while (end_not_reached && IS_DIGIT(*curr)) {
      exponent *= 10;
      exponent += static_cast<int>(*curr - 0x30);
      curr++;
      read++;
      end_not_reached = (curr != s_end);
    }
    exponent *= (exp_sign == '+' ? 1 : -1);
    if (read == 0) goto fail;
  }

assemble:
  *result = (sign == '+' ? 1 : -1) *
            (exponent ? std::ldexp(mantissa * std::pow(5.0, exponent), exponent)
                      : mantissa);
  return true;
fail:
  return false;
}

// Assembly:
cmpq %rsi, %rdi
jae 0x16086
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdx, %rbx
movq %rsi, %r14
movq %rdi, %r15
movzbl (%rdi), %r12d
cmpl $0x2d, %r12d
je 0x1606d
cmpl $0x2b, %r12d
jne 0x16089
incq %r15
cmpq %r14, %r15
je 0x16098
movb $0x1, %al
xorpd %xmm2, %xmm2
cmpb $0x2e, (%r15)
jne 0x1609e
jmp 0x16116
xorl %eax, %eax
retq
movsbl %r12b, %eax
addl $-0x30, %eax
cmpl $0xa, %eax
jae 0x160e6
movb $0x2b, %r12b
cmpq %r14, %r15
setne %al
xorpd %xmm2, %xmm2
xorl %ecx, %ecx
movsd 0x1a454(%rip), %xmm0    # 0x30500
testb $0x1, %al
je 0x160d5
movsbl (%r15), %edx
addl $-0x30, %edx
cmpl $0x9, %edx
ja 0x160d5
mulsd %xmm0, %xmm2
cvtsi2sd %edx, %xmm1
addsd %xmm1, %xmm2
incq %r15
cmpq %r14, %r15
setne %al
decl %ecx
jmp 0x160ac
testl %ecx, %ecx
je 0x16263
testb $0x1, %al
jne 0x160f7
jmp 0x1624d
cmpb $0x2e, %r12b
jne 0x16263
xorpd %xmm2, %xmm2
movb $0x2b, %r12b
movzbl (%r15), %ecx
cmpl $0x65, %ecx
je 0x16192
cmpl $0x45, %ecx
je 0x16192
cmpl $0x2e, %ecx
jne 0x1624d
movl %r12d, 0x4(%rsp)
movq %rbx, 0x8(%rsp)
pushq $0x1
popq %r13
pushq $-0x1
popq %rbp
leaq 0x1ad42(%rip), %rbx     # 0x30e70
leaq (%r15,%r13), %rax
cmpq %r14, %rax
je 0x16183
movsbl (%rax), %ecx
leal -0x30(%rcx), %r12d
cmpl $0x9, %r12d
ja 0x16197
cmpq $0x7, %r13
ja 0x16152
movsd (%rbx,%r13,8), %xmm0
jmp 0x1616f
cvtsi2sd %ebp, %xmm1
movsd 0x1a3a2(%rip), %xmm0    # 0x30500
movapd %xmm2, 0x10(%rsp)
callq 0x6700
movapd 0x10(%rsp), %xmm2
cvtsi2sd %r12d, %xmm1
mulsd %xmm0, %xmm1
addsd %xmm1, %xmm2
incq %r13
decl %ebp
jmp 0x1612e
movq 0x8(%rsp), %rbx
movl 0x4(%rsp), %r12d
jmp 0x1624d
movq %r15, %rax
jmp 0x161a1
movq 0x8(%rsp), %rbx
movl 0x4(%rsp), %r12d
movzbl %cl, %ecx
orl $0x20, %ecx
cmpl $0x65, %ecx
jne 0x1624d
leaq 0x1(%rax), %rcx
movsbl 0x1(%rax), %edx
cmpq %r14, %rcx
je 0x161e2
cmpb $0x2d, %dl
je 0x161ca
movzbl %dl, %esi
cmpl $0x2b, %esi
jne 0x161e2
addq $0x2, %rax
xorl %ecx, %ecx
cmpb $0x2b, %dl
sete %cl
leal -0x1(,%rcx,2), %edx
movq %rax, %rcx
jmp 0x161ed
addl $-0x30, %edx
cmpl $0x9, %edx
ja 0x16263
pushq $0x1
popq %rdx
movl %r14d, %eax
subl %ecx, %eax
xorl %esi, %esi
xorl %ebp, %ebp
leaq (%rcx,%rsi), %rdi
cmpq %r14, %rdi
je 0x1621a
movsbl (%rdi), %edi
addl $-0x30, %edi
cmpl $0x9, %edi
ja 0x16218
imull $0xa, %ebp, %r8d
addl %r8d, %edi
incq %rsi
movl %edi, %ebp
jmp 0x161f6
movl %esi, %eax
testl %eax, %eax
je 0x16263
testl %ebp, %ebp
je 0x1624d
imull %edx, %ebp
cvtsi2sd %ebp, %xmm1
movsd 0x1a287(%rip), %xmm0    # 0x304b8
movapd %xmm2, 0x10(%rsp)
callq 0x6700
mulsd 0x10(%rsp), %xmm0
movl %ebp, %edi
callq 0x65f0
movapd %xmm0, %xmm2
cmpb $0x2b, %r12b
je 0x1625b
xorpd 0x1a525(%rip), %xmm2    # 0x30780
movsd %xmm2, (%rbx)
movb $0x1, %al
jmp 0x16265
xorl %eax, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq