154 lines
3.0 KiB
C++
154 lines
3.0 KiB
C++
#include <NumberParsing.h>
|
|
|
|
usize _atou(const char** str)
|
|
{
|
|
usize val = 0;
|
|
|
|
while (_isdigit(**str))
|
|
{
|
|
val = (10 * val) + (**str - '0');
|
|
(*str)++;
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
isize _atos(const char** str)
|
|
{
|
|
bool neg = false;
|
|
isize val = 0;
|
|
|
|
switch (**str)
|
|
{
|
|
case '-':
|
|
neg = true;
|
|
(*str)++;
|
|
break;
|
|
case '+': (*str)++; break;
|
|
default: break;
|
|
}
|
|
|
|
while (_isdigit(**str))
|
|
{
|
|
val = (10 * val) + (**str - '0');
|
|
(*str)++;
|
|
}
|
|
|
|
return neg ? -val : val;
|
|
}
|
|
|
|
usize _strtou(const char* str, const char** endptr, int base)
|
|
{
|
|
usize val = 0;
|
|
|
|
auto valid_digit = [](int _base, char c) -> bool {
|
|
if (_base <= 10)
|
|
{
|
|
if (!_isdigit(c)) return false;
|
|
if ((c - '0') < _base) return true;
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
if (!_isalnum(c)) return false;
|
|
if (_isdigit(c)) return true;
|
|
bool lower = _islower(c);
|
|
if (((c - lower ? 'a' : 'A') + 10) < _base) return true;
|
|
return false;
|
|
}
|
|
};
|
|
|
|
auto to_digit = [](char c) -> usize {
|
|
if (_isdigit(c)) return c - '0';
|
|
if (_islower(c)) return (c - 'a') + 10;
|
|
return (c - 'A') + 10;
|
|
};
|
|
|
|
while (_isspace(*str)) str++;
|
|
|
|
if ((base == 0 || base == 16) && *str == '0')
|
|
{
|
|
str++;
|
|
if (_tolower(*str) == 'x')
|
|
{
|
|
base = 16;
|
|
str++;
|
|
}
|
|
else if (base == 0)
|
|
base = 8;
|
|
}
|
|
else if (base == 0)
|
|
base = 10;
|
|
|
|
while (valid_digit(base, *str))
|
|
{
|
|
val = (base * val) + to_digit(*str);
|
|
str++;
|
|
}
|
|
|
|
if (endptr) *endptr = str;
|
|
|
|
return val;
|
|
}
|
|
|
|
isize _strtoi(const char* str, const char** endptr, int base)
|
|
{
|
|
isize val = 0;
|
|
bool negative = false;
|
|
|
|
auto valid_digit = [](int _base, char c) -> bool {
|
|
if (_base <= 10)
|
|
{
|
|
if (!_isdigit(c)) return false;
|
|
if ((c - '0') < _base) return true;
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
if (!_isalnum(c)) return false;
|
|
if (_isdigit(c)) return true;
|
|
bool lower = _islower(c);
|
|
if (((c - lower ? 'a' : 'A') + 10) < _base) return true;
|
|
return false;
|
|
}
|
|
};
|
|
|
|
auto to_digit = [](char c) -> isize {
|
|
if (_isdigit(c)) return c - '0';
|
|
if (_islower(c)) return (c - 'a') + 10;
|
|
return (c - 'A') + 10;
|
|
};
|
|
|
|
while (_isspace(*str)) str++;
|
|
|
|
if (*str == '-' || *str == '+')
|
|
{
|
|
if (*str == '-') negative = true;
|
|
str++;
|
|
}
|
|
|
|
if ((base == 0 || base == 16) && *str == '0')
|
|
{
|
|
str++;
|
|
if (_tolower(*str) == 'x')
|
|
{
|
|
base = 16;
|
|
str++;
|
|
}
|
|
else if (base == 0)
|
|
base = 8;
|
|
}
|
|
else if (base == 0)
|
|
base = 10;
|
|
|
|
while (valid_digit(base, *str))
|
|
{
|
|
val = (base * val) + to_digit(*str);
|
|
str++;
|
|
}
|
|
|
|
if (endptr) *endptr = str;
|
|
|
|
return negative ? -val : val;
|
|
}
|