/*! \file pivariant.h * \brief Variant type * * This file declares PIVariant */ /* PIP - Platform Independent Primitives Variant type Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef PIVARIANT_H #define PIVARIANT_H #include "pistring.h" #include "pibitarray.h" #include "pitime.h" #include "pimath.h" #define __PIVARIANT_UNION_SIZE__ 32 #define _vcomplexd (*((complexd*)_vraw)) #define _vcomplexld (*((complexld*)_vraw)) #define _vtime (*((PITime*)_vraw)) #define _vdate (*((PIDate*)_vraw)) #define _vdatetime (*((PIDateTime*)_vraw)) #define _vsystime (*((PISystemTime*)_vraw)) #define _vvcomplexd(v) (*((complexd*)v._vraw)) #define _vvcomplexld(v) (*((complexld*)v._vraw)) #define _vvtime(v) (*((PITime*)v._vraw)) #define _vvdate(v) (*((PIDate*)v._vraw)) #define _vvdatetime(v) (*((PIDateTime*)v._vraw)) #define _vvsystime(v) (*((PISystemTime*)v._vraw)) class PIP_EXPORT PIVariant { friend PICout operator <<(PICout s, const PIVariant & v); public: //! Type of %PIVariant content enum Type { Invalid /** Invalid type , default type of empty contructor */ = 0 , Bool /** bool */ , Char /** char */ , UChar /** uchar */ , Short /** short */ , UShort /** ushort */ , Int /** int */ , UInt /** uint */ , Long /** long */ , ULong /** ulong */ , LLong /** llong */ , ULLong /** ullong */ , Float /** float */ , Double /** double */ , LDouble /** ldouble */ , Complexd /** complexd */ , Complexld /** complexld */ , BitArray /** PIBitArray */ , ByteArray /** PIByteArray */ , String /** PIString */ , StringList /** PIStringList */ , Time /** PITime */ , Date /** PIDate */ , DateTime /** PIDateTime */ , SystemTime /** PISystemTime */ , Custom /** Custom */ = 0xFF }; //! Empty constructor, \a type() will be set to \a Invalid PIVariant(); //! Constructs variant from string PIVariant(const char * v) {setValue(PIString(v));} //! Constructs variant from boolean PIVariant(const bool v) {setValue(v);} //! Constructs variant from char PIVariant(const char v) {setValue(v);} //! Constructs variant from integer PIVariant(const uchar v) {setValue(v);} //! Constructs variant from integer PIVariant(const short v) {setValue(v);} //! Constructs variant from integer PIVariant(const ushort v) {setValue(v);} //! Constructs variant from integer PIVariant(const int & v) {setValue(v);} //! Constructs variant from integer PIVariant(const uint & v) {setValue(v);} //! Constructs variant from integer PIVariant(const long & v) {setValue(v);} //! Constructs variant from integer PIVariant(const ulong & v) {setValue(v);} //! Constructs variant from integer PIVariant(const llong & v) {setValue(v);} //! Constructs variant from integer PIVariant(const ullong & v) {setValue(v);} //! Constructs variant from float PIVariant(const float & v) {setValue(v);} //! Constructs variant from double PIVariant(const double & v) {setValue(v);} //! Constructs variant from long double PIVariant(const ldouble & v) {setValue(v);} //! Constructs variant from complex PIVariant(const complexd & v) {setValue(v);} //! Constructs variant from complex PIVariant(const complexld & v) {setValue(v);} //! Constructs variant from bit array PIVariant(const PIBitArray & v) {setValue(v);} //! Constructs variant from byte array PIVariant(const PIByteArray & v) {setValue(v);} //! Constructs variant from string PIVariant(const PIString & v) {setValue(v);} //! Constructs variant from strings list PIVariant(const PIStringList & v) {setValue(v);} //! Constructs variant from time PIVariant(const PITime & v) {setValue(v);} //! Constructs variant from date PIVariant(const PIDate & v) {setValue(v);} //! Constructs variant from date and time PIVariant(const PIDateTime & v) {setValue(v);} //! Constructs variant from system time PIVariant(const PISystemTime & v) {setValue(v);} //! Set variant content and type to string void setValue(const char * v) {setValue(PIString(v));} //! Set variant content and type to boolean void setValue(const bool v) {type_ = PIVariant::Bool; _vint = (v ? 1 : 0);} //! Set variant content and type to char void setValue(const char v) {type_ = PIVariant::Char; _vint = v;} //! Set variant content and type to integer void setValue(const uchar v) {type_ = PIVariant::UChar; _vint = v;} //! Set variant content and type to integer void setValue(const short v) {type_ = PIVariant::Short; _vint = v;} //! Set variant content and type to integer void setValue(const ushort v) {type_ = PIVariant::UShort; _vint = v;} //! Set variant content and type to integer void setValue(const int & v) {type_ = PIVariant::Int; _vint = v;} //! Set variant content and type to integer void setValue(const uint & v) {type_ = PIVariant::UInt; _vint = v;} //! Set variant content and type to integer void setValue(const long & v) {type_ = PIVariant::Long; _vint = v;} //! Set variant content and type to integer void setValue(const ulong & v) {type_ = PIVariant::ULong; _vint = v;} //! Set variant content and type to integer void setValue(const llong & v) {type_ = PIVariant::LLong; _vllong = v;} //! Set variant content and type to integer void setValue(const ullong & v) {type_ = PIVariant::ULLong; _vllong = v;} //! Set variant content and type to float void setValue(const float & v) {type_ = PIVariant::Float; _vfloat = v;} //! Set variant content and type to double void setValue(const double & v) {type_ = PIVariant::Double; _vdouble = v;} //! Set variant content and type to long double void setValue(const ldouble & v) {type_ = PIVariant::LDouble; _vldouble = v;} //! Set variant content and type to complex void setValue(const complexd & v) {type_ = PIVariant::Complexd; _vcomplexd = v;} //! Set variant content and type to complex void setValue(const complexld & v) {type_ = PIVariant::Complexld; _vcomplexld = v;} //! Set variant content and type to bit array void setValue(const PIBitArray & v) {type_ = PIVariant::BitArray; _vbitarray = v;} //! Set variant content and type to byte array void setValue(const PIByteArray & v) {type_ = PIVariant::ByteArray; _vbytearray = v;} //! Set variant content and type to string void setValue(const PIString & v) {type_ = PIVariant::String; _vstring = v;} //! Set variant content and type to strings list void setValue(const PIStringList & v) {type_ = PIVariant::StringList; _vstringlist = v;} //! Set variant content and type to time void setValue(const PITime & v) {type_ = PIVariant::Time; _vtime = v;} //! Set variant content and type to date void setValue(const PIDate & v) {type_ = PIVariant::Date; _vdate = v;} //! Set variant content and type to date and time void setValue(const PIDateTime & v) {type_ = PIVariant::DateTime; _vdatetime = v;} //! Set variant content and type to system time void setValue(const PISystemTime & v) {type_ = PIVariant::SystemTime; _vsystime = v;} bool toBool() const; int toInt() const; llong toLLong() const; float toFloat() const; double toDouble() const; ldouble toLDouble() const; complexd toComplexd() const; complexld toComplexld() const; PITime toTime() const; PIDate toDate() const; PIDateTime toDateTime() const; PISystemTime toSystemTime() const; PIString toString() const; PIStringList toStringList() const; PIBitArray toBitArray() const; PIByteArray toByteArray() const; /** \brief Returns variant content as custom type * \details In case of known types this function equivalent \a to function. \n * Otherwise returns content as type T. */ template T toValue() const {if (_vcustom.size() != sizeof(T)) return T(); return *((T*)_vcustom.data());} /* operator bool() const {return toBool();} operator char() const {return toInt();} operator uchar() const {return toInt();} operator short() const {return toInt();} operator ushort() const {return toInt();} operator int() const {return toInt();} operator uint() const {return toInt();} operator long() const {return toInt();} operator ulong() const {return toInt();} operator llong() const {return toLLong();} operator ullong() const {return (ullong)toLLong();} operator float() const {return toFloat();} operator double() const {return toDouble();} operator ldouble() const {return toLDouble();} operator complexd() const {return toComplexd();} operator complexld() const {return toComplexld();} operator PITime() const {return toTime();} operator PIDate() const {return toDate();} operator PIDateTime() const {return toDateTime();} operator PIString() const {return toString();} operator PIStringList() const {return toStringList();} operator PIBitArray() const {return toBitArray();} operator PIByteArray() const {return toByteArray();} operator const char*() const {return toString().data();} operator void*() const {return (void*)(toLLong());} */ //! Assign operator PIVariant & operator =(const PIVariant & v); //! Assign operator PIVariant & operator =(const char * v) {setValue(PIString(v)); return *this;} //! Assign operator PIVariant & operator =(const bool v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const char v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const uchar v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const short v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const ushort v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const int & v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const uint & v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const long & v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const ulong & v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const llong & v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const ullong & v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const float & v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const double & v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const ldouble & v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const complexd & v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const complexld & v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const PIBitArray & v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const PIByteArray & v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const PIString & v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const PIStringList & v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const PITime & v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const PIDate & v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const PIDateTime & v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const PISystemTime & v) {setValue(v); return *this;} //! Compare operator bool operator ==(const PIVariant & v) const; //! Compare operator bool operator !=(const PIVariant & v) const {return !(*this == v);} //! Returns type of variant content PIVariant::Type type() const {return type_;} //! Returns type name of variant content PIString typeName() const {return typeName(type_);} //! Returns \b true if type is not Invalid bool isValid() const {return type_ != PIVariant::Invalid;} /** \brief Returns new variant from custom type * \details In case of known types this function equivalent \a PIVariant(T) constructors. \n * Otherwise returns variant with content \a v and type Custom. */ template static PIVariant fromValue(const T & v) {PIVariant ret; ret._vcustom.resize(sizeof(T)); new((T*)(ret._vcustom.data()))T(v); ret.type_ = PIVariant::Custom; return ret;} //! Returns type from name static PIVariant::Type typeFromName(const PIString & tname); //! Returns type name static PIString typeName(PIVariant::Type type); private: void destroy() {_vcustom.clear();} union { int _vint; llong _vllong; float _vfloat; double _vdouble; ldouble _vldouble; uchar _vraw[__PIVARIANT_UNION_SIZE__]; /*complexd _vcomplexd; complexld _vcomplexld; PITime _vtime; PIDate _vdate; PIDateTime _vdatetime; PISystemTime _vsystime;*/ }; PIBitArray _vbitarray; PIByteArray _vbytearray; PIString _vstring; PIStringList _vstringlist; PIByteArray _vcustom; PIVariant::Type type_; }; template<> inline bool PIVariant::toValue() const {return toBool();} template<> inline char PIVariant::toValue() const {return (char)toInt();} template<> inline uchar PIVariant::toValue() const {return (uchar)toInt();} template<> inline short PIVariant::toValue() const {return (short)toInt();} template<> inline ushort PIVariant::toValue() const {return (ushort)toInt();} template<> inline int PIVariant::toValue() const {return toInt();} template<> inline uint PIVariant::toValue() const {return (uint)toInt();} template<> inline long PIVariant::toValue() const {return (long)toInt();} template<> inline ulong PIVariant::toValue() const {return (ulong)toInt();} template<> inline llong PIVariant::toValue() const {return toLLong();} template<> inline ullong PIVariant::toValue() const {return (ullong)toLLong();} template<> inline float PIVariant::toValue() const {return toFloat();} template<> inline double PIVariant::toValue() const {return toDouble();} template<> inline ldouble PIVariant::toValue() const {return toLDouble();} template<> inline complexd PIVariant::toValue() const {return toComplexd();} template<> inline complexld PIVariant::toValue() const {return toComplexld();} template<> inline void* PIVariant::toValue() const {return (void*)toLLong();} template<> inline const char* PIVariant::toValue() const {return toString().data();} template<> inline PITime PIVariant::toValue() const {return toTime();} template<> inline PIDate PIVariant::toValue() const {return toDate();} template<> inline PIDateTime PIVariant::toValue() const {return toDateTime();} template<> inline PIString PIVariant::toValue() const {return toString();} template<> inline PIStringList PIVariant::toValue() const {return toStringList();} template<> inline PIBitArray PIVariant::toValue() const {return toBitArray();} template<> inline PIByteArray PIVariant::toValue() const {return toByteArray();} //template<> inline PIVariant PIVariant::fromValue(const char * v) {return PIVariant(PIString(v));} template<> inline PIVariant PIVariant::fromValue(const bool & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const char & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const uchar & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const short & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const ushort & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const int & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const uint & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const long & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const ulong & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const llong & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const ullong & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const float & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const double & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const ldouble & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const complexd & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const complexld & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIBitArray & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIByteArray & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIString & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIStringList & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PITime & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIDate & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIDateTime & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PISystemTime & v) {return PIVariant(v);} inline PICout operator <<(PICout s, const PIVariant & v) { s.space(); s.setControl(0, true); s << "PIVariant(" << PIVariant::typeName(v.type()) << ", "; if (v.type() == PIVariant::Custom) s << v._vcustom.size() << " bytes"; else s << v.toString(); s << ")"; s.restoreControl(); return s; } #endif // PIVARIANT_H