public static bool TryParseInt32(ReadOnlySpan<byte> text, out int value, out int bytesConsumed)
{
int textLength = text.Length;
if (textLength < 1) goto FalseExit;
int sign = 1;
int index = default;
int num = text[index];
if (num == '-')
{
sign = -1;
index++;
if (index >= textLength) goto FalseExit;
num = text[index];
}
else if (num == '+')
{
index++;
if (index >= textLength) goto FalseExit;
num = text[index];
}
int answer = default;
if (IsDigit(num))
{
if (num == '0')
{
do
{
index++;
if (index >= textLength) goto Done;
num = text[index];
} while (num == '0');
if (!IsDigit(num)) goto Done;
}
int len = textLength - index;
if (len < Int32OverflowLength)
{
switch (len)
{
case 9:
answer = (num - '0');
index = textLength - 8;
num = text[index];
if (!IsDigit(num))
{
goto Done;
}
goto case 8;
case 8:
answer = answer * 10 + (num - '0');
index = textLength - 7;
num = text[index];
if (!IsDigit(num))
{
goto Done;
}
goto case 7;
case 7:
answer = answer * 10 + (num - '0');
index = textLength - 6;
num = text[index];
if (!IsDigit(num))
{
goto Done;
}
goto case 6;
case 6:
answer = answer * 10 + (num - '0');
index = textLength - 5;
num = text[index];
if (!IsDigit(num))
{
goto Done;
}
goto case 5;
case 5:
answer = answer * 10 + (num - '0');
index = textLength - 4;
num = text[index];
if (!IsDigit(num))
{
goto Done;
}
goto case 4;
case 4:
answer = answer * 10 + (num - '0');
index = textLength - 3;
num = text[index];
if (!IsDigit(num))
{
goto Done;
}
goto case 3;
case 3:
answer = answer * 10 + (num - '0');
index = textLength - 2;
num = text[index];
if (!IsDigit(num))
{
goto Done;
}
goto case 2;
case 2:
answer = answer * 10 + (num - '0');
index = textLength - 1;
num = text[index];
if (!IsDigit(num))
{
goto Done;
}
goto case 1;
case 1:
answer = answer * 10 + (num - '0');
index = textLength;
goto Done;
}
}
else if (len == Int32OverflowLength)
{
switch (Int32OverflowLength)
{
case 10:
answer = (num - '0');
num = text[textLength - 9];
if (!IsDigit(num))
{
index = index + Int32OverflowLength - 9;
goto Done;
}
goto case 9;
case 9:
answer = answer * 10 + (num - '0');
num = text[textLength - 8];
if (!IsDigit(num))
{
index = index + Int32OverflowLength - 8;
goto Done;
}
goto case 8;
case 8:
answer = answer * 10 + (num - '0');
num = text[textLength - 7];
if (!IsDigit(num))
{
index = index + Int32OverflowLength - 7;
goto Done;
}
goto case 7;
case 7:
answer = answer * 10 + (num - '0');
num = text[textLength - 6];
if (!IsDigit(num))
{
index = index + Int32OverflowLength - 6;
goto Done;
}
goto case 6;
case 6:
answer = answer * 10 + (num - '0');
num = text[textLength - 5];
if (!IsDigit(num))
{
index = index + Int32OverflowLength - 5;
goto Done;
}
goto case 5;
case 5:
answer = answer * 10 + (num - '0');
num = text[textLength - 4];
if (!IsDigit(num))
{
index = index + Int32OverflowLength - 4;
goto Done;
}
goto case 4;
case 4:
answer = answer * 10 + (num - '0');
num = text[textLength - 3];
if (!IsDigit(num))
{
index = index + Int32OverflowLength - 3;
goto Done;
}
goto case 3;
case 3:
answer = answer * 10 + (num - '0');
num = text[textLength - 2];
if (!IsDigit(num))
{
index = index + Int32OverflowLength - 2;
goto Done;
}
goto case 2;
case 2:
answer = answer * 10 + (num - '0');
num = text[textLength - 1];
if (!IsDigit(num))
{
index = index + Int32OverflowLength - 1;
goto Done;
}
goto case 1;
case 1:
num -= '0';
if (WillOverFlow(answer, num, sign)) goto FalseExit;
answer = answer * 10 + num;
index = index + Int32OverflowLength;
goto Done;
}
}
else
{
index += Int32OverflowLength;
switch (Int32OverflowLength)
{
case 10:
answer = (num - '0');
num = text[index - 9];
if (!IsDigit(num))
{
index -= 9;
goto Done;
}
goto case 9;
case 9:
answer = answer * 10 + (num - '0');
num = text[index - 8];
if (!IsDigit(num))
{
index -= 8;
goto Done;
}
goto case 8;
case 8:
answer = answer * 10 + (num - '0');
num = text[index - 7];
if (!IsDigit(num))
{
index -= 7;
goto Done;
}
goto case 7;
case 7:
answer = answer * 10 + (num - '0');
num = text[index - 6];
if (!IsDigit(num))
{
index -= 6;
goto Done;
}
goto case 6;
case 6:
answer = answer * 10 + (num - '0');
num = text[index - 5];
if (!IsDigit(num))
{
index -= 5;
goto Done;
}
goto case 5;
case 5:
answer = answer * 10 + (num - '0');
num = text[index - 4];
if (!IsDigit(num))
{
index -= 4;
goto Done;
}
goto case 4;
case 4:
answer = answer * 10 + (num - '0');
num = text[index - 3];
if (!IsDigit(num))
{
index -= 3;
goto Done;
}
goto case 3;
case 3:
answer = answer * 10 + (num - '0');
num = text[index - 2];
if (!IsDigit(num))
{
index -= 2;
goto Done;
}
goto case 2;
case 2:
answer = answer * 10 + (num - '0');
num = text[index - 1];
if (!IsDigit(num))
{
index -= 1;
goto Done;
}
goto case 1;
case 1:
num -= '0';
if (WillOverFlow(answer, num, sign) || IsDigit(text[index])) goto FalseExit;
answer = answer * 10 + num;
goto Done;
}
}
goto Done;
}
FalseExit:
bytesConsumed = default;
value = default;
return false;
Done:
bytesConsumed = index;
value = answer * sign;
return true;
}
Last active
June 24, 2017 04:23
-
-
Save ahsonkhan/dba0afb3304de15be844111d0f8a3ea6 to your computer and use it in GitHub Desktop.
Loop unrolled int 32 parser
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Disassembly
x86:
Current (no branch) - A:
Current (with branch) - D:
Combined (no branch) - B:
Combined (branch) - C: