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