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)
|
||||
{
|
||||
// return false, in case an empty string is provided
|
||||
if (s.empty())
|
||||
return false;
|
||||
|
||||
enum {START, PLUSMINUS, HEX_PREFIX, DIGIT, DIGITS} state = START;
|
||||
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
|
||||
switch (state) {
|
||||
|
@ -403,45 +399,39 @@ bool MathLib::isBin(const std::string& s)
|
|||
|
||||
bool MathLib::isInt(const std::string & s)
|
||||
{
|
||||
// perform prechecks:
|
||||
// ------------------
|
||||
// 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
|
||||
// check for two known types: hexadecimal and octal
|
||||
if (isHex(s) || isOct(s)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// check sign
|
||||
if (s[n] == '-' || s[n] == '+') ++n;
|
||||
|
||||
// starts with digit
|
||||
bool bStartsWithDigit=false;
|
||||
while (std::isdigit(s[n])) {
|
||||
bStartsWithDigit=true;
|
||||
++n;
|
||||
enum {START, PLUSMINUS, DIGIT, SUFFIX} state = START;
|
||||
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
|
||||
switch (state) {
|
||||
case START:
|
||||
if (*it == '+' || *it == '-')
|
||||
state = PLUSMINUS;
|
||||
else if (isdigit(*it))
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
return state == DIGIT;
|
||||
}
|
||||
|
||||
std::string MathLib::add(const std::string & first, const std::string & second)
|
||||
|
|
|
@ -29,9 +29,6 @@ public:
|
|||
private:
|
||||
|
||||
void run() {
|
||||
TEST_CASE(calculate);
|
||||
TEST_CASE(calculate1);
|
||||
TEST_CASE(convert);
|
||||
TEST_CASE(isint);
|
||||
TEST_CASE(isbin);
|
||||
TEST_CASE(isoct);
|
||||
|
@ -45,6 +42,9 @@ private:
|
|||
TEST_CASE(isNotEqual)
|
||||
TEST_CASE(isLess)
|
||||
TEST_CASE(isLessEqual)
|
||||
TEST_CASE(calculate);
|
||||
TEST_CASE(calculate1);
|
||||
TEST_CASE(convert);
|
||||
TEST_CASE(naninf)
|
||||
}
|
||||
|
||||
|
@ -440,6 +440,7 @@ private:
|
|||
ASSERT_EQUALS(false, MathLib::isOct("-042ULL "));
|
||||
// front and trailing white space
|
||||
ASSERT_EQUALS(false, MathLib::isOct(" -042ULL "));
|
||||
ASSERT_EQUALS(false, MathLib::isOct("+042LUL+0"));
|
||||
}
|
||||
|
||||
void ishex() const {
|
||||
|
@ -496,6 +497,9 @@ private:
|
|||
ASSERT_EQUALS(false, MathLib::isHex("-0x0ULLz"));
|
||||
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
|
||||
ASSERT_EQUALS(false, MathLib::isHex(""));
|
||||
|
|
Loading…
Reference in New Issue