⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 variant.cpp

📁 The code for this article was written for version 1.0 of the Active Template Library (ATL). The cu
💻 CPP
📖 第 1 页 / 共 2 页
字号:
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 + -