/*! \file pivariant.h * \ingroup Core * \brief * \~english Variant type * \~russian Вариативный тип */ /* PIP - Platform Independent Primitives Variant type Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef PIVARIANT_H #define PIVARIANT_H #include "pivarianttypes.h" #include "piconstchars.h" #include "pitime.h" #include "pigeometry.h" #include "pimathmatrix.h" #ifdef DOXYGEN //! \relatesalso PIVariant //! \~\brief //! \~english Macro to register type for using in %PIVariant //! \~russian Макрос для регистрации типа для использования в %PIVariant # define REGISTER_VARIANT(Typename) //! \relatesalso PIVariant //! \~\brief //! \~english Macro to register type with namespace for using in %PIVariant //! \~russian Макрос для регистрации типа с пространством имен для использования в %PIVariant # define REGISTER_NS_VARIANT(Namespace, Typename) #endif #ifndef QNX # define CUSTOM_PIVARIANT #endif #ifdef CUSTOM_PIVARIANT template class __PIVariantFunctions__ { public: static PIString typeNameHelper() {return PIStringAscii("");} static bool isSimpleHelper() {return false;} template static PIByteArray castHelper(PIByteArray ba) {return PIByteArray();} template static C castVariant(const T & v) {return C();} }; struct PIP_EXPORT __PIVariantInfo__ { __PIVariantInfo__() { simple = false; } typedef PIByteArray(*castHelperFunc)(PIByteArray); PIMap cast; PIString typeName; bool simple; }; template struct __PIVariantTypeInfo__ { typedef T PureType; typedef const T ConstPureType; typedef T * PointerType; typedef const T * ConstPointerType; typedef T & ReferenceType; typedef const T & ConstReferenceType; }; #define __TYPEINFO_SINGLE(PT, T) \ template<> struct __PIVariantTypeInfo__ { \ typedef PT PureType; \ typedef const PT ConstPureType; \ typedef PT * PointerType; \ typedef const PT * ConstPointerType; \ typedef PT & ReferenceType; \ typedef const PT & ConstReferenceType; \ }; #define REGISTER_VARIANT_TYPEINFO(T) \ __TYPEINFO_SINGLE(T, T &) \ __TYPEINFO_SINGLE(T, const T) \ __TYPEINFO_SINGLE(T, const T &) class PIP_EXPORT __PIVariantInfoStorage__ { public: __PIVariantInfoStorage__() {if (!map) map = new PIMap();} static __PIVariantInfoStorage__ * get() {static __PIVariantInfoStorage__ * r = new __PIVariantInfoStorage__(); return r;} static PIMap * map; }; #define REGISTER_VARIANT_H(classname) \ template<> inline PIString __PIVariantFunctions__< classname >::typeNameHelper() {static PIString tn = PIStringAscii(#classname); return tn;} \ REGISTER_VARIANT_TYPEINFO(classname) #define REGISTER_NS_VARIANT_H(ns, classname) \ template<> inline PIString __PIVariantFunctions__< ns::classname >::typeNameHelper() {static PIString tn = PIStringAscii(#ns"::"#classname); return tn;} \ REGISTER_VARIANT_TYPEINFO(ns::classname) #define REGISTER_VARIANT_CPP(classname) \ template \ class __##classname##_PIVariantInitializer__ { \ public: \ __##classname##_PIVariantInitializer__(const PIString & name) { \ if (__PIVariantInfoStorage__::get()->map->contains(name)) \ return; \ __PIVariantInfo__ * vi = new __PIVariantInfo__(); \ vi->typeName = name; \ (*(__PIVariantInfoStorage__::get()->map))[name] = vi; \ } \ }; #define REGISTER_NS_VARIANT_CPP(ns, classname) \ template \ class __##ns##classname##_PIVariantInitializer__ { \ public: \ __##ns##classname##_PIVariantInitializer__(const PIString & name) { \ if (__PIVariantInfoStorage__::get()->map->contains(name)) \ return; \ __PIVariantInfo__ * vi = new __PIVariantInfo__(); \ vi->typeName = name; \ (*(__PIVariantInfoStorage__::get()->map))[name] = vi; \ } \ }; #define INIT_VARIANT(classname) \ __##classname##_PIVariantInitializer__< classname > __##classname##_pivariant_initializer__(#classname); #define INIT_NS_VARIANT(ns, classname) \ __##ns##classname##_PIVariantInitializer__< ns::classname > __##ns##classname##_pivariant_initializer__(#ns"::"#classname); #define REGISTER_VARIANT(classname) \ REGISTER_VARIANT_H(classname) \ REGISTER_VARIANT_CPP(classname) \ static INIT_VARIANT(classname) #define REGISTER_NS_VARIANT(ns, classname) \ REGISTER_NS_VARIANT_H(ns, classname) \ REGISTER_NS_VARIANT_CPP(ns, classname) \ static INIT_NS_VARIANT(ns, classname) #define REGISTER_VARIANT_CAST_H(classname_from, classname_to) \ template<> template<> inline \ classname_to __PIVariantFunctions__::castVariant(const classname_from & v); #define REGISTER_VARIANT_CAST_CPP(classname_from, classname_to) \ template<> template<> inline \ PIByteArray __PIVariantFunctions__::castHelper(PIByteArray v) { \ classname_from f; v >> f; \ classname_to t = __PIVariantFunctions__::castVariant(f); \ PIByteArray ret; ret << t; \ return ret;} \ template \ class __##classname_from##_##classname_to##_PIVariantCastInitializer__ { \ public: \ __##classname_from##_##classname_to##_PIVariantCastInitializer__(const PIString & name, const PIString & cname) { \ __PIVariantInfo__ * vi(__PIVariantInfoStorage__::get()->map->value(name, 0)); \ if (!vi) { \ piCout << "Warning! Using REGISTER_VARIANT_CAST("#classname_from", "#classname_to") before REGISTER_VARIANT("#classname_from"), ignore."; \ return; \ } \ vi->cast[cname] = __PIVariantFunctions__::castHelper; \ } \ }; \ static __##classname_from##_##classname_to##_PIVariantCastInitializer__< classname_from, classname_to > __##classname_from##_##classname_to##_pivariant_cast_initializer__(#classname_from, #classname_to); \ template<> template<> \ classname_to __PIVariantFunctions__::castVariant(const classname_from & v) #define REGISTER_VARIANT_CAST(classname_from, classname_to) \ REGISTER_VARIANT_CAST_H(classname_from, classname_to) \ REGISTER_VARIANT_CAST_CPP(classname_from, classname_to) #define REGISTER_VARIANT_CAST_SIMPLE(classname_from, classname_to) REGISTER_VARIANT_CAST(classname_from, classname_to) {return classname_to(v);} #define REGISTER_VARIANT_CAST_SIMPLE_H(classname_from, classname_to) REGISTER_VARIANT_CAST_H(classname_from, classname_to) #define REGISTER_VARIANT_CAST_SIMPLE_CPP(classname_from, classname_to) REGISTER_VARIANT_CAST_CPP(classname_from, classname_to) {return classname_to(v);} #else #define REGISTER_VARIANT_TYPEINFO(classname) #define REGISTER_VARIANT_H(classname) #define REGISTER_VARIANT_CPP(classname) #define INIT_VARIANT(classname) #define REGISTER_VARIANT(classname) #define REGISTER_NS_VARIANT_H(ns, classname) #define REGISTER_NS_VARIANT_CPP(ns, classname) #define INIT_NS_VARIANT(ns, classname) #define REGISTER_NS_VARIANT(ns, classname) #define REGISTER_VARIANT_CAST_H(classname_from, classname_to) #define REGISTER_VARIANT_CAST_CPP(classname_from, classname_to) #define REGISTER_VARIANT_CAST(classname_from, classname_to) #define REGISTER_VARIANT_CAST_SIMPLE(classname_from, classname_to) #define REGISTER_VARIANT_CAST_SIMPLE_H(classname_from, classname_to) #define REGISTER_VARIANT_CAST_SIMPLE_CPP(classname_from, classname_to) #endif //! \ingroup Core //! \~\brief //! \~english Variant type. //! \~russian Вариантный тип. class PIP_EXPORT PIVariant { friend PICout operator <<(PICout s, const PIVariant & v); BINARY_STREAM_FRIEND(PIVariant); public: //! \~english Type of %PIVariant content //! \~russian Тип содержимого %PIVariant enum Type { pivInvalid /** \~english Invalid type, default type of empty contructor \~russian Недействительный тип, также конструированный по умолчанию */ = 0 , pivBool /** bool */ , pivChar /** char */ , pivUChar /** uchar */ , pivShort /** short */ , pivUShort /** ushort */ , pivInt /** int */ , pivUInt /** uint */ , pivLLong /** llong */ , pivULLong /** ullong */ , pivFloat /** float */ , pivDouble /** double */ , pivLDouble /** ldouble */ , pivComplexd /** complexd */ , pivComplexld /** complexld */ , pivBitArray /** PIBitArray */ , pivByteArray /** PIByteArray */ , pivString /** PIString */ , pivStringList /** PIStringList */ , pivTime /** PITime */ , pivDate /** PIDate */ , pivDateTime /** PIDateTime */ , pivSystemTime /** PISystemTime */ , pivEnum /** PIVariantTypes::Enum */ , pivFile /** PIVariantTypes::File */ , pivDir /** PIVariantTypes::Dir */ , pivColor /** PIVariantTypes::Color */ , pivPoint /** PIPoint */ , pivRect /** PIRect */ , pivIODevice /** PIVariantTypes::IODevice */ , pivMathVector /** PIMathVector */ , pivMathMatrix /** PIMathMatrix */ , pivLine /** PILine */ , pivCustom /** \~english Custom \~russian Свой тип */ = 0xFF }; //! \~english Construct \a pivInvalid %PIVariant //! \~russian Создает \a pivInvalid %PIVariant PIVariant(); //! \~english Contructs a copy of %PIVariant. //! \~russian Создает копию %PIVariant. PIVariant(const PIVariant & v); //! \~english Move constructor. //! \~russian Перемещающий конструктор. PIVariant(PIVariant && v); //! \~english Constructs %PIVariant from string //! \~russian Создает %PIVariant из строки. PIVariant(const char * v) {initType(PIString(v));} //! \~english Constructs %PIVariant from boolean //! \~russian Создает %PIVariant из логического значения. PIVariant(const bool v) {initType(v);} //! \~english Constructs %PIVariant from char //! \~russian Создает %PIVariant из символа. PIVariant(const char v) {initType(v);} //! \~english Constructs %PIVariant from integer //! \~russian Создает %PIVariant из целого числа. PIVariant(const uchar v) {initType(v);} //! \~english Constructs %PIVariant from integer //! \~russian Создает %PIVariant из целого числа. PIVariant(const short v) {initType(v);} //! \~english Constructs %PIVariant from integer //! \~russian Создает %PIVariant из целого числа. PIVariant(const ushort v) {initType(v);} //! \~english Constructs %PIVariant from integer //! \~russian Создает %PIVariant из целого числа. PIVariant(const int & v) {initType(v);} //! \~english Constructs %PIVariant from integer //! \~russian Создает %PIVariant из целого числа. PIVariant(const uint & v) {initType(v);} //! \~english Constructs %PIVariant from integer //! \~russian Создает %PIVariant из целого числа. PIVariant(const llong & v) {initType(v);} //! \~english Constructs %PIVariant from integer //! \~russian Создает %PIVariant из целого числа. PIVariant(const ullong & v) {initType(v);} //! \~english Constructs %PIVariant from float //! \~russian Создает %PIVariant из вещественного числа. PIVariant(const float & v) {initType(v);} //! \~english Constructs %PIVariant from double //! \~russian Создает %PIVariant из вещественного числа. PIVariant(const double & v) {initType(v);} //! \~english Constructs %PIVariant from long double //! \~russian Создает %PIVariant из вещественного числа. PIVariant(const ldouble & v) {initType(v);} //! \~english Constructs %PIVariant from bit array //! \~russian Создает %PIVariant из массива битов. PIVariant(const PIBitArray & v) {initType(v);} //! \~english Constructs %PIVariant from byte array //! \~russian Создает %PIVariant из массива байтов. PIVariant(const PIByteArray & v) {initType(v);} //! \~english Constructs %PIVariant from string //! \~russian Создает %PIVariant из строки. PIVariant(const PIString & v) {initType(v);} //! \~english Constructs %PIVariant from strings list //! \~russian Создает %PIVariant из массива строк. PIVariant(const PIStringList & v) {initType(v);} //! \~english Constructs %PIVariant from time //! \~russian Создает %PIVariant из времени. PIVariant(const PITime & v) {initType(v);} //! \~english Constructs %PIVariant from date //! \~russian Создает %PIVariant из даты. PIVariant(const PIDate & v) {initType(v);} //! \~english Constructs %PIVariant from date and time //! \~russian Создает %PIVariant из даты и времени. PIVariant(const PIDateTime & v) {initType(v);} //! \~english Constructs %PIVariant from system time //! \~russian Создает %PIVariant из системного времени. PIVariant(const PISystemTime & v) {initType(v);} //! \~english Constructs %PIVariant from enum //! \~russian Создает %PIVariant из перечисления. PIVariant(const PIVariantTypes::Enum & v) {initType(v);} //! \~english Constructs %PIVariant from file //! \~russian Создает %PIVariant из файла. PIVariant(const PIVariantTypes::File & v) {initType(v);} //! \~english Constructs %PIVariant from dir //! \~russian Создает %PIVariant из директории. PIVariant(const PIVariantTypes::Dir & v) {initType(v);} //! \~english Constructs %PIVariant from color //! \~russian Создает %PIVariant из цвета. PIVariant(const PIVariantTypes::Color & v) {initType(v);} //! \~english Constructs %PIVariant from IODevice //! \~russian Создает %PIVariant из IODevice. PIVariant(const PIVariantTypes::IODevice & v) {initType(v);} //! \~english Constructs %PIVariant from point //! \~russian Создает %PIVariant из точки. PIVariant(const PIPointd & v) {initType(v);} //! \~english Constructs %PIVariant from rect //! \~russian Создает %PIVariant из прямоугольника. PIVariant(const PIRectd & v) {initType(v);} //! \~english Constructs %PIVariant from line //! \~russian Создает %PIVariant из линии. PIVariant(const PILined & v) {initType(v);} //! \~english Constructs %PIVariant from MathVector //! \~russian Создает %PIVariant из MathVector. PIVariant(const PIMathVectord & v) {initType(v);} //! \~english Constructs %PIVariant from MathMatrix //! \~russian Создает %PIVariant из MathMatrix. PIVariant(const PIMathMatrixd & v) {initType(v);} //! \~english Set variant content and type to string //! \~russian Устанавливает значение и тип из строки void setValue(const char * v) {setValue(PIString(v));} //! \~english Set variant content and type to boolean //! \~russian Устанавливает значение и тип из void setValue(const bool v) {initType(v);} //! \~english Set variant content and type to char //! \~russian Устанавливает значение и тип из символа void setValue(const char v) {initType(v);} //! \~english Set variant content and type to integer //! \~russian Устанавливает значение и тип из целого числа void setValue(const uchar v) {initType(v);} //! \~english Set variant content and type to integer //! \~russian Устанавливает значение и тип из целого числа void setValue(const short v) {initType(v);} //! \~english Set variant content and type to integer //! \~russian Устанавливает значение и тип из целого числа void setValue(const ushort v) {initType(v);} //! \~english Set variant content and type to integer //! \~russian Устанавливает значение и тип из целого числа void setValue(const int & v) {initType(v);} //! \~english Set variant content and type to integer //! \~russian Устанавливает значение и тип из целого числа void setValue(const uint & v) {initType(v);} //! \~english Set variant content and type to integer //! \~russian Устанавливает значение и тип из целого числа void setValue(const llong & v) {initType(v);} //! \~english Set variant content and type to integer //! \~russian Устанавливает значение и тип из целого числа void setValue(const ullong & v) {initType(v);} //! \~english Set variant content and type to float //! \~russian Устанавливает значение и тип из вещественного числа void setValue(const float & v) {initType(v);} //! \~english Set variant content and type to double //! \~russian Устанавливает значение и тип из вещественного числа void setValue(const double & v) {initType(v);} //! \~english Set variant content and type to long double //! \~russian Устанавливает значение и тип из вещественного числа void setValue(const ldouble & v) {initType(v);} //! \~english Set variant content and type to bit array //! \~russian Устанавливает значение и тип из массива битов void setValue(const PIBitArray & v) {initType(v);} //! \~english Set variant content and type to byte array //! \~russian Устанавливает значение и тип из массива байтов void setValue(const PIByteArray & v) {initType(v);} //! \~english Set variant content and type to string //! \~russian Устанавливает значение и тип из строки void setValue(const PIString & v) {initType(v);} //! \~english Set variant content and type to strings list //! \~russian Устанавливает значение и тип из массива строк void setValue(const PIStringList & v) {initType(v);} //! \~english Set variant content and type to time //! \~russian Устанавливает значение и тип из времени void setValue(const PITime & v) {initType(v);} //! \~english Set variant content and type to date //! \~russian Устанавливает значение и тип из даты void setValue(const PIDate & v) {initType(v);} //! //! \~english Set variant content and type to date and time //! \~russian Устанавливает значение и тип из даты и времени void setValue(const PIDateTime & v) {initType(v);} //! \~english Set variant content and type to system time //! \~russian Устанавливает значение и тип из системного времени void setValue(const PISystemTime & v) {initType(v);} //! \~english Set variant content and type to enum //! \~russian Устанавливает значение и тип из перечисления void setValue(const PIVariantTypes::Enum & v) {initType(v);} //! \~english Set variant content and type to file //! \~russian Устанавливает значение и тип из файла void setValue(const PIVariantTypes::File & v) {initType(v);} //! \~english Set variant content and type to dir //! \~russian Устанавливает значение и тип из директории void setValue(const PIVariantTypes::Dir & v) {initType(v);} //! \~english Set variant content and type to color //! \~russian Устанавливает значение и тип из цвета void setValue(const PIVariantTypes::Color & v) {initType(v);} //! \~english Set variant content and type to IODevice //! \~russian Устанавливает значение и тип из IODevice void setValue(const PIVariantTypes::IODevice & v) {initType(v);} //! \~english Set variant content and type to point //! \~russian Устанавливает значение и тип из точки void setValue(const PIPointd & v) {initType(v);} //! \~english Set variant content and type to rect //! \~russian Устанавливает значение и тип из прямоугольника void setValue(const PIRectd & v) {initType(v);} //! \~english Set variant content and type to line //! \~russian Устанавливает значение и тип из линии void setValue(const PILined & v) {initType(v);} //! \~english Set variant content and type to math vector //! \~russian Устанавливает значение и тип из вектора void setValue(const PIMathVectord & v) {initType(v);} //! \~english Set variant content and type to math matrix //! \~russian Устанавливает значение и тип из матрицы void setValue(const PIMathMatrixd & v) {initType(v);} //! \~english Set current value from string without change type //! \~russian Устанавливает текущее значение из строки без изменения типа void setValueFromString(const PIString & v); bool toBool() const; int toInt() const; llong toLLong() const; float toFloat() const; double toDouble() const; ldouble toLDouble() 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; PIVariantTypes::Enum toEnum() const; PIVariantTypes::File toFile() const; PIVariantTypes::Dir toDir() const; PIVariantTypes::Color toColor() const; PIVariantTypes::IODevice toIODevice() const; PIPointd toPoint() const; PIRectd toRect() const; PILined toLine() const; PIMathVectord toMathVector() const; PIMathMatrixd toMathMatrix() const; //! \~\brief //! \~english Returns variant content as custom type //! \~russian Возвращает содержимое в качестве своего типа //! \~\details //! \~english //! In case of known types this function equivalent \a to function. \n //! Otherwise returns content as type T only if this type was set earlier. //! \~russian //! Для стандартных типов эквиваленстно методу \a to. \n //! Для других возвращает тип T только если он был установлен ранее. template T value() const {return getAsValue(*this);} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const PIVariant & v); //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(PIVariant && v); //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const char * v) {setValue(PIString(v)); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const bool v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const char v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const uchar v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const short v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const ushort v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const int & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const uint & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const llong & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const ullong & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const float & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const double & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const ldouble & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const PIBitArray & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const PIByteArray & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const PIString & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const PIStringList & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const PITime & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const PIDate & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const PIDateTime & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const PISystemTime & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const PIVariantTypes::Enum & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const PIVariantTypes::File & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const PIVariantTypes::Dir & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const PIVariantTypes::Color & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const PIVariantTypes::IODevice & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const PIPointd & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const PIRectd & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const PILined & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const PIMathVectord & v) {setValue(v); return *this;} //! \~english Assign operator. //! \~russian Оператор присваивания. PIVariant & operator =(const PIMathMatrixd & v) {setValue(v); return *this;} //! \~english Compare operator. Check type and content. //! \~russian Оператор сравнения. Сравнивает тип и содержимое. bool operator ==(const PIVariant & v) const; //! \~english Compare operator. Check type and content. //! \~russian Оператор сравнения. Сравнивает тип и содержимое. bool operator !=(const PIVariant & v) const {return !(*this == v);} //! \~english Returns type of variant content. //! \~russian Возвращает тип значения. PIVariant::Type type() const {return _type;} //! \~english Returns type name of variant content. //! \~russian Возвращает имя типа значения. PIString typeName() const; //! \~english Returns if type is not \a pivInvalid. //! \~russian Возвращает не является ли тип \a pivInvalid. bool isValid() const {return _type != PIVariant::pivInvalid;} //! \~english Swaps with other %PIVariant. //! \~russian Меняет с другим %PIVariant. void swap(PIVariant & v); //! \~\brief //! \~english Returns new %PIVariant from custom type value. //! \~russian Возвращает новый %PIVariant из значения своего типа. //! \~\details //! \~english //! In case of known types this function equivalent \a PIVariant() constructors. \n //! Otherwise returns variant with content "v" and type \a pivCustom. //! \~russian //! Для стандартных типов эквиваленстно конструктору \a PIVariant(). \n //! Для других устанавливает содержимое из "v" и тип \a pivCustom. template static PIVariant fromValue(const T & v) { PIVariant ret; ret.initType(v); return ret; } static PIVariant fromValue(const PIByteArray & c, const PIString & type) { PIVariant ret; PIVariant::Type t = typeFromName(type); if (t == pivInvalid) { #ifdef CUSTOM_PIVARIANT ret._info = __PIVariantInfoStorage__::get()->map->value(type, 0); if (ret._info) { t = pivCustom; } else #endif { piCout << "Can`t initialize PIVariant from unregistered type \"" << type << "\"!"; return ret; } } ret._type = t; ret._content = c; return ret; } //! \~english Returns type from its name. //! \~russian Возвращает тип из его названия. static PIVariant::Type typeFromName(const PIString & tname); //! \~english Returns type name. //! \~russian Возвращает имя типа. static PIString typeName(PIVariant::Type type); private: void destroy() {_content.clear();} template inline static Type getType() {return pivCustom;} template inline void initType(const T & v) { _content.clear(); _content << v; _type = getType(); #ifdef CUSTOM_PIVARIANT if (_type == pivCustom) { _info = __PIVariantInfoStorage__::get()->map->value(__PIVariantFunctions__::typeNameHelper(), 0); if (!_info) piCout << "Can`t initialize PIVariant from unregistered type!"; } else _info = 0; #endif } template inline static T getAsValue(const PIVariant & v) { #ifdef CUSTOM_PIVARIANT if (v._content.isEmpty() || !v._info) return T(); PIString cn = __PIVariantFunctions__::typeNameHelper(); //piCout << "gav" << cn; PIByteArray ba; if (cn == v._info->typeName) { ba = v._content; } else { __PIVariantInfo__::castHelperFunc cf = v._info->cast.value(cn); //piCout << "gav cast" << cf; if (!cf) return T(); ba = cf(v._content); } T ret; ba >> ret; return ret; #else return T(); #endif } PIByteArray _content; PIVariant::Type _type; #ifdef CUSTOM_PIVARIANT __PIVariantInfo__ * _info; #endif }; template<> inline bool PIVariant::value() const {return toBool();} template<> inline char PIVariant::value() const {return (char)toInt();} template<> inline uchar PIVariant::value() const {return (uchar)toInt();} template<> inline short PIVariant::value() const {return (short)toInt();} template<> inline ushort PIVariant::value() const {return (ushort)toInt();} template<> inline int PIVariant::value() const {return toInt();} template<> inline uint PIVariant::value() const {return (uint)toInt();} template<> inline llong PIVariant::value() const {return toLLong();} template<> inline ullong PIVariant::value() const {return (ullong)toLLong();} template<> inline float PIVariant::value() const {return toFloat();} template<> inline double PIVariant::value() const {return toDouble();} template<> inline ldouble PIVariant::value() const {return toLDouble();} template<> inline void* PIVariant::value() const {return (void*)toLLong();} template<> inline const char* PIVariant::value() const {return toString().data();} template<> inline PITime PIVariant::value() const {return toTime();} template<> inline PIDate PIVariant::value() const {return toDate();} template<> inline PIDateTime PIVariant::value() const {return toDateTime();} template<> inline PIString PIVariant::value() const {return toString();} template<> inline PIStringList PIVariant::value() const {return toStringList();} template<> inline PIBitArray PIVariant::value() const {return toBitArray();} template<> inline PIByteArray PIVariant::value() const {return toByteArray();} template<> inline PIVariantTypes::Enum PIVariant::value() const {return toEnum();} template<> inline PIVariantTypes::File PIVariant::value() const {return toFile();} template<> inline PIVariantTypes::Dir PIVariant::value() const {return toDir();} template<> inline PIVariantTypes::Color PIVariant::value() const {return toColor();} template<> inline PIVariantTypes::IODevice PIVariant::value() const {return toIODevice();} template<> inline PIPointd PIVariant::value() const {return toPoint();} template<> inline PIRectd PIVariant::value() const {return toRect();} template<> inline PILined PIVariant::value() const {return toLine();} template<> inline PIVariant PIVariant::value() const {return *this;} 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 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 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);} template<> inline PIVariant PIVariant::fromValue(const PIVariantTypes::Enum & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIVariantTypes::File & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIVariantTypes::Dir & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIVariantTypes::Color & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIVariantTypes::IODevice & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIPointd & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIRectd & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PILined & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIMathVectord & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIMathMatrixd & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIVariant & v) {return PIVariant(v);} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivBool;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivChar;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivUChar;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivShort;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivUShort;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivInt;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivUInt;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivLLong;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivULLong;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivFloat;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivDouble;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivLDouble;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivBitArray;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivByteArray;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivString;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivStringList;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivTime;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivDate;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivDateTime;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivSystemTime;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivEnum;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivFile;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivDir;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivColor;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivIODevice;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivPoint;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivRect;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivLine;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivMathVector;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivMathMatrix;} REGISTER_VARIANT(bool) REGISTER_VARIANT(char) REGISTER_VARIANT(uchar) REGISTER_VARIANT(short) REGISTER_VARIANT(ushort) REGISTER_VARIANT(int) REGISTER_VARIANT(uint) REGISTER_VARIANT(llong) REGISTER_VARIANT(ullong) REGISTER_VARIANT(float) REGISTER_VARIANT(double) REGISTER_VARIANT(ldouble) REGISTER_VARIANT(PIBitArray) REGISTER_VARIANT(PIByteArray) REGISTER_VARIANT(PIString) REGISTER_VARIANT(PIStringList) REGISTER_VARIANT(PITime) REGISTER_VARIANT(PIDate) REGISTER_VARIANT(PIDateTime) REGISTER_VARIANT(PISystemTime) REGISTER_NS_VARIANT(PIVariantTypes, Enum) REGISTER_NS_VARIANT(PIVariantTypes, File) REGISTER_NS_VARIANT(PIVariantTypes, Dir) REGISTER_NS_VARIANT(PIVariantTypes, Color) REGISTER_NS_VARIANT(PIVariantTypes, IODevice) REGISTER_VARIANT(PIPointd) REGISTER_VARIANT(PIRectd) REGISTER_VARIANT(PILined) REGISTER_VARIANT(PIMathVectord) REGISTER_VARIANT(PIMathMatrixd) //! \relatesalso PIBinaryStream //! \~english Store operator. //! \~russian Оператор сохранения. BINARY_STREAM_WRITE(PIVariant) { s << v._content << v._type; if (v._type == PIVariant::pivCustom) { #ifdef CUSTOM_PIVARIANT if (v._info) { s << v._info->typeName; } else { s << PIStringAscii(""); } #else s << PIStringAscii(""); #endif } return s; } //! \relatesalso PIBinaryStream //! \~english Restore operator. //! \~russian Оператор извлечения. BINARY_STREAM_READ(PIVariant) { s >> v._content >> v._type; if (v._type == PIVariant::pivCustom) { PIString tn; s >> tn; #ifdef CUSTOM_PIVARIANT PIByteArray vc = v._content; v = PIVariant::fromValue(vc, tn); #endif } return s; } //! \relatesalso PICout //! \~english Output operator to \a PICout //! \~russian Оператор вывода в \a PICout inline PICout operator <<(PICout s, const PIVariant & v) { s.space(); s.saveAndSetControls(0); s << "PIVariant(" << v.typeName(); if (v.isValid()) s << ", " << v.toString(); s << ")"; s.restoreControls(); return s; } #endif // PIVARIANT_H