/******************************************************************************* | |
* Copyright (c) 2012 AIT | |
* This program and the accompanying materials are made available under the | |
* terms of the Eclipse Public License 2.0 which is available at | |
* http://www.eclipse.org/legal/epl-2.0. | |
* | |
* SPDX-License-Identifier: EPL-2.0 | |
* | |
* Contributors: | |
* Werner Tremmel - initial API and implementation and/or initial documentation | |
*******************************************************************************/ | |
#ifndef VARIANTNEW_H_ | |
#define VARIANTNEW_H_ | |
#include <boost/lexical_cast.hpp> | |
/*! \brief structure for simplified handling of the VARIANT | |
* | |
* The structure simplifies the handling of the VARIANT with numeric types. | |
*/ | |
#include <OleAuto.h> | |
#include <comutil.h> | |
struct Variant : public VARIANT{ | |
public: | |
class VariantException : public std::exception{ | |
public: | |
VariantException(){ | |
} | |
virtual const char* what() throw (){ | |
return "VariantException: unknown variant type"; | |
} | |
}; | |
~Variant(){ | |
} | |
Variant(){ | |
} | |
explicit Variant(const _variant_t &value) : | |
VARIANT(value){ | |
} | |
explicit Variant(const VARIANT &value) : | |
VARIANT(value){ | |
} | |
explicit Variant(bool value){ | |
setbool(value); | |
} | |
explicit Variant(BOOL value){ | |
setbool(value != 0); | |
} | |
explicit Variant(VARIANT_BOOL value){ | |
setbool(value != 0); | |
} | |
template<typename T> explicit Variant(T value){ | |
set<T>(value); | |
} | |
template<typename T> T get() const{ | |
switch (vt){ | |
case VT_I8: | |
return static_cast < T > (llVal); | |
case VT_I4: | |
return static_cast < T > (lVal); | |
case VT_I2: | |
return static_cast < T > (iVal); | |
case VT_I1: | |
return static_cast < T > (cVal); | |
case VT_UI8: | |
return static_cast < T > (ullVal); | |
case VT_UI4: | |
return static_cast < T > (ulVal); | |
case VT_UI2: | |
return static_cast < T > (uiVal); | |
case VT_UI1: | |
return static_cast < T > (bVal); | |
case VT_R8: | |
return static_cast < T > (dblVal); | |
case VT_R4: | |
return static_cast < T > (fltVal); | |
case VT_INT: | |
return static_cast < T > (intVal); | |
case VT_UINT: | |
return static_cast < T > (uintVal); | |
case VT_BOOL: | |
return boolVal != 0 ? static_cast < T > (1) : static_cast < T > (0); | |
default: | |
throw VariantException(); | |
} | |
} | |
template<> std::string get<std::string>() const{ | |
switch (vt){ | |
case VT_I8: | |
return boost::lexical_cast < std::string > (llVal); | |
case VT_I4: | |
return boost::lexical_cast < std::string > (lVal); | |
case VT_I2: | |
return boost::lexical_cast < std::string > (iVal); | |
case VT_I1: | |
return boost::lexical_cast < std::string > (cVal); | |
case VT_UI8: | |
return boost::lexical_cast < std::string > (ullVal); | |
case VT_UI4: | |
return boost::lexical_cast < std::string > (ulVal); | |
case VT_UI2: | |
return boost::lexical_cast < std::string > (uiVal); | |
case VT_UI1: | |
return boost::lexical_cast < std::string > (bVal); | |
case VT_R8: | |
return boost::lexical_cast < std::string > (dblVal); | |
case VT_R4: | |
return boost::lexical_cast < std::string > (fltVal); | |
case VT_INT: | |
return boost::lexical_cast < std::string > (intVal); | |
case VT_UINT: | |
return boost::lexical_cast < std::string > (uintVal); | |
case VT_BOOL: | |
return boolVal != 0 ? boost::lexical_cast < std::string > (true) : boost::lexical_cast < std::string > (false); | |
default: | |
throw VariantException(); | |
} | |
} | |
template<> bool get<bool>() const{ | |
switch (vt){ | |
case VT_I8: | |
return llVal != 0 ? true : false; | |
case VT_I4: | |
return lVal != 0 ? true : false; | |
case VT_I2: | |
return iVal != 0 ? true : false; | |
case VT_I1: | |
return cVal != 0 ? true : false; | |
case VT_UI8: | |
return ullVal != 0 ? true : false; | |
case VT_UI4: | |
return ulVal != 0 ? true : false; | |
case VT_UI2: | |
return uiVal != 0 ? true : false; | |
case VT_UI1: | |
return bVal != 0 ? true : false; | |
case VT_R8: | |
return dblVal != 0 ? true : false; | |
case VT_R4: | |
return fltVal != 0 ? true : false; | |
case VT_INT: | |
return intVal != 0 ? true : false; | |
case VT_UINT: | |
return uintVal != 0 ? true : false; | |
case VT_BOOL: | |
return boolVal != 0 ? true : false; | |
default: | |
throw VariantException(); | |
} | |
} | |
void setbool(bool value){ | |
boolVal = value ? 0xffff : 0; | |
vt = VT_BOOL; | |
} | |
template<typename T> void set(T value){ | |
getField<T>() = value; | |
vt = getType<T>(); | |
} | |
template<> void set<bool>(bool value){ | |
setbool(value); | |
} | |
void setBOOL(BOOL value){ | |
setbool(value != 0); | |
} | |
void setVARIANT_BOOL(VARIANT_BOOL value){ | |
setbool(value != 0); | |
} | |
template<typename T> bool isType() const{ | |
return vt == getType<T>(); | |
} | |
bool isInteger() const{ | |
switch (vt){ | |
case VT_I8: | |
case VT_I4: | |
case VT_I2: | |
case VT_I1: | |
case VT_INT: | |
return true; | |
default: | |
return false; | |
} | |
} | |
bool isUnsignedInteger() const{ | |
switch (vt){ | |
case VT_UI8: | |
case VT_UI4: | |
case VT_UI2: | |
case VT_UI1: | |
case VT_UINT: | |
return true; | |
default: | |
return false; | |
} | |
} | |
bool isFloatingPoint() const{ | |
switch (vt){ | |
case VT_R8: | |
case VT_R4: | |
return true; | |
default: | |
return false; | |
} | |
} | |
template<typename T> VARTYPE getType() const{ | |
constraint<T>(); | |
} | |
template<> VARTYPE getType<LONGLONG>() const{ | |
return VT_I8; | |
} | |
template<> VARTYPE getType<LONG>() const{ | |
return VT_I4; | |
} | |
template<> VARTYPE getType<SHORT>() const{ | |
return VT_I2; | |
} | |
template<> VARTYPE getType<CHAR>() const{ | |
return VT_I1; | |
} | |
template<> VARTYPE getType<signed char>() const{ | |
return VT_I1; | |
} | |
template<> VARTYPE getType<ULONGLONG>() const{ | |
return VT_UI8; | |
} | |
template<> VARTYPE getType<ULONG>() const{ | |
return VT_UI4; | |
} | |
template<> VARTYPE getType<USHORT>() const{ | |
return VT_UI2; | |
} | |
template<> VARTYPE getType<BYTE>() const{ | |
return VT_UI1; | |
} | |
template<> VARTYPE getType<float>() const{ | |
return VT_R4; | |
} | |
template<> VARTYPE getType<double>() const{ | |
return VT_R8; | |
} | |
//template<> VARTYPE getType<BOOL>() const{ | |
// return VT_BOOL; | |
//} | |
template<> VARTYPE getType<INT>() const{ | |
return VT_INT; | |
} | |
template<> VARTYPE getType<UINT>() const{ | |
return VT_UINT; | |
} | |
template<typename T> T &getField(){ | |
constraint<T>(); | |
} | |
template<> LONGLONG &getField<LONGLONG>(){ | |
return llVal; | |
} | |
template<> LONG &getField<LONG>(){ | |
return lVal; | |
} | |
template<> SHORT &getField<SHORT>(){ | |
return iVal; | |
} | |
template<> CHAR &getField<CHAR>(){ | |
return cVal; | |
} | |
template<> signed char &getField<signed char>(){ | |
return (signed char&)cVal; | |
} | |
template<> ULONGLONG &getField<ULONGLONG>(){ | |
return ullVal; | |
} | |
template<> ULONG &getField<ULONG>(){ | |
return ulVal; | |
} | |
template<> USHORT &getField<USHORT>(){ | |
return uiVal; | |
} | |
template<> BYTE &getField<BYTE>(){ | |
return bVal; | |
} | |
template<> float &getField<float>(){ | |
return fltVal; | |
} | |
template<> double &getField<double>(){ | |
return dblVal; | |
} | |
template<> INT &getField<INT>(){ | |
return intVal; | |
} | |
template<> UINT &getField<UINT>(){ | |
return uintVal; | |
} | |
bool operator==(const Variant &other) const{ | |
if(vt != other.vt) { | |
return false; | |
} | |
ULONGLONG mask = ~0ul; | |
switch (vt){ | |
case VT_I4: | |
case VT_UI4: | |
case VT_INT: | |
case VT_UINT: | |
case VT_R4: | |
mask = 0xffffffffull; | |
break; | |
case VT_I2: | |
case VT_UI2: | |
case VT_BOOL: | |
mask = 0xffffull; | |
break; | |
case VT_I1: | |
case VT_UI1: | |
mask = 0xffull; | |
break; | |
} | |
return ((ullVal ^ other.ullVal) & mask) == 0; | |
} | |
/*! \brief Compiler error, when used | |
* | |
* This is only here to throw a compiler error when used. So the unsupported types are caught by the compiler | |
* and not by the runtime system | |
*/ | |
template<typename T> static void constraint(){ | |
char a[2]; | |
a[1.2] = 0; | |
} | |
}; | |
#endif //VARIANTNEW_H_ |