templated VARIANT
От: adontz Грузия http://adontz.wordpress.com/
Дата: 08.01.04 04:36
Оценка: 6 (1)
Реализация работа с ОЛЕ типом вариант на основе частичной специализации шаблонов.
Просьба похвалить и покритиковать в пропорции
Код в ответах
A journey of a thousand miles must begin with a single step © Lau Tsu
Re: templated VARIANT - implementation
От: adontz Грузия http://adontz.wordpress.com/
Дата: 08.01.04 04:45
Оценка:
#include "header.h"
//
template <> E_VarType _var_type_from_type<signed __int16>() {return VAR_TYPE_I2;}
template <> E_VarType _var_type_from_type<signed __int32>() {return VAR_TYPE_I4;}
template <> E_VarType _var_type_from_type<float>() {return VAR_TYPE_R4;}
template <> E_VarType _var_type_from_type<double>() {return VAR_TYPE_R8;}
template <> E_VarType _var_type_from_type<CY>() {return VAR_TYPE_CY;}
template <> E_VarType _var_type_from_type<BSTR>() {return VAR_TYPE_BSTR;}
template <> E_VarType _var_type_from_type<IDispatch *>() {return VAR_TYPE_DISPATCH;}
template <> E_VarType _var_type_from_type<bool>() {return VAR_TYPE_BOOL;}
template <> E_VarType _var_type_from_type<tagVARIANT>() {return VAR_TYPE_VARIANT;}
template <> E_VarType _var_type_from_type<IUnknown *>() {return VAR_TYPE_UNKNOWN;}
template <> E_VarType _var_type_from_type<DECIMAL>() {return VAR_TYPE_DECIMAL;}
template <> E_VarType _var_type_from_type<signed __int8>() {return VAR_TYPE_I1;}
template <> E_VarType _var_type_from_type<unsigned __int8>() {return VAR_TYPE_UI1;}
template <> E_VarType _var_type_from_type<unsigned __int16>() {return VAR_TYPE_UI2;}
template <> E_VarType _var_type_from_type<unsigned __int32>() {return VAR_TYPE_UI4;}
template <> E_VarType _var_type_from_type<SAFEARRAY>() {return VAR_TYPE_ARRAY;}
template <> E_VarType _var_type_from_type<signed __int16 *>() {return VAR_TYPE_REF_I2;}
template <> E_VarType _var_type_from_type<signed __int32 *>() {return VAR_TYPE_REF_I4;}
template <> E_VarType _var_type_from_type<float *>() {return VAR_TYPE_REF_R4;}
template <> E_VarType _var_type_from_type<double *>() {return VAR_TYPE_REF_R8;}
template <> E_VarType _var_type_from_type<CY *>() {return VAR_TYPE_REF_CY;}
template <> E_VarType _var_type_from_type<BSTR *>() {return VAR_TYPE_REF_BSTR;}
template <> E_VarType _var_type_from_type<IDispatch **>() {return VAR_TYPE_REF_DISPATCH;}
template <> E_VarType _var_type_from_type<bool *>() {return VAR_TYPE_REF_BOOL;}
template <> E_VarType _var_type_from_type<tagVARIANT *>() {return VAR_TYPE_REF_VARIANT;}
template <> E_VarType _var_type_from_type<IUnknown **>() {return VAR_TYPE_REF_UNKNOWN;}
template <> E_VarType _var_type_from_type<DECIMAL *>() {return VAR_TYPE_REF_DECIMAL;}
template <> E_VarType _var_type_from_type<signed __int8 *>() {return VAR_TYPE_REF_I1;}
template <> E_VarType _var_type_from_type<unsigned __int8 *>() {return VAR_TYPE_REF_UI1;}
template <> E_VarType _var_type_from_type<unsigned __int16 *>() {return VAR_TYPE_REF_UI2;}
template <> E_VarType _var_type_from_type<unsigned __int32 *>() {return VAR_TYPE_REF_UI4;}
template <> E_VarType _var_type_from_type<SAFEARRAY *>() {return VAR_TYPE_REF_ARRAY;}
//
template <> E_VarType _var_type_from_type<signed long>() {return VAR_TYPE_I4;}
template <> E_VarType _var_type_from_type<unsigned long>() {return VAR_TYPE_UI4;}
template <> E_VarType _var_type_from_type<signed long *>() {return VAR_TYPE_REF_I4;}
template <> E_VarType _var_type_from_type<unsigned long *>() {return VAR_TYPE_REF_UI4;}
//
template <> LPVOID _var_address_from_type<signed __int16>(tagVARIANT & variant) {return (LPVOID)&variant.iVal;}
template <> LPVOID _var_address_from_type<signed __int32>(tagVARIANT & variant) {return (LPVOID)&variant.intVal;}
template <> LPVOID _var_address_from_type<float>(tagVARIANT & variant) {return (LPVOID)&variant.fltVal;}
template <> LPVOID _var_address_from_type<double>(tagVARIANT & variant) {return (LPVOID)&variant.dblVal;}
template <> LPVOID _var_address_from_type<CY>(tagVARIANT & variant) {return (LPVOID)&variant.cyVal;}
template <> LPVOID _var_address_from_type<BSTR>(tagVARIANT & variant) {return (LPVOID)&variant.bstrVal;}
template <> LPVOID _var_address_from_type<IDispatch *>(tagVARIANT & variant) {return (LPVOID)&variant.pdispVal;}
template <> LPVOID _var_address_from_type<bool>(tagVARIANT & variant) {return (LPVOID)&variant.boolVal;}
template <> LPVOID _var_address_from_type<tagVARIANT>(tagVARIANT & variant) {return (LPVOID)&variant;}
template <> LPVOID _var_address_from_type<IUnknown *>(tagVARIANT & variant) {return (LPVOID)&variant.punkVal;}
template <> LPVOID _var_address_from_type<DECIMAL>(tagVARIANT & variant) {return (LPVOID)&variant.decVal;}
template <> LPVOID _var_address_from_type<signed __int8>(tagVARIANT & variant) {return (LPVOID)&variant.cVal;}
template <> LPVOID _var_address_from_type<unsigned __int8>(tagVARIANT & variant) {return (LPVOID)&variant.bVal;}
template <> LPVOID _var_address_from_type<unsigned __int16>(tagVARIANT & variant) {return (LPVOID)&variant.uiVal;}
template <> LPVOID _var_address_from_type<unsigned __int32>(tagVARIANT & variant) {return (LPVOID)&variant.uintVal;}
template <> LPVOID _var_address_from_type<signed __int64>(tagVARIANT & variant) {return (LPVOID)&variant.llVal;}
template <> LPVOID _var_address_from_type<unsigned __int64>(tagVARIANT & variant) {return (LPVOID)&variant.ullVal;}
template <> LPVOID _var_address_from_type<SAFEARRAY *>(tagVARIANT & variant) {return (LPVOID)&variant.parray;}
template <> LPVOID _var_address_from_type<signed __int16 *>(tagVARIANT & variant) {return (LPVOID)&variant.piVal;}
template <> LPVOID _var_address_from_type<signed __int32 *>(tagVARIANT & variant) {return (LPVOID)&variant.plVal;}
template <> LPVOID _var_address_from_type<float *>(tagVARIANT & variant) {return (LPVOID)&variant.pfltVal;}
template <> LPVOID _var_address_from_type<double *>(tagVARIANT & variant) {return (LPVOID)&variant.pdblVal;}
template <> LPVOID _var_address_from_type<CY *>(tagVARIANT & variant) {return (LPVOID)&variant.pcyVal;}
template <> LPVOID _var_address_from_type<BSTR *>(tagVARIANT & variant) {return (LPVOID)&variant.pbstrVal;}
template <> LPVOID _var_address_from_type<IDispatch **>(tagVARIANT & variant) {return (LPVOID)&variant.ppdispVal;}
template <> LPVOID _var_address_from_type<bool *>(tagVARIANT & variant) {return (LPVOID)&variant.pboolVal;}
template <> LPVOID _var_address_from_type<tagVARIANT *>(tagVARIANT & variant) {return (LPVOID)&variant.pvarVal;}
template <> LPVOID _var_address_from_type<IUnknown **>(tagVARIANT & variant) {return (LPVOID)&variant.ppunkVal;}
template <> LPVOID _var_address_from_type<DECIMAL *>(tagVARIANT & variant) {return (LPVOID)&variant.pdecVal;}
template <> LPVOID _var_address_from_type<signed __int8 *>(tagVARIANT & variant) {return (LPVOID)&variant.pcVal;}
template <> LPVOID _var_address_from_type<unsigned __int8 *>(tagVARIANT & variant) {return (LPVOID)&variant.pbVal;}
template <> LPVOID _var_address_from_type<unsigned __int16 *>(tagVARIANT & variant) {return (LPVOID)&variant.puiVal;}
template <> LPVOID _var_address_from_type<unsigned __int32 *>(tagVARIANT & variant) {return (LPVOID)&variant.puintVal;}
template <> LPVOID _var_address_from_type<signed __int64 *>(tagVARIANT & variant) {return (LPVOID)&variant.pllVal;}
template <> LPVOID _var_address_from_type<unsigned __int64 *>(tagVARIANT & variant) {return (LPVOID)&variant.pullVal;}
template <> LPVOID _var_address_from_type<SAFEARRAY **>(tagVARIANT & variant) {return (LPVOID)&variant.pparray;}
//
template <> LPVOID _var_address_from_type<signed long>(tagVARIANT & variant) {return (LPVOID)&variant.intVal;}
template <> LPVOID _var_address_from_type<unsigned long>(tagVARIANT & variant) {return (LPVOID)&variant.uintVal;}
template <> LPVOID _var_address_from_type<signed long *>(tagVARIANT & variant) {return (LPVOID)&variant.plVal;}
template <> LPVOID _var_address_from_type<unsigned long *>(tagVARIANT & variant) {return (LPVOID)&variant.puintVal;}
//
template <> LPVOID _var_address_from_var_type<VT_I2>(tagVARIANT & variant) {return &variant.iVal;}
template <> LPVOID _var_address_from_var_type<VT_I4>(tagVARIANT & variant) {return &variant.intVal;}
template <> LPVOID _var_address_from_var_type<VT_R4>(tagVARIANT & variant) {return &variant.fltVal;}
template <> LPVOID _var_address_from_var_type<VT_R8>(tagVARIANT & variant) {return &variant.dblVal;}
template <> LPVOID _var_address_from_var_type<VT_CY>(tagVARIANT & variant) {return &variant.cyVal;}
template <> LPVOID _var_address_from_var_type<VT_DATE>(tagVARIANT & variant) {return &variant.date;}
template <> LPVOID _var_address_from_var_type<VT_BSTR>(tagVARIANT & variant) {return &variant.bstrVal;}
template <> LPVOID _var_address_from_var_type<VT_DISPATCH>(tagVARIANT & variant) {return &variant.pdispVal;}
template <> LPVOID _var_address_from_var_type<VT_ERROR>(tagVARIANT & variant) {return &variant.scode;}
template <> LPVOID _var_address_from_var_type<VT_BOOL>(tagVARIANT & variant) {return &variant.boolVal;}
template <> LPVOID _var_address_from_var_type<VT_VARIANT>(tagVARIANT & variant) {return &variant;}
template <> LPVOID _var_address_from_var_type<VT_UNKNOWN>(tagVARIANT & variant) {return &variant.punkVal;}
template <> LPVOID _var_address_from_var_type<VT_DECIMAL>(tagVARIANT & variant) {return &variant.decVal;}
template <> LPVOID _var_address_from_var_type<VT_I1>(tagVARIANT & variant) {return &variant.cVal;}
template <> LPVOID _var_address_from_var_type<VT_UI1>(tagVARIANT & variant) {return &variant.bVal;}
template <> LPVOID _var_address_from_var_type<VT_UI2>(tagVARIANT & variant) {return &variant.uiVal;}
template <> LPVOID _var_address_from_var_type<VT_UI4>(tagVARIANT & variant) {return &variant.uintVal;}
//
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_I2>(tagVARIANT & variant) {return &variant.piVal;}
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_I4>(tagVARIANT & variant) {return &variant.pintVal;}
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_R4>(tagVARIANT & variant) {return &variant.pfltVal;}
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_R8>(tagVARIANT & variant) {return &variant.pdblVal;}
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_CY>(tagVARIANT & variant) {return &variant.pcyVal;}
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_DATE>(tagVARIANT & variant) {return &variant.pdate;}
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_BSTR>(tagVARIANT & variant) {return &variant.pbstrVal;}
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_DISPATCH>(tagVARIANT & variant) {return &variant.ppdispVal;}
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_ERROR>(tagVARIANT & variant) {return &variant.pscode;}
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_BOOL>(tagVARIANT & variant) {return &variant.pboolVal;}
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_VARIANT>(tagVARIANT & variant) {return &variant.pvarVal;}
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_UNKNOWN>(tagVARIANT & variant) {return &variant.ppunkVal;}
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_DECIMAL>(tagVARIANT & variant) {return &variant;}
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_RECORD>(tagVARIANT & variant) {return &variant;}
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_I1>(tagVARIANT & variant) {return &variant;}
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_UI1>(tagVARIANT & variant) {return &variant;}
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_UI2>(tagVARIANT & variant) {return &variant;}
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_UI4>(tagVARIANT & variant) {return &variant;}
A journey of a thousand miles must begin with a single step © Lau Tsu
Re: templated VARIANT - header
От: adontz Грузия http://adontz.wordpress.com/
Дата: 08.01.04 04:46
Оценка:
//
#ifndef ADONTZ_TEMPLATED_VARIANT_HEADER_INCLUDED_DID_YOU_READ_TILL_HERE_SO_KEEP_READING_THIS_BULL_SHIT_HA_ARE_YOU_STILL_READING_SO_THE_COMPILER_DOES_AND_MAY_CRASH_HA_HA
#define ADONTZ_TEMPLATED_VARIANT_HEADER_INCLUDED_DID_YOU_READ_TILL_HERE_SO_KEEP_READING_THIS_BULL_SHIT_HA_ARE_YOU_STILL_READING_SO_THE_COMPILER_DOES_AND_MAY_CRASH_HA_HA
//
#include <Windows.h>
//
enum E_VarType
    {
        VAR_TYPE_EMPTY    = VT_EMPTY,
        VAR_TYPE_NULL    = VT_NULL,
        VAR_TYPE_I2    = VT_I2,
        VAR_TYPE_I4    = VT_I4,
        VAR_TYPE_R4    = VT_R4,
        VAR_TYPE_R8    = VT_R8,
        VAR_TYPE_CY    = VT_CY,
        VAR_TYPE_DATE    = VT_DATE,
        VAR_TYPE_BSTR    = VT_BSTR,
        VAR_TYPE_DISPATCH    = VT_DISPATCH,
        VAR_TYPE_ERROR    = VT_ERROR,
        VAR_TYPE_BOOL    = VT_BOOL,
        VAR_TYPE_VARIANT    = VT_VARIANT,
        VAR_TYPE_UNKNOWN    = VT_UNKNOWN,
        VAR_TYPE_DECIMAL    = VT_DECIMAL,
        VAR_TYPE_I1    = VT_I1,
        VAR_TYPE_UI1    = VT_UI1,
        VAR_TYPE_UI2    = VT_UI2,
        VAR_TYPE_UI4    = VT_UI4,
        VAR_TYPE_INT    = VT_INT,
        VAR_TYPE_UINT    = VT_UINT,
//
        VAR_TYPE_REF_EMPTY    = VT_EMPTY | VT_BYREF,
        VAR_TYPE_REF_NULL    = VT_NULL | VT_BYREF,
        VAR_TYPE_REF_I2    = VT_I2 | VT_BYREF,
        VAR_TYPE_REF_I4    = VT_I4 | VT_BYREF,
        VAR_TYPE_REF_R4    = VT_R4 | VT_BYREF,
        VAR_TYPE_REF_R8    = VT_R8 | VT_BYREF,
        VAR_TYPE_REF_CY    = VT_CY | VT_BYREF,
        VAR_TYPE_REF_DATE    = VT_DATE | VT_BYREF,
        VAR_TYPE_REF_BSTR    = VT_BSTR | VT_BYREF,
        VAR_TYPE_REF_DISPATCH    = VT_DISPATCH | VT_BYREF,
        VAR_TYPE_REF_ERROR    = VT_ERROR | VT_BYREF,
        VAR_TYPE_REF_BOOL    = VT_BOOL | VT_BYREF,
        VAR_TYPE_REF_VARIANT    = VT_VARIANT | VT_BYREF,
        VAR_TYPE_REF_UNKNOWN    = VT_UNKNOWN | VT_BYREF,
        VAR_TYPE_REF_DECIMAL    = VT_DECIMAL | VT_BYREF,
        VAR_TYPE_REF_I1    = VT_I1 | VT_BYREF,
        VAR_TYPE_REF_UI1    = VT_UI1 | VT_BYREF,
        VAR_TYPE_REF_UI2    = VT_UI2 | VT_BYREF,
        VAR_TYPE_REF_UI4    = VT_UI4 | VT_BYREF,
        VAR_TYPE_REF_INT    = VT_INT | VT_BYREF,
        VAR_TYPE_REF_UINT    = VT_UINT | VT_BYREF,
//
        VAR_TYPE_ARRAY_EMPTY    = VT_EMPTY | VT_ARRAY,
        VAR_TYPE_ARRAY_NULL    = VT_NULL | VT_ARRAY,
        VAR_TYPE_ARRAY_I2    = VT_I2 | VT_ARRAY,
        VAR_TYPE_ARRAY_I4    = VT_I4 | VT_ARRAY,
        VAR_TYPE_ARRAY_R4    = VT_R4 | VT_ARRAY,
        VAR_TYPE_ARRAY_R8    = VT_R8 | VT_ARRAY,
        VAR_TYPE_ARRAY_CY    = VT_CY | VT_ARRAY,
        VAR_TYPE_ARRAY_DATE    = VT_DATE | VT_ARRAY,
        VAR_TYPE_ARRAY_BSTR    = VT_BSTR | VT_ARRAY,
        VAR_TYPE_ARRAY_DISPATCH    = VT_DISPATCH | VT_ARRAY,
        VAR_TYPE_ARRAY_ERROR    = VT_ERROR | VT_ARRAY,
        VAR_TYPE_ARRAY_BOOL    = VT_BOOL | VT_ARRAY,
        VAR_TYPE_ARRAY_VARIANT    = VT_VARIANT | VT_ARRAY,
        VAR_TYPE_ARRAY_UNKNOWN    = VT_UNKNOWN | VT_ARRAY,
        VAR_TYPE_ARRAY_DECIMAL    = VT_DECIMAL | VT_ARRAY,
        VAR_TYPE_ARRAY_I1    = VT_I1 | VT_ARRAY,
        VAR_TYPE_ARRAY_UI1    = VT_UI1 | VT_ARRAY,
        VAR_TYPE_ARRAY_UI2    = VT_UI2 | VT_ARRAY,
        VAR_TYPE_ARRAY_UI4    = VT_UI4 | VT_ARRAY,
        VAR_TYPE_ARRAY_INT    = VT_INT | VT_ARRAY,
        VAR_TYPE_ARRAY_UINT    = VT_UINT | VT_ARRAY,
//
        VAR_TYPE_REF_ARRAY_EMPTY    = VT_EMPTY | VT_BYREF | VT_ARRAY,
        VAR_TYPE_REF_ARRAY_NULL    = VT_NULL | VT_BYREF | VT_ARRAY,
        VAR_TYPE_REF_ARRAY_I2    = VT_I2 | VT_BYREF | VT_ARRAY,
        VAR_TYPE_REF_ARRAY_I4    = VT_I4 | VT_BYREF | VT_ARRAY,
        VAR_TYPE_REF_ARRAY_R4    = VT_R4 | VT_BYREF | VT_ARRAY,
        VAR_TYPE_REF_ARRAY_R8    = VT_R8 | VT_BYREF | VT_ARRAY,
        VAR_TYPE_REF_ARRAY_CY    = VT_CY | VT_BYREF | VT_ARRAY,
        VAR_TYPE_REF_ARRAY_DATE    = VT_DATE | VT_BYREF | VT_ARRAY,
        VAR_TYPE_REF_ARRAY_BSTR    = VT_BSTR | VT_BYREF | VT_ARRAY,
        VAR_TYPE_REF_ARRAY_DISPATCH    = VT_DISPATCH | VT_BYREF | VT_ARRAY,
        VAR_TYPE_REF_ARRAY_ERROR    = VT_ERROR | VT_BYREF | VT_ARRAY,
        VAR_TYPE_REF_ARRAY_BOOL    = VT_BOOL | VT_BYREF | VT_ARRAY,
        VAR_TYPE_REF_ARRAY_VARIANT    = VT_VARIANT | VT_BYREF | VT_ARRAY,
        VAR_TYPE_REF_ARRAY_UNKNOWN    = VT_UNKNOWN | VT_BYREF | VT_ARRAY,
        VAR_TYPE_REF_ARRAY_DECIMAL    = VT_DECIMAL | VT_BYREF | VT_ARRAY,
        VAR_TYPE_REF_ARRAY_I1    = VT_I1 | VT_BYREF | VT_ARRAY,
        VAR_TYPE_REF_ARRAY_UI1    = VT_UI1 | VT_BYREF | VT_ARRAY,
        VAR_TYPE_REF_ARRAY_UI2    = VT_UI2 | VT_BYREF | VT_ARRAY,
        VAR_TYPE_REF_ARRAY_UI4    = VT_UI4 | VT_BYREF | VT_ARRAY,
        VAR_TYPE_REF_ARRAY_INT    = VT_INT | VT_BYREF | VT_ARRAY,
        VAR_TYPE_REF_ARRAY_UINT    = VT_UINT | VT_BYREF | VT_ARRAY,
//
        VAR_TYPE_ARRAY = VT_ARRAY,
        VAR_TYPE_REF_ARRAY = VT_ARRAY | VT_BYREF
    };
//
template <typename TYPE> E_VarType _var_type_from_type() {return VAR_TYPE_EMPTY;}
//
template <> E_VarType _var_type_from_type<signed __int16>();
template <> E_VarType _var_type_from_type<signed __int32>();
template <> E_VarType _var_type_from_type<float>();
template <> E_VarType _var_type_from_type<double>();
template <> E_VarType _var_type_from_type<CY>();
template <> E_VarType _var_type_from_type<BSTR>();
template <> E_VarType _var_type_from_type<IDispatch *>();
template <> E_VarType _var_type_from_type<bool>();
template <> E_VarType _var_type_from_type<tagVARIANT>();
template <> E_VarType _var_type_from_type<IUnknown *>();
template <> E_VarType _var_type_from_type<DECIMAL>();
template <> E_VarType _var_type_from_type<signed __int8>();
template <> E_VarType _var_type_from_type<unsigned __int8>();
template <> E_VarType _var_type_from_type<unsigned __int16>();
template <> E_VarType _var_type_from_type<unsigned __int32>();
template <> E_VarType _var_type_from_type<signed __int64>();
template <> E_VarType _var_type_from_type<unsigned __int64>();
template <> E_VarType _var_type_from_type<SAFEARRAY>();
template <> E_VarType _var_type_from_type<signed __int16 *>();
template <> E_VarType _var_type_from_type<signed __int32 *>();
template <> E_VarType _var_type_from_type<float *>();
template <> E_VarType _var_type_from_type<double *>();
template <> E_VarType _var_type_from_type<CY *>();
template <> E_VarType _var_type_from_type<BSTR *>();
template <> E_VarType _var_type_from_type<IDispatch **>();
template <> E_VarType _var_type_from_type<bool *>();
template <> E_VarType _var_type_from_type<tagVARIANT *>();
template <> E_VarType _var_type_from_type<IUnknown **>();
template <> E_VarType _var_type_from_type<DECIMAL *>();
template <> E_VarType _var_type_from_type<signed __int8 *>();
template <> E_VarType _var_type_from_type<unsigned __int8 *>();
template <> E_VarType _var_type_from_type<unsigned __int16 *>();
template <> E_VarType _var_type_from_type<unsigned __int32 *>();
template <> E_VarType _var_type_from_type<signed __int64 *>();
template <> E_VarType _var_type_from_type<unsigned __int64 *>();
template <> E_VarType _var_type_from_type<SAFEARRAY *>();
//
template <> E_VarType _var_type_from_type<signed long>();
template <> E_VarType _var_type_from_type<unsigned long>();
template <> E_VarType _var_type_from_type<signed long *>();
template <> E_VarType _var_type_from_type<unsigned long *>();
//
template <typename TYPE> LPVOID _var_address_from_type(tagVARIANT & variant) {return &variant;}
//
template <> LPVOID _var_address_from_type<signed __int16>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<signed __int32>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<float>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<double>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<CY>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<BSTR>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<IDispatch *>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<bool>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<tagVARIANT>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<IUnknown *>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<DECIMAL>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<signed __int8>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<unsigned __int8>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<unsigned __int16>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<unsigned __int32>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<signed __int64>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<unsigned __int64>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<SAFEARRAY *>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<signed __int16 *>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<signed __int32 *>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<float *>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<double *>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<CY *>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<BSTR *>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<IDispatch **>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<bool *>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<tagVARIANT *>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<IUnknown **>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<DECIMAL *>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<signed __int8 *>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<unsigned __int8 *>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<unsigned __int16 *>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<unsigned __int32 *>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<signed __int64 *>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<unsigned __int64 *>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<SAFEARRAY **>(tagVARIANT & variant);
//
template <> LPVOID _var_address_from_type<signed long>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<unsigned long>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<signed long *>(tagVARIANT & variant);
template <> LPVOID _var_address_from_type<unsigned long *>(tagVARIANT & variant);
//
template <VARTYPE varType> LPVOID _var_address_from_var_type(tagVARIANT & variant) {return &variant;}
//
template <> LPVOID _var_address_from_var_type<VT_I2>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_I4>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_R4>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_R8>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_CY>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_DATE>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_BSTR>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_DISPATCH>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_ERROR>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_BOOL>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_VARIANT>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_UNKNOWN>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_DECIMAL>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_RECORD>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_I1>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_UI1>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_UI2>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_UI4>(tagVARIANT & variant);
//
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_I2>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_I4>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_R4>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_R8>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_CY>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_DATE>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_BSTR>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_DISPATCH>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_ERROR>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_BOOL>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_VARIANT>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_UNKNOWN>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_DECIMAL>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_RECORD>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_I1>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_UI1>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_UI2>(tagVARIANT & variant);
template <> LPVOID _var_address_from_var_type<VT_BYREF | VT_UI4>(tagVARIANT & variant);
//
typedef class C_Variant : public tagVARIANT
    {
        public:
            C_Variant(const E_VarType varType = VAR_TYPE_EMPTY)
                {
                    VariantInit(this);
                    if (FAILED(VariantChangeType(this, this, VARIANT_NOUSEROVERRIDE, (VARTYPE)varType)))
                        {
                            vt = (VARTYPE)varType;
                        }
                }
            template <typename TYPE>
            C_Variant(const TYPE & initValue)
                {
                    VariantInit(this);
                    // Local variables
                    tagVARIANT variant;
                    // Code
                    variant.vt = (VARTYPE)_var_type_from_type<TYPE>();
                    *((TYPE *)_var_address_from_type<TYPE>(variant)) = initValue;
                    vt = VT_EMPTY;
                    VariantCopy(this, &variant);
                }
            C_Variant(const bool & initValue)
                {
                    vt = VT_BOOL;
                    boolVal = initValue ? VARIANT_TRUE : VARIANT_FALSE;
                }
            C_Variant(SAFEARRAY * lpSafeArray)
                {
                    VariantInit(this);
                    // Local variables
                    tagVARIANT variant;
                    // Code
                    SafeArrayGetVartype(lpSafeArray, &variant.vt);
                    variant.vt |= VT_ARRAY;
                    variant.parray = lpSafeArray;
                    vt = VT_EMPTY;
                    VariantCopy(this, &variant);
                }
            ~C_Variant()
                {
                    VariantClear(this);
                }
            template <typename TYPE>
            operator TYPE &()
                {
                    return *((TYPE *)_var_address_from_type<TYPE>(*this));
                }
            template <typename TYPE>
            C_Variant & operator = (const TYPE & initValue)
                {
                    // Local variables
                    tagVARIANT variant;
                    // Code
                    variant.vt = (VARTYPE)_var_type_from_type<TYPE>();
                    *((TYPE *)_var_address_from_type<TYPE>(variant)) = initValue;
                    VariantCopy(this, &variant);
                    return *this;
                }
            C_Variant & operator = (const bool & initValue)
                {
                    VariantClear(this);
                    vt = VT_BOOL;
                    boolVal = initValue ? VARIANT_TRUE : VARIANT_FALSE;
                    return *this;
                }
            C_Variant & operator = (SAFEARRAY * lpSafeArray)
                {
                    VariantClear(this);
                    // Local variables
                    tagVARIANT variant;
                    // Code
                    SafeArrayGetVartype(lpSafeArray, &variant.vt);
                    variant.vt |= VT_ARRAY;
                    variant.parray = lpSafeArray;
                    vt = VT_EMPTY;
                    VariantCopy(this, &variant);
                    return *this;
                }
            bool operator == (const VARIANT & variant)    const
                {
                    if (vt == VT_NULL && variant.vt == VT_NULL)
                        {
                            return true;
                        }
                    else
                        {
                            return VarCmp((VARIANT *)this, (VARIANT *)&variant, LOCALE_USER_DEFAULT, 0) == VARCMP_EQ;
                        }
                }
            bool operator != (const VARIANT & variant)    const
                {
                    if (vt == VT_NULL && variant.vt == VT_NULL)
                        {
                            return false;
                        }
                    else
                        {
                            return VarCmp((VARIANT *)this, (VARIANT *)&variant, LOCALE_USER_DEFAULT, 0) != VARCMP_EQ;
                        }
                }
            bool operator < (const VARIANT & variant)    const
                {
                    if (vt == VT_NULL && variant.vt == VT_NULL)
                        {
                            return false;
                        }
                    else
                        {
                            return VarCmp((VARIANT *)this, (VARIANT *)&variant, LOCALE_USER_DEFAULT, 0) == VARCMP_LT;
                        }
                }
            bool operator <= (const VARIANT & variant)    const
                {
                    if (vt == VT_NULL && variant.vt == VT_NULL)
                        {
                            return true;
                        }
                    else
                        {
                            return VarCmp((VARIANT *)this, (VARIANT *)&variant, LOCALE_USER_DEFAULT, 0) != VARCMP_GT;
                        }
                }
            bool operator > (const VARIANT & variant)    const
                {
                    if (vt == VT_NULL && variant.vt == VT_NULL)
                        {
                            return true;
                        }
                    else
                        {
                            return VarCmp((VARIANT *)this, (VARIANT *)&variant, LOCALE_USER_DEFAULT, 0) == VARCMP_GT;
                        }
                }
            bool operator >= (const VARIANT & variant)    const
                {
                    if (vt == VT_NULL && variant.vt == VT_NULL)
                        {
                            return true;
                        }
                    else
                        {
                            return VarCmp((VARIANT *)this, (VARIANT *)&variant, LOCALE_USER_DEFAULT, 0) != VARCMP_LT;
                        }
                }
    }    * LP_CVariant;
//
#endif
//
// End of file
//
A journey of a thousand miles must begin with a single step © Lau Tsu
Re: templated VARIANT
От: Андрей Россия  
Дата: 08.01.04 05:08
Оценка:
Здравствуйте, adontz, Вы писали:

A>Реализация работа с ОЛЕ типом вариант на основе частичной специализации шаблонов.

A>Просьба похвалить и покритиковать в пропорции
A>Код в ответах

Непонятно, для чего нужен этот велосипед? Есть же COleVariant и CComVariant. То, что ты написал, не сильно лучше, имхо
Да и код малость странный

typedef class blablabla : public blabla
{
...
};

зачем typedef? какой сакральный смысл ты в него заложил?

и удаление константности прямым приведением типов в стиле C — дурной тон
 return VarCmp((VARIANT *)this, (VARIANT *)&variant, LOCALE_USER_DEFAULT, 0) == VARCMP_GT;

если уж ты используешь C++, будь добр юзать const_cast — это, по крайней мере, в данном конетксте, явно будет показывать, что ты хотел сделать.
Re[2]: templated VARIANT
От: adontz Грузия http://adontz.wordpress.com/
Дата: 08.01.04 05:19
Оценка:
Здравствуйте, Андрей, Вы писали:

А>зачем typedef? какой сакральный смысл ты в него заложил?

Прсто привычка.
А>и удаление константности прямым приведением типов в стиле C — дурной тон
А>
А> return VarCmp((VARIANT *)this, (VARIANT *)&variant, LOCALE_USER_DEFAULT, 0) == VARCMP_GT;
А>

А>если уж ты используешь C++, будь добр юзать const_cast — это, по крайней мере, в данном конетксте, явно будет показывать, что ты хотел сделать.
О, пожалуй так и сделаю.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re: templated VARIANT
От: Аноним  
Дата: 08.01.04 13:37
Оценка:
Здравствуйте, adontz, Вы писали:

A>Реализация работа с ОЛЕ типом вариант на основе частичной специализации шаблонов.

A>Просьба похвалить и покритиковать в пропорции

<...>

Вот такой консруктор


template <typename TYPE>
C_Variant(const TYPE & initValue)
{
  VariantInit(this);
  // Local variables
  tagVARIANT variant;
  // Code
  variant.vt = (VARTYPE)_var_type_from_type<TYPE>();
  *((TYPE *)_var_address_from_type<TYPE>(variant)) = initValue;
  vt = VT_EMPTY;
  VariantCopy(this, &variant);
}


вкупе с вот такой функцей

template <typename TYPE> LPVOID _var_address_from_type(tagVARIANT & variant) {return &variant;}


Сделает такой код возможным :


struct Aargh {};
C_Variant variant=aargh();
Re[2]: templated VARIANT
От: adontz Грузия http://adontz.wordpress.com/
Дата: 08.01.04 18:01
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Сделает такой код возможным :

А>
А>struct Aargh {};
А>C_Variant variant=aargh();
А>


Может я мало понимаю, что такое вариант. Такой код должен быть возможен? Вроде структуры хранить можно, но для них интерфейс нужно писать описывающий структуру. А автогенерация интерфейсов в задачу не входила
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[3]: templated VARIANT
От: Аноним  
Дата: 09.01.04 11:50
Оценка:
Здравствуйте, adontz, Вы писали:

<...>

A>Может я мало понимаю, что такое вариант. Такой код должен быть возможен? Вроде структуры хранить можно, но для них интерфейс нужно писать описывающий структуру. А автогенерация интерфейсов в задачу не входила


Как я понимаю, так как в VARIANT'е может храниться лишь ограниченное количество типов данных, то "запихивать" в него всё подряд — неправильно, и должно быть невозможно.
Re[4]: templated VARIANT
От: adontz Грузия http://adontz.wordpress.com/
Дата: 10.01.04 01:43
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Как я понимаю, так как в VARIANT'е может храниться лишь ограниченное количество типов данных, то "запихивать" в него всё подряд — неправильно, и должно быть невозможно.


По идее да. Можно (цчитывая что шаблоны компилируються по ребованию, а не заранее) запихать в реализации по умолчанию что-нибудь не компилирующееся.
... << RSDN@Home 1.1.0 stable >>
A journey of a thousand miles must begin with a single step © Lau Tsu
Re: templated VARIANT
От: _nn_  
Дата: 10.01.04 09:04
Оценка:
Здравствуйте, adontz, Вы писали:

A>Реализация работа с ОЛЕ типом вариант на основе частичной специализации шаблонов.

A>Просьба похвалить и покритиковать в пропорции
A>Код в ответах

Немного недоделанный код.
1)В классе вообще нет функций, как же работать ?
2)Работа со строками недоделанна.
C_Variant s;
char str[]="AAAA";
s=str; // Ошибка !

3)Зачем нужно два файла ?
Лучше все в один запихнуть и все специализации _var_type_from_type, _var_address_from_type , _var_address_from_var_type сделать inline.

А так все неплохо !!!

С Уважением.
NN.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: templated VARIANT
От: adontz Грузия http://adontz.wordpress.com/
Дата: 10.01.04 09:30
Оценка:
Здравствуйте, _nn_, Вы писали:

__>1)В классе вообще нет функций, как же работать ?


А какие нужны?

__>2)Работа со строками недоделанна.

__>
__>C_Variant s;
__>char str[]="AAAA";
__>s=str; // Ошибка !

Ну ведь её преобразовывать в 2х байтный вариант надо. А это не ривиальная (не решаеться однозначно, локаль нужна) задача.

__>

__>3)Зачем нужно два файла ?

А фиг его

__>Лучше все в один запихнуть и все специализации _var_type_from_type, _var_address_from_type , _var_address_from_var_type сделать inline.


Могет битъ.

__>А так все неплохо !!!


Спасибо
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[3]: templated VARIANT
От: _nn_  
Дата: 10.01.04 10:17
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, _nn_, Вы писали:


__>>1)В классе вообще нет функций, как же работать ?


A>А какие нужны?

Ну например смена типа.

__>>2)Работа со строками недоделанна.

__>>
__>>C_Variant s;
__>>char str[]="AAAA";
__>>s=str; // Ошибка !

A>Ну ведь её преобразовывать в 2х байтный вариант надо. А это не ривиальная (не решаеться однозначно, локаль нужна) задача.

Ну в CComVariant работает , так надо чтобы и здесь тоже работало.

__>>

__>>3)Зачем нужно два файла ?

A>А фиг его


__>>Лучше все в один запихнуть и все специализации _var_type_from_type, _var_address_from_type , _var_address_from_var_type сделать inline.


A>Могет битъ.


__>>А так все неплохо !!!


A>Спасибо


Пожалуйста.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: templated VARIANT
От: adontz Грузия http://adontz.wordpress.com/
Дата: 10.01.04 10:42
Оценка:
Здравствуйте, _nn_, Вы писали:

A>>А какие нужны?

__>Ну например смена типа.

ОК, будет.

__>Ну в CComVariant работает , так надо чтобы и здесь тоже работало.


ОК, будет.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[5]: templated VARIANT
От: _nn_  
Дата: 12.01.04 17:41
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, _nn_, Вы писали:


A>>>А какие нужны?

__>>Ну например смена типа.

A>ОК, будет.


__>>Ну в CComVariant работает , так надо чтобы и здесь тоже работало.


A>ОК, будет.


Когда ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[6]: templated VARIANT
От: adontz Грузия http://adontz.wordpress.com/
Дата: 13.01.04 06:42
Оценка:
Здравствуйте, _nn_, Вы писали:

Сам класс вот
typedef class C_Variant : public tagVARIANT
    {
        public:
            C_Variant(const E_VarType & varType = VAR_TYPE_EMPTY)
                {
                    VariantInit(this);
                    if (FAILED(VariantChangeType(this, this, VARIANT_NOUSEROVERRIDE, (VARTYPE)varType)))
                        {
                            vt = (VARTYPE)varType;
                        }
                }
            template <typename TYPE>
            C_Variant(const TYPE & initValue)
                {
                    VariantInit(this);
                    // Local variables
                    VARIANT variant;
                    // Code
                    variant.vt = (VARTYPE)_var_type_from_type<TYPE>();
                    *((TYPE *)_var_address_from_type<TYPE>(variant)) = initValue;
                    VariantCopy(this, &variant);
                }
            C_Variant(const bool & initValue)
                {
                    vt = VT_BOOL;
                    boolVal = initValue ? VARIANT_TRUE : VARIANT_FALSE;
                }
            C_Variant(const char * lpString)
                {
                    VariantInit(this);
                    // Local variables
                    unsigned int lengthConverted = _str_convert_len<WCHAR>(lpString) + 1;
                    C_AutoPtr<WCHAR>    CBuffer(lengthConverted);
                    // Code
                    _str_convert(CBuffer, lpString, lengthConverted);
                    if ((bstrVal = SysAllocStringLen(CBuffer, lengthConverted)) != NULL)
                        {
                            vt = VT_BSTR;
                        }
                }
            C_Variant(SAFEARRAY * lpSafeArray)
                {
                    VariantInit(this);
                    // Local variables
                    VARIANT variant;
                    // Code
                    SafeArrayGetVartype(lpSafeArray, &variant.vt);
                    variant.vt |= VT_ARRAY;
                    variant.parray = lpSafeArray;
                    vt = VT_EMPTY;
                    VariantCopy(this, &variant);
                }
            ~C_Variant()
                {
                    VariantClear(this);
                }
            template <typename TYPE>
            operator TYPE &()
                {
                    return *((TYPE *)_var_address_from_type<TYPE>(*this));
                }
            template <typename TYPE>
            C_Variant & operator = (const TYPE & initValue)
                {
                    // Local variables
                    VARIANT variant;
                    // Code
                    variant.vt = (VARTYPE)_var_type_from_type<TYPE>();
                    *((TYPE *)_var_address_from_type<TYPE>(variant)) = initValue;
                    VariantCopy(this, &variant);
                    return *this;
                }
            C_Variant & operator = (const bool & initValue)
                {
                    VariantClear(this);
                    vt = VT_BOOL;
                    boolVal = initValue ? VARIANT_TRUE : VARIANT_FALSE;
                    return *this;
                }
            C_Variant & operator = (const char * lpString)
                {
                    VariantClear(this);
                    // Local variables
                    unsigned int lengthConverted = _str_convert_len<WCHAR>(lpString) + 1;
                    C_AutoPtr<WCHAR>    CBuffer(lengthConverted);
                    // Code
                    _str_convert(CBuffer, lpString, lengthConverted);
                    if ((bstrVal = SysAllocStringLen(CBuffer, lengthConverted)) != NULL)
                        {
                            vt = VT_BSTR;
                        }
                    return *this;
                }
            C_Variant & operator = (SAFEARRAY * lpSafeArray)
                {
                    VariantClear(this);
                    // Local variables
                    VARIANT variant;
                    // Code
                    SafeArrayGetVartype(lpSafeArray, &variant.vt);
                    variant.vt |= VT_ARRAY;
                    variant.parray = lpSafeArray;
                    vt = VT_EMPTY;
                    VariantCopy(this, &variant);
                    return *this;
                }
            bool operator == (const VARIANT & variant)    const
                {
                    if (vt == VT_NULL && variant.vt == VT_NULL)
                        {
                            return true;
                        }
                    else
                        {
                            return VarCmp(const_cast<C_Variant *>(this), const_cast<VARIANT *>(&variant), LOCALE_USER_DEFAULT, 0) == VARCMP_EQ;
                        }
                }
            bool operator != (const VARIANT & variant)    const
                {
                    if (vt == VT_NULL && variant.vt == VT_NULL)
                        {
                            return false;
                        }
                    else
                        {
                            return VarCmp(const_cast<C_Variant *>(this), const_cast<VARIANT *>(&variant), LOCALE_USER_DEFAULT, 0) != VARCMP_EQ;
                        }
                }
            bool operator < (const VARIANT & variant)    const
                {
                    if (vt == VT_NULL && variant.vt == VT_NULL)
                        {
                            return false;
                        }
                    else
                        {
                            return VarCmp(const_cast<C_Variant *>(this), const_cast<VARIANT *>(&variant), LOCALE_USER_DEFAULT, 0) == VARCMP_LT;
                        }
                }
            bool operator <= (const VARIANT & variant)    const
                {
                    if (vt == VT_NULL && variant.vt == VT_NULL)
                        {
                            return true;
                        }
                    else
                        {
                            return VarCmp(const_cast<C_Variant *>(this), const_cast<VARIANT *>(&variant), LOCALE_USER_DEFAULT, 0) != VARCMP_GT;
                        }
                }
            bool operator > (const VARIANT & variant)    const
                {
                    if (vt == VT_NULL && variant.vt == VT_NULL)
                        {
                            return true;
                        }
                    else
                        {
                            return VarCmp(const_cast<C_Variant *>(this), const_cast<VARIANT *>(&variant), LOCALE_USER_DEFAULT, 0) == VARCMP_GT;
                        }
                }
            bool operator >= (const VARIANT & variant)    const
                {
                    if (vt == VT_NULL && variant.vt == VT_NULL)
                        {
                            return true;
                        }
                    else
                        {
                            return VarCmp(const_cast<C_Variant *>(this), const_cast<VARIANT *>(&variant), LOCALE_USER_DEFAULT, 0) != VARCMP_LT;
                        }
                }
            template <typename TYPE>
            HRESULT Convert(TYPE * lpDestination, USHORT flags = VARIANT_NOUSEROVERRIDE | VARIANT_LOCALBOOL, LCID localeID = MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), SORT_DEFAULT))
                {
                    // Local variables
                    VARIANT    variant;
                    // Code
                    VariantInit(&variant);
                    // Local variables
                    HRESULT hResult = VariantChangeTypeEx(&variant, this, localeID, flags, (VARTYPE)_var_type_from_type<TYPE>());
                    // Code
                    if (FAILED(hResult))
                        {
                            return hResult;
                        }
                    *lpDestination = *((TYPE *)_var_address_from_type<TYPE>(variant));
                    return S_OK;
                }
    }    * LP_CVariant;


Для преобразования строк это


void _str_convert(LPSTR lpDestination, LPCSTR lpSource, unsigned int destLength, WORD codePage = CP_ACP);
//
void _str_convert(LPWSTR lpDestination, LPCSTR lpSource, unsigned int destLength, WORD codePage = CP_ACP);
//
void _str_convert(LPSTR lpDestination, LPCWSTR lpSource, unsigned int destLength, WORD codePage = CP_ACP);
//
void _str_convert(LPWSTR lpDestination, LPCWSTR lpSource, unsigned int destLength, WORD codePage = CP_ACP);
//
template <typename DCHAR, typename SCHAR>
unsigned int _str_convert_len(const SCHAR * lpSource, WORD codePage = CP_ACP)
    {
    }
//
template <>
unsigned int _str_convert_len<CHAR, CHAR>(LPCSTR lpSource, WORD codePage);
template <>
unsigned int _str_convert_len<WCHAR, CHAR>(LPCSTR lpSource, WORD codePage);
template <>
unsigned int _str_convert_len<CHAR, WCHAR>(LPCWSTR lpSource, WORD codePage);
template <>
unsigned int _str_convert_len<WCHAR, WCHAR>(LPCWSTR lpSource, WORD codePage);
//
void _str_convert_char(LPSTR  lpDestination, CHAR source, WORD codePage = CP_ACP);
void _str_convert_char(LPWSTR lpDestination, CHAR source, WORD codePage = CP_ACP);
void _str_convert_char(LPSTR  lpDestination, WCHAR source, WORD codePage = CP_ACP);
void _str_convert_char(LPWSTR lpDestination, WCHAR source, WORD codePage = CP_ACP);
//
unsigned int _str_len(LPCSTR lpSource);
unsigned int _str_len(LPCWSTR lpSource);
//
unsigned int _str_load(HINSTANCE hInstance, int resourceID, LPSTR lpBuffer, unsigned int bufferLength);
unsigned int _str_load(HINSTANCE hInstance, int resourceID, LPWSTR lpBuffer, unsigned int bufferLength);
//
LPSTR  _str_cat(LPSTR lpDestination, LPCSTR lpSource);
LPWSTR _str_cat(LPWSTR lpDestination, LPCWSTR lpSource);
//
LPSTR  _str_copy(LPSTR lpDestination, LPCSTR lpSource);
LPWSTR _str_copy(LPWSTR lpDestination, LPCWSTR lpSource);
LPSTR  _str_copy(LPSTR lpDestination, LPCSTR lpSource, unsigned int maxLength);
LPWSTR _str_copy(LPWSTR lpDestination, LPCWSTR lpSource, unsigned int maxLength);
//
unsigned int _str_lower(LPSTR lpSource, unsigned int sourceLength);
unsigned int _str_lower(LPWSTR lpSource, unsigned int sourceLength);
unsigned int _str_upper(LPSTR lpSource, unsigned int sourceLength);
unsigned int _str_upper(LPWSTR lpSource, unsigned  sourceLength);
//
int _str_comp(LPCSTR lpSource, LPCSTR lpDestination);
int _str_comp(LPCWSTR lpSource, LPCWSTR lpDestination);
int _str_compi(LPCSTR lpSource, LPCSTR lpDestination);
int _str_compi(LPCWSTR lpSource, LPCWSTR lpDestination);
//


+

template <>
unsigned int _str_convert_len<CHAR, CHAR>(LPCSTR lpSource, WORD codePage)
    {
        return lstrlenA(lpSource);
    }
//
template <>
unsigned int _str_convert_len<WCHAR, CHAR>(LPCSTR lpSource, WORD codePage)
    {
        return MultiByteToWideChar(codePage, 0, lpSource, - 1, NULL, 0) - 1;
    }
//
template <>
unsigned int _str_convert_len<CHAR, WCHAR>(LPCWSTR lpSource, WORD codePage)
    {
        return WideCharToMultiByte(codePage, 0, lpSource, - 1, NULL, 0, NULL, NULL) - 1;
    }
//
template <>
unsigned int _str_convert_len<WCHAR, WCHAR>(LPCWSTR lpSource, WORD codePage)
    {
        return lstrlenW(lpSource);
    }
//
void _str_convert(LPSTR lpDestination, LPCSTR lpSource, unsigned int destLength, WORD codePage)
    {
        if ((lpSource != NULL)&&(lpDestination != NULL))
            {
                lstrcpynA(lpDestination, lpSource, destLength);
            }
    }
//
void _str_convert(LPWSTR lpDestination, LPCSTR lpSource, unsigned int destLength, WORD codePage)
    {
        if ((lpSource != NULL)&&(lpDestination != NULL))
            {
                MultiByteToWideChar(codePage, 0, lpSource, - 1, lpDestination, destLength);
            }
    }
//
void _str_convert(LPSTR lpDestination, LPCWSTR lpSource, unsigned int destLength, WORD codePage)
    {
        if ((lpSource != NULL)&&(lpDestination != NULL))
            {
                WideCharToMultiByte(codePage, 0, lpSource, - 1, lpDestination, destLength, NULL, NULL);
            }
    }
//
void _str_convert(LPWSTR lpDestination, LPCWSTR lpSource, unsigned int destLength, WORD codePage)
    {
        if ((lpSource != NULL)&&(lpDestination != NULL))
            {
                lstrcpynW(lpDestination, lpSource, destLength);
            }
    }
//
void _str_convert_char(LPSTR lpDestination, CHAR source, WORD codePage)
    {
        *lpDestination = source;
    }
void _str_convert_char(LPWSTR lpDestination, CHAR source, WORD codePage)
    {
        // Local variables
        CHAR  s[2] = {source, 0};
        WCHAR d[2];
        // Code
        _str_convert(d, s, ARRAY_SIZE(d), codePage);
        *lpDestination = d[0];
    }
void _str_convert_char(LPSTR lpDestination, WCHAR source, WORD codePage)
    {
        // Local variables
        WCHAR s[2] = {source, 0};
        CHAR  d[2];
        // Code
        _str_convert(d, s, ARRAY_SIZE(d), codePage);
        *lpDestination = d[0];
    }
void _str_convert_char(LPWSTR lpDestination, WCHAR source, WORD codePage)
    {
        *lpDestination = source;
    }
//
unsigned int _str_len(LPCSTR lpSource)
    {
        return lstrlenA(lpSource);
    }
//
unsigned int _str_len(LPCWSTR lpSource)
    {
        return lstrlenW(lpSource);
    }
//
unsigned int _str_load(HINSTANCE hInstance, int resourceID, LPSTR lpBuffer, unsigned int bufferLength)
    {
        return LoadStringA(hInstance, resourceID, lpBuffer, bufferLength);
    }
//
unsigned int _str_load(HINSTANCE hInstance, int resourceID, LPWSTR lpBuffer, unsigned int bufferLength)
    {
        return LoadStringW(hInstance, resourceID, lpBuffer, bufferLength);
    }
//
LPSTR _str_cat(LPSTR lpDestination, LPCSTR lpSource)
    {
        return lstrcatA(lpDestination, lpSource);
    }
//
LPWSTR _str_cat(LPWSTR lpDestination, LPCWSTR lpSource)
    {
        return lstrcatW(lpDestination, lpSource);
    }
//
LPSTR _str_copy(LPSTR lpDestination, LPCSTR lpSource)
    {
        return lstrcpyA(lpDestination, lpSource);
    }
//
LPWSTR _str_copy(LPWSTR lpDestination, LPCWSTR lpSource)
    {
        return lstrcpyW(lpDestination, lpSource);
    }
//
LPSTR _str_copy(LPSTR lpDestination, LPCSTR lpSource, unsigned int maxLength)
    {
        return lstrcpynA(lpDestination, lpSource, maxLength);
    }
//
LPWSTR _str_copy(LPWSTR lpDestination, LPCWSTR lpSource, unsigned int maxLength)
    {
        return lstrcpynW(lpDestination, lpSource, maxLength);
    }
//
unsigned int _str_lower(LPSTR lpSource, unsigned int sourceLength)
    {
        return CharLowerBuffA(lpSource, sourceLength);
    }
unsigned int _str_lower(LPWSTR lpSource, unsigned int sourceLength)
    {
        return CharLowerBuffW(lpSource, sourceLength);
    }
//
unsigned int _str_upper(LPSTR lpSource, unsigned int sourceLength)
    {
        return CharUpperBuffA(lpSource, sourceLength);
    }
//
unsigned int _str_upper(LPWSTR lpSource, unsigned int sourceLength)
    {
        return CharUpperBuffW(lpSource, sourceLength);
    }
//
int _str_comp(LPCSTR lpSource, LPCSTR lpDestination)
    {
        if ((lpSource != NULL)&&(lpDestination != NULL))
            {
                return lstrcmpA(lpSource, lpDestination);
            }
        else
            {
                return lpSource - lpDestination;
            }
    }
//
int _str_comp(LPCWSTR lpSource, LPCWSTR lpDestination)
    {
        if ((lpSource != NULL)&&(lpDestination != NULL))
            {
                return lstrcmpW(lpSource, lpDestination);
            }
        else
            {
                return lpSource - lpDestination;
            }
    }
//
int _str_compi(LPCSTR lpSource, LPCSTR lpDestination)
    {
        if ((lpSource != NULL)&&(lpDestination != NULL))
            {
                return lstrcmpiA(lpSource, lpDestination);
            }
        else
            {
                return lpSource - lpDestination;
            }
    }
//
int _str_compi(LPCWSTR lpSource, LPCWSTR lpDestination)
    {
        if ((lpSource != NULL)&&(lpDestination != NULL))
            {
                return lstrcmpiW(lpSource, lpDestination);
            }
        else
            {
                return lpSource - lpDestination;
            }
    }


Выносить реализацию шаблона в заголовочный файл не стоит — проблемы с компоновкой потом бывают.
... << RSDN@Home 1.1.0 stable >>
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[7]: templated VARIANT
От: WolfHound  
Дата: 13.01.04 09:36
Оценка:
Здравствуйте, adontz, Вы писали:

A>Выносить реализацию шаблона в заголовочный файл не стоит — проблемы с компоновкой потом бывают.

inline спасет отца русской демократии.
... << RSDN@Home 1.1 beta 2 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[7]: templated VARIANT
От: _nn_  
Дата: 14.01.04 08:01
Оценка:
Здравствуйте, adontz, Вы писали:

Неясны некоторые моменты :
Почему название класса C_Variant , а не _variant или т.п. ?
Почему еще и с typedef идет ?
C_AutoPtr это как я понимаю auto_ptr ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[8]: templated VARIANT
От: adontz Грузия http://adontz.wordpress.com/
Дата: 14.01.04 12:38
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Почему название класса C_Variant , а не _variant или т.п. ?

Привычка. Это CClass переменная, а это C_Class тип. Тогда набрав C_ и нажав Ctrl+Spase я получу имена только типов. Мельчь, а приятно.

__>Почему еще и с typedef идет ?

Сишный атавизм.

__>C_AutoPtr это как я понимаю auto_ptr ?


template <typename TYPE, UINT size = 0>
class C_AutoPtr
    {
        protected:
            TYPE * lpData;
        public:
            C_AutoPtr()
                {
                    DEBUG_CHECK(size != 0)
                    lpData = new TYPE[size];
                    if (lpData == NULL)
                        {
                            throw C_Exception(ERROR_OUTOFMEMORY);
                        }
                }
            C_AutoPtr(unsigned int sizeInit)
                {
                    DEBUG_CHECK((size|sizeInit) != 0)
                    DEBUG_CHECK((size&sizeInit) == 0)
                    lpData = new TYPE[sizeInit];
                    if (lpData == NULL)
                        {
                            throw C_Exception(ERROR_OUTOFMEMORY);
                        }
                }
            ~C_AutoPtr()
                {
                    delete[] lpData;
                }
            operator TYPE * ()
                {
                    DEBUG_CHECK(memValidate(lpData))
                    return lpData;
                }
            operator LPVOID()
                {
                    DEBUG_CHECK(memValidate(lpData))
                    return lpData;
                }
            operator int()
                {
                    return (int)(memSize(lpData)/sizeof(TYPE));
                }
            operator unsigned int()
                {
                    return (unsigned int)(memSize(lpData)/sizeof(TYPE));
                }
            operator long()
                {
                    return (long)(memSize(lpData)/sizeof(TYPE));
                }
            operator unsigned long()
                {
                    return (unsigned long)(memSize(lpData)/sizeof(TYPE));
                }
    };
//

DEBUG_CHECK это типа ASSERT но существует только в DEBUG версии и не рушит программу, а тихонечко пишет в окно Output отладчика. ИМХО так удобнее отлавливать сразу несколько ошибок.

memAlloc == new == HeapAlloc
memFree = delete == HeapFree
memValidate == HeapValidate
memSize == HeapSize

В принципе можно заменить на функции CRT, но просто класс из проекта где нет CRT
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[9]: templated VARIANT
От: adontz Грузия http://adontz.wordpress.com/
Дата: 14.01.04 12:48
Оценка:
Здравствуйте, adontz, Вы писали:

__>>Почему еще и с typedef идет ?

A>Сишный атавизм.

Нет не атавизм. Из-за этого
    }    * LP_CVariant;

typedef очень даже нужен.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[9]: templated VARIANT
От: _nn_  
Дата: 14.01.04 16:43
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, _nn_, Вы писали:


__>>Почему название класса C_Variant , а не _variant или т.п. ?

A>Привычка. Это CClass переменная, а это C_Class тип. Тогда набрав C_ и нажав Ctrl+Spase я получу имена только типов. Мельчь, а приятно.

Но все же например _var_type_from_type , написан в другом таком стиле.
Надо придерживаться одного стиля при написании

__>>Почему еще и с typedef идет ?

A>Сишный атавизм.

Почему не сделать так :
class C_Variant // ...

typedef C_Variant* LP_CVariant;

Но все таки лучше всего назвать как нибудь типа _variant и оформить в пространстве имен.

__>>C_AutoPtr это как я понимаю auto_ptr ?


A>
A>template <typename TYPE, UINT size = 0>
A>class C_AutoPtr
// ..
// <skip>
A>


В таком виде для каждого размера компилятор будет создавать разные классы.

Вот класс в замену C_AutoPtr(всякие проверки убраны) :

template<typename TYPE>
class _auto_ptr
{
protected:
    TYPE* pData;
public:
    inline _auto_ptr(unsigned sizeInit)
    {
        pData=sizeInit?new TYPE[sizeInit]:0;
    }
    inline _auto_ptr(TYPE* psetdata)
    {
        pData=psetdata;
    }
    inline ~_auto_ptr()
    {
        delete[] pData;
    }
    inline setdata(TYPE* psetdata)
    {
        if(pData) delete[] pData;
        pData=psetdata;
    }
    inline operator TYPE*()
    {
        return pData;
    }
    inline operator void*()
    {
        return lpData;
    }
    inline operator unsigned()
    {
        return memSize(lpData)/sizeof(TYPE);
    }
 }
};


И весь код поместить в один файл , inline нам поможет , как писал нам об этом выше WolfHound (http://www.rsdn.ru/Forum/Message.aspx?mid=505099&amp;only=1
Автор: WolfHound
Дата: 13.01.04
).

С Уважением.
NN.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.