📄 variant.cpp
字号:
Variant Variant::operator++(int)
{
Variant v = *this;
switch (vt) {
case VT_UI1:
bVal++;
break;
case VT_I2:
iVal++;
break;
case VT_I4:
lVal++;
break;
case VT_R4:
fltVal++;
break;
case VT_R8:
dblVal++;
break;
case VT_CY:
cyVal.int64++;
break;
default:
throw DISP_E_TYPEMISMATCH;
}
return v;
}
// -
const Variant& Variant::operator-=(Variant v)
{
if (Variant::Preciser(vt, v.vt)) {
switch (vt) {
case VT_UI1:
bVal -= (BYTE)v;
break;
case VT_I2:
iVal -= (short)v;
break;
case VT_I4:
lVal -= (long)v;
break;
case VT_R4:
fltVal -= (float)v;
break;
case VT_R8:
dblVal -= (double)v;
break;
case VT_CY:
cyVal.int64 -= (LONGLONG)v;
break;
default:
throw DISP_E_TYPEMISMATCH;
break;
}
} else {
Type(v.vt);
switch (v.vt) {
case VT_UI1:
bVal -= v.bVal;
break;
case VT_I2:
iVal -= v.iVal;
break;
case VT_I4:
lVal -= v.lVal;
break;
case VT_R4:
fltVal -= v.fltVal;
break;
case VT_R8:
dblVal -= v.dblVal;
break;
case VT_CY:
cyVal.int64 -= v.cyVal.int64;
break;
default:
throw DISP_E_TYPEMISMATCH;
break;
}
}
return *this;
}
Variant operator-(Variant& v1, Variant& v2)
{
if (Variant::Preciser(v1.vt, v2.vt)) {
switch (v1.vt) {
case VT_UI1:
return short(v1.bVal - (BYTE)v2);
case VT_I2:
return long(v1.iVal - (short)v2);
case VT_I4:
return v1.lVal - (long)v2;
case VT_R4:
return v1.fltVal - (float)v2;
case VT_R8:
return v1.dblVal - (double)v2;
case VT_CY:
return v1.cyVal.int64 - (LONGLONG)v2;
default:
throw DISP_E_TYPEMISMATCH;
return 0L;
}
} else {
switch (v2.vt) {
case VT_UI1:
return short((BYTE)v2 - v2.bVal);
case VT_I2:
return long((short)v2 - v2.iVal);
case VT_I4:
return (long)v1 - v2.lVal;
case VT_R4:
return (float)v1 - v2.fltVal;
case VT_R8:
return (double)v1 - v2.dblVal;
case VT_CY:
return (LONGLONG)v1 - v2.cyVal.int64;
default:
throw DISP_E_TYPEMISMATCH;
return 0L;
}
}
}
// Prefix
Variant & Variant::operator--()
{
switch (vt) {
case VT_UI1:
--bVal;
break;
case VT_I2:
--iVal;
break;
case VT_I4:
--lVal;
break;
case VT_R4:
--fltVal;
break;
case VT_R8:
--dblVal;
break;
case VT_CY:
--cyVal.int64;
break;
default:
throw DISP_E_TYPEMISMATCH;
}
return *this;
}
// Postfix
Variant Variant::operator--(int)
{
Variant v = *this;
switch (vt) {
case VT_UI1:
bVal--;
break;
case VT_I2:
iVal--;
break;
case VT_I4:
lVal--;
break;
case VT_R4:
fltVal--;
break;
case VT_R8:
dblVal--;
break;
case VT_CY:
cyVal.int64--;
break;
default:
throw DISP_E_TYPEMISMATCH;
}
return v;
}
// *
const Variant& Variant::operator*=(Variant v)
{
if (Variant::Preciser(vt, v.vt)) {
switch (vt) {
case VT_UI1:
bVal *= (BYTE)v;
break;
case VT_I2:
iVal *= (short)v;
break;
case VT_I4:
lVal *= (long)v;
break;
case VT_R4:
fltVal *= (float)v;
break;
case VT_R8:
dblVal *= (double)v;
break;
case VT_CY:
cyVal.int64 *= (LONGLONG)v;
break;
default:
throw DISP_E_TYPEMISMATCH;
break;
}
} else {
Type(v.vt);
switch (v.vt) {
case VT_UI1:
bVal *= v.bVal;
break;
case VT_I2:
iVal *= v.iVal;
break;
case VT_I4:
lVal *= v.lVal;
break;
case VT_R4:
fltVal *= v.fltVal;
break;
case VT_R8:
dblVal *= v.dblVal;
break;
case VT_CY:
cyVal.int64 *= v.cyVal.int64;
break;
default:
throw DISP_E_TYPEMISMATCH;
break;
}
}
return *this;
}
Variant operator*(Variant& v1, Variant& v2)
{
if (Variant::Preciser(v1.vt, v2.vt)) {
switch (v1.vt) {
case VT_UI1:
return short(v1.bVal * (BYTE)v2);
case VT_I2:
return long(v1.iVal * (short)v2);
case VT_I4:
return v1.lVal * (long)v2;
case VT_R4:
return v1.fltVal * (float)v2;
case VT_R8:
return v1.dblVal * (double)v2;
case VT_CY:
return v1.cyVal.int64 * (LONGLONG)v2;
default:
throw DISP_E_TYPEMISMATCH;
return 0L;
}
} else {
switch (v2.vt) {
case VT_UI1:
return short((BYTE)v2 * v2.bVal);
case VT_I2:
return long((short)v2 * v2.iVal);
case VT_I4:
return (long)v1 * v2.lVal;
case VT_R4:
return (float)v1 * v2.fltVal;
case VT_R8:
return (double)v1 * v2.dblVal;
case VT_CY:
return (LONGLONG)v1 * v2.cyVal.int64;
default:
throw DISP_E_TYPEMISMATCH;
return 0L;
}
}
}
// /
const Variant& Variant::operator/=(Variant v)
{
if (long(v) == 0L) throw DISP_E_EXCEPTION;
if (Variant::Preciser(vt, v.vt)) {
switch (vt) {
case VT_UI1:
bVal /= (BYTE)v;
break;
case VT_I2:
iVal /= (short)v;
break;
case VT_I4:
lVal /= (long)v;
break;
case VT_R4:
fltVal /= (float)v;
break;
case VT_R8:
dblVal /= (double)v;
break;
case VT_CY:
cyVal.int64 /= (LONGLONG)v;
break;
default:
throw DISP_E_TYPEMISMATCH;
break;
}
} else {
Type(v.vt);
switch (v.vt) {
case VT_UI1:
bVal /= v.bVal;
break;
case VT_I2:
iVal /= v.iVal;
break;
case VT_I4:
lVal /= v.lVal;
break;
case VT_R4:
fltVal /= v.fltVal;
break;
case VT_R8:
dblVal /= v.dblVal;
break;
case VT_CY:
cyVal.int64 /= v.cyVal.int64;
break;
default:
throw DISP_E_TYPEMISMATCH;
break;
}
}
return *this;
}
Variant operator/(Variant& v1, Variant& v2)
{
if (long(v2) == 0L) throw DISP_E_EXCEPTION;
if (Variant::Preciser(v1.vt, v2.vt)) {
switch (v1.vt) {
case VT_UI1:
return short(v1.bVal / (BYTE)v2);
case VT_I2:
return long(v1.iVal / (short)v2);
case VT_I4:
return v1.lVal / (long)v2;
case VT_R4:
return v1.fltVal / (float)v2;
case VT_R8:
return v1.dblVal / (double)v2;
case VT_CY:
return v1.cyVal.int64 * (LONGLONG)v2;
default:
throw DISP_E_TYPEMISMATCH;
return 0L;
}
} else {
switch (v2.vt) {
case VT_UI1:
return short((BYTE)v2 / v2.bVal);
case VT_I2:
return long((short)v2 / v2.iVal);
case VT_I4:
return (long)v1 / v2.lVal;
case VT_R4:
return (float)v1 / v2.fltVal;
case VT_R8:
return (double)v1 / v2.dblVal;
case VT_CY:
return (LONGLONG)v1 * v2.cyVal.int64;
default:
throw DISP_E_TYPEMISMATCH;
return 0L;
}
}
}
// %
const Variant& Variant::operator%=(Variant v)
{
if (long(v) == 0L) throw DISP_E_EXCEPTION;
if (Variant::Preciser(vt, v.vt)) {
switch (vt) {
case VT_UI1:
bVal %= (BYTE)v;
break;
case VT_I2:
iVal %= (short)v;
break;
case VT_I4:
lVal %= (long)v;
break;
case VT_CY:
cyVal.int64 %= (LONGLONG)v;
break;
default:
throw DISP_E_TYPEMISMATCH;
break;
}
} else {
Type(v.vt);
switch (v.vt) {
case VT_UI1:
bVal %= v.bVal;
break;
case VT_I2:
iVal %= v.iVal;
break;
case VT_I4:
lVal %= v.lVal;
break;
case VT_CY:
cyVal.int64 %= v.cyVal.int64;
break;
default:
throw DISP_E_TYPEMISMATCH;
break;
}
}
return *this;
}
Variant operator%(Variant& v1, Variant& v2)
{
if (long(v2) == 0L) throw DISP_E_EXCEPTION;
if (Variant::Preciser(v1.vt, v2.vt)) {
switch (v1.vt) {
case VT_UI1:
return short(v1.bVal % (BYTE)v2);
case VT_I2:
return long(v1.iVal % (short)v2);
case VT_I4:
return v1.lVal % (long)v2;
case VT_CY:
return v1.cyVal.int64 * (LONGLONG)v2;
default:
throw DISP_E_TYPEMISMATCH;
return 0L;
}
} else {
switch (v2.vt) {
case VT_UI1:
return short((BYTE)v2 % v2.bVal);
case VT_I2:
return long((short)v2 % v2.iVal);
case VT_I4:
return (long)v1 % v2.lVal;
case VT_CY:
return (LONGLONG)v1 * v2.cyVal.int64;
default:
throw DISP_E_TYPEMISMATCH;
return 0L;
}
}
}
// Logical operators
// Literal comparison. Types and values must match.
BOOL operator==(const Variant& v1, const Variant& v2)
{
try {
// Check type specific values
switch (v1.vt) {
case VT_EMPTY:
return v2.vt == VT_EMPTY;
case VT_NULL:
return v2.vt == VT_NULL;
case VT_BOOL:
return v1.boolVal == ((short)v2 != 0);
case VT_UI1:
return v1.bVal == (BYTE)v2;
case VT_I2:
return v1.iVal == (short)v2;
case VT_I4:
return v1.lVal == (long)v2;
case VT_R4:
return v1.fltVal == (float)v2;
case VT_R8:
return v1.dblVal == (double)v2;
case VT_CY:
return v1.cyVal == (LONGLONG)v2;
case VT_DATE:
return v1.date == (DATE)v2;
case VT_BSTR:
{
String s = v2;
return wcscmp(v1.bstrVal, (BSTR)s) == 0;
}
case VT_ERROR:
return v2.vt == VT_ERROR && v1.scode == v2.scode;
case VT_DISPATCH:
case VT_UNKNOWN:
return v1.punkVal == v2.punkVal;
default:
throw DISP_E_BADVARTYPE;
// fall through
}
return FALSE;
} catch(...) {
// Type conversion errors always indicate not equal
return FALSE;
}
}
BOOL operator<(const Variant& v1, const Variant& v2)
{
try {
// Check type specific values
switch (v1.vt) {
case VT_EMPTY:
return v2.vt != VT_EMPTY;
case VT_NULL:
return v2.vt != VT_NULL;
case VT_BOOL:
return v1.boolVal < ((short)v2 != 0);
case VT_UI1:
return v1.bVal < (BYTE)v2;
case VT_I2:
return v1.iVal < (short)v2;
case VT_I4:
return v1.lVal < (long)v2;
case VT_R4:
return v1.fltVal < (float)v2;
case VT_R8:
return v1.dblVal < (double)v2;
case VT_CY:
return v1.cyVal.int64 < (LONGLONG)v2;
case VT_DATE:
return v1.date < (DATE)v2;
case VT_BSTR:
{
String s = v2;
return wcscmp(v1.bstrVal, (BSTR)s) < 0;
}
case VT_ERROR:
case VT_DISPATCH:
case VT_UNKNOWN:
default:
throw DISP_E_BADVARTYPE;
// fall through
}
} catch(...) {
// Type conversion errors always indicate less than
return TRUE;
}
}
// Only have to implement == and <.
// Others !=, <=, >=, and > implemented trivially with first two.
// inline BOOL operator!=(const Variant& v1, const Variant& v2)
// inline BOOL operator<=(const Variant& v1, const Variant& v2)
// inline BOOL operator>=(const Variant& v1, const Variant& v2)
// inline BOOL operator>(const Variant& v1, const Variant& v2)
ostream& operator<<(ostream& os, Variant& v)
{
// Let OLE code translate to string
try {
String s = v;
os << s; // Automatic convertions to ANSI
} catch(...) {
// If VT_ERROR, we translate, otherwise insert blank
if (v.vt == VT_ERROR) {
os << "Facility:" << HRESULT_FACILITY(v.scode)
<< ", Severity:" << HRESULT_SEVERITY(v.scode)
<< ", Code:" << HRESULT_CODE(v.scode);
}
}
return os;
}
// Check whether one type is more precise than another
BOOL Variant::Preciser(VARTYPE vt1, VARTYPE vt2)
{
// Precision data table
static int aiPrecise[] = {
0, // VT_EMPTY = 0,
0, // VT_NULL = 1,
2, // VT_I2 = 2,
3, // VT_I4 = 3,
4, // VT_R4 = 4,
5, // VT_R8 = 5,
6, // VT_CY = 6,
5, // VT_DATE = 7,
7, // VT_BSTR = 8,
0, // VT_DISPATCH = 9,
0, // VT_ERROR = 10,
0, // VT_BOOL = 11,
0, // VT_VARIANT = 12,
0, // VT_UNKNOWN = 13,
0, // VT_I1 = 16,
1 // VT_UI1 = 17,
};
if (vt1 > VT_UI1 || vt2 > VT_UI1) throw E_INVALIDARG;
return aiPrecise[vt1] > aiPrecise[vt2];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -