| 963 | // returns 1 (-1) if the first (second) condition is sufficient, 0 if indeterminate |
| 964 | template<typename T> |
| 965 | static int sufficientCondition(std::string op1, const bool not1, const T value1, std::string op2, const bool not2, const T value2, const bool isAnd) { |
| 966 | auto transformOp = [](std::string& op, const bool invert) { |
| 967 | if (invert) { |
| 968 | if (op == "==") |
| 969 | op = "!="; |
| 970 | else if (op == "!=") |
| 971 | op = "=="; |
| 972 | else if (op == "<") |
| 973 | op = ">="; |
| 974 | else if (op == ">") |
| 975 | op = "<="; |
| 976 | else if (op == "<=") |
| 977 | op = ">"; |
| 978 | else if (op == ">=") |
| 979 | op = "<"; |
| 980 | } |
| 981 | }; |
| 982 | transformOp(op1, not1); |
| 983 | transformOp(op2, not2); |
| 984 | int res = 0; |
| 985 | bool equal = false; |
| 986 | if (op1 == op2) { |
| 987 | equal = true; |
| 988 | if (op1 == ">" || op1 == ">=") |
| 989 | res = sign(value1 - value2); |
| 990 | else if (op1 == "<" || op1 == "<=") |
| 991 | res = -sign(value1 - value2); |
| 992 | } else { // not equal |
| 993 | if (op1 == "!=") |
| 994 | res = 1; |
| 995 | else if (op2 == "!=") |
| 996 | res = -1; |
| 997 | else if (op1 == "==") |
| 998 | res = -1; |
| 999 | else if (op2 == "==") |
| 1000 | res = 1; |
| 1001 | else if (op1 == ">" && op2 == ">=") |
| 1002 | res = sign(value1 - (value2 - 1)); |
| 1003 | else if (op1 == ">=" && op2 == ">") |
| 1004 | res = sign((value1 - 1) - value2); |
| 1005 | else if (op1 == "<" && op2 == "<=") |
| 1006 | res = -sign(value1 - (value2 + 1)); |
| 1007 | else if (op1 == "<=" && op2 == "<") |
| 1008 | res = -sign((value1 + 1) - value2); |
| 1009 | } |
| 1010 | return res * (isAnd == equal ? 1 : -1); |
| 1011 | } |
| 1012 | |
| 1013 | template<typename T> |
| 1014 | static bool checkIntRelation(const std::string &op, const T value1, const T value2) |
no test coverage detected