diff --git a/lib/mathlib.cpp b/lib/mathlib.cpp index 16a0c1c94..9667414d4 100644 --- a/lib/mathlib.cpp +++ b/lib/mathlib.cpp @@ -25,6 +25,101 @@ #include #include +MathLib::biguint MathLib::toULongNumber(const std::string & str) { + // hexadecimal numbers: + if (isHex(str)) { + if (str[0] == '-') { + biguint ret = 0; + std::istringstream istr(str); + istr >> std::hex >> ret; + return ret; + } else { + unsigned long long ret = 0; + std::istringstream istr(str); + istr >> std::hex >> ret; + return (biguint)ret; + } + } + + // octal numbers: + if (isOct(str)) { + biguint ret = 0; + std::istringstream istr(str); + istr >> std::oct >> ret; + return ret; + } + + // binary numbers: + if (isBin(str)) { + biguint ret = 0; + for (std::string::size_type i = str[0] == '0'?2:3; i < str.length(); i++) { + ret <<= 1; + if (str[i] == '1') + ret |= 1; + } + /* if (str[0] == '-') + ret = -ret; */ + return ret; + } + + if (isFloat(str)) { + return static_cast(std::atof(str.c_str())); + } + + biguint ret = 0; + std::istringstream istr(str); + istr >> ret; + return ret; +} + +MathLib::bigint MathLib::toLongNumber(const std::string & str) { + // hexadecimal numbers: + if (isHex(str)) { + if (str[0] == '-') { + bigint ret = 0; + std::istringstream istr(str); + istr >> std::hex >> ret; + return ret; + } else { + unsigned long long ret = 0; + std::istringstream istr(str); + istr >> std::hex >> ret; + return (bigint)ret; + } + } + + // octal numbers: + if (isOct(str)) { + bigint ret = 0; + std::istringstream istr(str); + istr >> std::oct >> ret; + return ret; + } + + // binary numbers: + if (isBin(str)) { + bigint ret = 0; + for (std::string::size_type i = str[0] == '0'?2:3; i < str.length(); i++) { + ret <<= 1; + if (str[i] == '1') + ret |= 1; + } + if (str[0] == '-') + ret = -ret; + return ret; + } + + if (isFloat(str)) { + return static_cast(std::atof(str.c_str())); + } + + bigint ret = 0; + std::istringstream istr(str); + istr >> ret; + return ret; +} + + double MathLib::toDoubleNumber(const std::string &str) { if (isHex(str)) diff --git a/lib/mathlib.h b/lib/mathlib.h index bd4aacbd5..35254a3af 100644 --- a/lib/mathlib.h +++ b/lib/mathlib.h @@ -24,7 +24,6 @@ #include #include #include -#include #include "config.h" /// @addtogroup Core @@ -37,54 +36,8 @@ public: typedef long long bigint; typedef unsigned long long biguint; - template < class T = bigint > - static T toLongNumber(const std::string & str) { - // hexadecimal numbers: - if (isHex(str)) { - if (str[0] == '-') { - T ret = 0; - std::istringstream istr(str); - istr >> std::hex >> ret; - return ret; - } else { - unsigned long long ret = 0; - std::istringstream istr(str); - istr >> std::hex >> ret; - return (T)ret; - } - } - - // octal numbers: - if (isOct(str)) { - T ret = 0; - std::istringstream istr(str); - istr >> std::oct >> ret; - return ret; - } - - // binary numbers: - if (isBin(str)) { - T ret = 0; - for (std::string::size_type i = str[0] == '0'?2:3; i < str.length(); i++) { - ret <<= 1; - if (str[i] == '1') - ret |= 1; - } - if (std::is_signed()) { - if (str[0] == '-') - ret = -ret; - } - return ret; - } - - if (isFloat(str)) - return static_cast(std::atof(str.c_str())); - - T ret = 0; - std::istringstream istr(str); - istr >> ret; - return ret; - } + static bigint toLongNumber(const std::string & str); + static biguint toULongNumber(const std::string & str); template static std::string toString(T value) { std::ostringstream result; diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 55b1d4364..153666a15 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -800,20 +800,35 @@ static bool isLowerEqualThanMulDiv(const Token* lower) return isLowerThanMulDiv(lower) || Token::Match(lower, "[*/%]"); } -template -std::string typeCorrectShift(const char cop, const Token* left, const Token* right) +static std::string ShiftInt(const char cop, const Token* left, const Token* right) { - const T leftInt=MathLib::toLongNumber(left->str()); - const T rightInt=MathLib::toLongNumber(right->str()); - if (cop == '&' || cop == '|' || cop == '^') return MathLib::calculate(left->str(), right->str(), cop); - else if (cop == '<') { + + const MathLib::bigint leftInt=MathLib::toLongNumber(left->str()); + const MathLib::bigint rightInt=MathLib::toLongNumber(right->str()); + if (cop == '<') { if (left->previous()->str() != "<<" && rightInt > 0) // Ensure that its not a shift operator as used for streams return MathLib::toString(leftInt << rightInt); - } else if (rightInt > 0) + } else if (rightInt > 0) { return MathLib::toString(leftInt >> rightInt); + } + return ""; +} +static std::string ShiftUInt(const char cop, const Token* left, const Token* right) +{ + if (cop == '&' || cop == '|' || cop == '^') + return MathLib::calculate(left->str(), right->str(), cop); + + const MathLib::biguint leftInt=MathLib::toULongNumber(left->str()); + const MathLib::biguint rightInt=MathLib::toULongNumber(right->str()); + if (cop == '<') { + if (left->previous()->str() != "<<") // Ensure that its not a shift operator as used for streams + return MathLib::toString(leftInt << rightInt); + } else { + return MathLib::toString(leftInt >> rightInt); + } return ""; } @@ -846,9 +861,9 @@ bool TemplateSimplifier::simplifyNumericCalculations(Token *tok) const char cop = op->str()[0]; std::string result; if (tok->str().find_first_of("uU") != std::string::npos) - result = typeCorrectShift(cop, tok, tok->tokAt(2)); + result = ShiftUInt(cop, tok, tok->tokAt(2)); else - result = typeCorrectShift(cop, tok, tok->tokAt(2)); + result = ShiftInt(cop, tok, tok->tokAt(2)); if (!result.empty()) { ret = true; tok->str(result);