Tidy up MathLib::isInt() - using a state machine approach
This commit is contained in:
parent
b10fce304e
commit
ab2f8bfba3
|
@ -251,10 +251,6 @@ bool MathLib::isOct(const std::string& s)
|
||||||
|
|
||||||
bool MathLib::isHex(const std::string& s)
|
bool MathLib::isHex(const std::string& s)
|
||||||
{
|
{
|
||||||
// return false, in case an empty string is provided
|
|
||||||
if (s.empty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
enum {START, PLUSMINUS, HEX_PREFIX, DIGIT, DIGITS} state = START;
|
enum {START, PLUSMINUS, HEX_PREFIX, DIGIT, DIGITS} state = START;
|
||||||
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
|
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
@ -403,45 +399,39 @@ bool MathLib::isBin(const std::string& s)
|
||||||
|
|
||||||
bool MathLib::isInt(const std::string & s)
|
bool MathLib::isInt(const std::string & s)
|
||||||
{
|
{
|
||||||
// perform prechecks:
|
// check for two known types: hexadecimal and octal
|
||||||
// ------------------
|
|
||||||
// first check, if a point is found, it is an floating point value
|
|
||||||
const std::string charsToIndicateAFloat=".eE";
|
|
||||||
if (s.find_last_of(charsToIndicateAFloat) != std::string::npos)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// remember position
|
|
||||||
unsigned long n = 0;
|
|
||||||
// eat up whitespace
|
|
||||||
while (std::isspace(s[n])) ++n;
|
|
||||||
|
|
||||||
// determine type
|
|
||||||
if (isHex(s) || isOct(s)) {
|
if (isHex(s) || isOct(s)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check sign
|
enum {START, PLUSMINUS, DIGIT, SUFFIX} state = START;
|
||||||
if (s[n] == '-' || s[n] == '+') ++n;
|
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
|
||||||
|
switch (state) {
|
||||||
// starts with digit
|
case START:
|
||||||
bool bStartsWithDigit=false;
|
if (*it == '+' || *it == '-')
|
||||||
while (std::isdigit(s[n])) {
|
state = PLUSMINUS;
|
||||||
bStartsWithDigit=true;
|
else if (isdigit(*it))
|
||||||
++n;
|
state = DIGIT;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case PLUSMINUS:
|
||||||
|
if (isdigit(*it))
|
||||||
|
state = DIGIT;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case DIGIT:
|
||||||
|
if (isdigit(*it))
|
||||||
|
state = DIGIT;
|
||||||
|
else
|
||||||
|
return isValidSuffix(it,s.end());
|
||||||
|
break;
|
||||||
|
case SUFFIX:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return state == DIGIT;
|
||||||
while (std::tolower(s[n]) == 'u' || std::tolower(s[n]) == 'l') ++n; // unsigned or long (long)
|
|
||||||
|
|
||||||
if (!bStartsWithDigit)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// eat up whitespace
|
|
||||||
while (std::isspace(s[n]))
|
|
||||||
++n;
|
|
||||||
|
|
||||||
// if everything goes good, we are at the end of the string and no digits/character
|
|
||||||
// is here --> return true, but if something was found e.g. 12E+12AA return false
|
|
||||||
return (n >= s.length());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MathLib::add(const std::string & first, const std::string & second)
|
std::string MathLib::add(const std::string & first, const std::string & second)
|
||||||
|
|
|
@ -29,9 +29,6 @@ public:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void run() {
|
void run() {
|
||||||
TEST_CASE(calculate);
|
|
||||||
TEST_CASE(calculate1);
|
|
||||||
TEST_CASE(convert);
|
|
||||||
TEST_CASE(isint);
|
TEST_CASE(isint);
|
||||||
TEST_CASE(isbin);
|
TEST_CASE(isbin);
|
||||||
TEST_CASE(isoct);
|
TEST_CASE(isoct);
|
||||||
|
@ -45,6 +42,9 @@ private:
|
||||||
TEST_CASE(isNotEqual)
|
TEST_CASE(isNotEqual)
|
||||||
TEST_CASE(isLess)
|
TEST_CASE(isLess)
|
||||||
TEST_CASE(isLessEqual)
|
TEST_CASE(isLessEqual)
|
||||||
|
TEST_CASE(calculate);
|
||||||
|
TEST_CASE(calculate1);
|
||||||
|
TEST_CASE(convert);
|
||||||
TEST_CASE(naninf)
|
TEST_CASE(naninf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,6 +440,7 @@ private:
|
||||||
ASSERT_EQUALS(false, MathLib::isOct("-042ULL "));
|
ASSERT_EQUALS(false, MathLib::isOct("-042ULL "));
|
||||||
// front and trailing white space
|
// front and trailing white space
|
||||||
ASSERT_EQUALS(false, MathLib::isOct(" -042ULL "));
|
ASSERT_EQUALS(false, MathLib::isOct(" -042ULL "));
|
||||||
|
ASSERT_EQUALS(false, MathLib::isOct("+042LUL+0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ishex() const {
|
void ishex() const {
|
||||||
|
@ -496,6 +497,9 @@ private:
|
||||||
ASSERT_EQUALS(false, MathLib::isHex("-0x0ULLz"));
|
ASSERT_EQUALS(false, MathLib::isHex("-0x0ULLz"));
|
||||||
ASSERT_EQUALS(false, MathLib::isHex("+0x0LLUz"));
|
ASSERT_EQUALS(false, MathLib::isHex("+0x0LLUz"));
|
||||||
ASSERT_EQUALS(false, MathLib::isHex("-0x0LLUz"));
|
ASSERT_EQUALS(false, MathLib::isHex("-0x0LLUz"));
|
||||||
|
ASSERT_EQUALS(false, MathLib::isHex("0x0+0"));
|
||||||
|
ASSERT_EQUALS(false, MathLib::isHex("e2"));
|
||||||
|
ASSERT_EQUALS(false, MathLib::isHex("+E2"));
|
||||||
|
|
||||||
// test empty string
|
// test empty string
|
||||||
ASSERT_EQUALS(false, MathLib::isHex(""));
|
ASSERT_EQUALS(false, MathLib::isHex(""));
|
||||||
|
|
Loading…
Reference in New Issue