| /******************************************************************************* | |
| * 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_ |