bool CompAB(const TVar& a, const TVar& b, TVarFuncCmp fcmp) { bool r = true; __int64 bi; double bd; switch (a.vType) { case vtUnknown: case vtInteger: switch (b.vType) { case vtUnknown: case vtInteger: r = fcmp(vtInteger,&a.inum,&b.inum); break; case vtDouble: r = fcmp(vtDouble,&a.inum,&b.dnum); break; case vtString: { switch (checkTypeString(b.asString())) { case tsStr: r = fcmp(vtString,a.asString().data(),b.str.data()); break; case tsInt: bi=b.asInteger(); r = fcmp(vtInteger,&a.inum,&bi); break; case tsFloat: bd=b.asDouble(); r = fcmp(vtDouble,&a.inum,&bd); break; } break; } } break; case vtDouble: switch (b.vType) { case vtUnknown: case vtInteger: r = fcmp(vtInteger,&a.dnum,&b.inum); break; case vtDouble: r = fcmp(vtDouble,&a.dnum,&b.dnum); break; case vtString: { switch (checkTypeString(b.str)) { case tsStr: r = fcmp(vtString,a.asString().data(),b.str.data()); break; case tsInt: case tsFloat: bd=b.asDouble(); r = fcmp(vtDouble,&a.inum,&bd); break; } break; } } break; case vtString: { r = fcmp(vtString,a.asString().data(),b.asString().data()); break; } } return r; };
bool TVar::isNumber() const { switch (type()) { case vtUnknown: case vtInteger: case vtDouble: return true; case vtString: switch (checkTypeString(str)) { case tsInt: case tsFloat: return true; default: return false; } } return false; }
TVar operator%(const TVar& a, const TVar& b) { TVar r; switch (a.vType) { case vtUnknown: case vtInteger: { switch (b.vType) { case vtUnknown: case vtInteger: r = b.inum ? (a.inum % b.inum) : 0; break; case vtDouble: r = fabs(b.dnum) > DBL_EPSILON? fmod((double)a.inum, b.dnum) : 0.0; break; case vtString: { switch (checkTypeString(b.str)) { case tsStr: r = a; break; case tsInt: { __int64 bi=b.i(); r = bi ? a.inum % bi : 0; break; } case tsFloat: { double bd=b.d(); r = fabs(bd) > DBL_EPSILON? fmod((double)a.inum, bd) : 0.0; break; } } break; } } break; } case vtDouble: { switch (b.vType) { case vtUnknown: case vtInteger: r = b.inum ? fmod(a.dnum,(double)b.inum) : 0.0; break; case vtDouble: r = fabs(b.dnum) > DBL_EPSILON? fmod(a.dnum,b.dnum) : 0.0; break; case vtString: { switch (checkTypeString(b.str)) { case tsStr: r = a; break; case tsInt: case tsFloat: { double bd=b.d(); r = fabs(bd) > DBL_EPSILON? fmod(a.dnum, bd) : 0.0; break; } } break; } } break; } case vtString: { TypeString tsA=checkTypeString(a.str),tsB; if (b.vType == vtInteger || b.vType == vtUnknown) tsB=tsInt; else if (b.vType == vtDouble) tsB=tsFloat; else tsA=tsB=tsStr; if ((tsA == tsStr && tsB == tsStr) || (tsA != tsStr && tsB == tsStr) || (tsA == tsStr && tsB != tsStr)) r = a; else if (tsA == tsInt && tsB == tsInt) { __int64 bi=b.i(); r = bi ? (a.i() % bi) : 0; } else { double bd=b.d(); r = fabs(bd) > DBL_EPSILON? fmod(a.d() , bd) : 0.0; } break; } } return r; };
TVar operator*(const TVar& a, const TVar& b) { TVar r; switch (a.vType) { case vtUnknown: case vtInteger: { switch (b.vType) { case vtUnknown: case vtInteger: r = a.inum * b.inum; break; case vtDouble: r = (double)a.inum * b.dnum; break; case vtString: { switch (checkTypeString(b.str)) { case tsStr: r = a; break; case tsInt: r = a.inum * b.i(); break; case tsFloat: r = (double)a.inum * b.d(); break; } break; } } break; } case vtDouble: { switch (b.vType) { case vtUnknown: case vtInteger: r = a.dnum * (double)b.inum; break; case vtDouble: r = a.dnum * b.dnum; break; case vtString: { switch (checkTypeString(b.str)) { case tsStr: r = a; break; case tsInt: case tsFloat: r = a.dnum * b.d(); break; } break; } } break; } case vtString: { TypeString tsA=checkTypeString(a.str),tsB; if (b.vType == vtInteger || b.vType == vtUnknown) tsB=tsInt; else if (b.vType == vtDouble) tsB=tsFloat; else tsA=tsB=tsStr; if ((tsA == tsStr && tsB == tsStr) || (tsA != tsStr && tsB == tsStr) || (tsA == tsStr && tsB != tsStr)) r = a; else if (tsA == tsInt && tsB == tsInt) r = a.i() * b.i(); else r = a.d() * b.d(); break; } } return r; }
int TVar::CompAB(const TVar& a, const TVar& b, TVarFuncCmp fcmp) { int r = 1; __int64 bi; double bd; switch (a.vType) { case vtUnknown: case vtInteger: switch (b.vType) { case vtUnknown: case vtInteger: r = fcmp(vtInteger,&a.inum,&b.inum); break; case vtDouble: r = fcmp(vtDouble,&a.inum,&b.dnum); break; case vtString: { switch (checkTypeString(b.s())) { case tsStr: r = fcmp(vtString,a.s(),b.str); break; case tsInt: bi=b.i(); r = fcmp(vtInteger,&a.inum,&bi); break; case tsFloat: bd=b.d(); r = fcmp(vtDouble,&a.inum,&bd); break; } break; } } break; case vtDouble: switch (b.vType) { case vtUnknown: case vtInteger: r = fcmp(vtInteger,&a.dnum,&b.inum); break; case vtDouble: r = fcmp(vtDouble,&a.dnum,&b.dnum); break; case vtString: { switch (checkTypeString(b.str)) { case tsStr: r = fcmp(vtString,a.s(),b.str); break; case tsInt: case tsFloat: bd=b.d(); r = fcmp(vtDouble,&a.inum,&bd); break; } break; } } break; case vtString: { #if defined(TVAR_USE_STRMUN) __int64 bi; double bd; TypeString tsA=checkTypeString(a.str), tsB; if (b.vType == vtInteger || b.vType == vtUnknown) tsB=tsInt; else if (b.vType == vtDouble) tsB=tsFloat; else tsB=checkTypeString(b.str); if ((tsA == tsStr && tsB == tsStr) || (tsA != tsStr && tsB == tsStr) || (tsA == tsStr && tsB != tsStr)) r = fcmp(vtString,a.s(),b.s()); else if (tsA == tsInt && tsB == tsInt) { ai=a.i(); bi=b.i(); r = fcmp(vtInteger,&ai,&bi); } else { ad=a.d(); bd=b.d(); r = fcmp(vtDouble,&ad,&bd); } #else r = fcmp(vtString,a.s(),b.s()); #endif break; } } return r; };