Files
pip/libs/main/core/pivariant.h
2022-08-15 19:35:49 +03:00

1002 lines
42 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*! \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 <http://www.gnu.org/licenses/>.
*/
#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<typename T>
class __PIVariantFunctions__ {
public:
static PIString typeNameHelper() {return PIStringAscii("");}
static bool isSimpleHelper() {return false;}
template<typename C> static PIByteArray castHelper(PIByteArray ba) {return PIByteArray();}
template<typename C> static C castVariant(const T & v) {return C();}
};
struct PIP_EXPORT __PIVariantInfo__ {
__PIVariantInfo__() {
simple = false;
}
typedef PIByteArray(*castHelperFunc)(PIByteArray);
PIMap<PIString, castHelperFunc> cast;
PIString typeName;
bool simple;
};
template<typename T>
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__<T> { \
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<PIString, __PIVariantInfo__ * >();}
static __PIVariantInfoStorage__ * get() {static __PIVariantInfoStorage__ * r = new __PIVariantInfoStorage__(); return r;}
static PIMap<PIString, __PIVariantInfo__ * > * 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 <typename T> \
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 <typename T> \
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__<classname_from>::castVariant<classname_to>(const classname_from & v);
#define REGISTER_VARIANT_CAST_CPP(classname_from, classname_to) \
template<> template<> inline \
PIByteArray __PIVariantFunctions__<classname_from>::castHelper<classname_to>(PIByteArray v) { \
classname_from f; v >> f; \
classname_to t = __PIVariantFunctions__<classname_from>::castVariant<classname_to>(f); \
PIByteArray ret; ret << t; \
return ret;} \
template <typename T, typename C> \
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__<classname_from>::castHelper<classname_to>; \
} \
}; \
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__<classname_from>::castVariant<classname_to>(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<double> */ ,
pivRect /** PIRect<double> */ ,
pivIODevice /** PIVariantTypes::IODevice */ ,
pivMathVector /** PIMathVector<double> */ ,
pivMathMatrix /** PIMathMatrix<double> */ ,
pivLine /** PILine<double> */ ,
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<Type> function. \n
//! Otherwise returns content as type T only if this type was set earlier.
//! \~russian
//! Для стандартных типов эквиваленстно методу \a to<Type>. \n
//! Для других возвращает тип T только если он был установлен ранее.
template<typename T>
T value() const {return getAsValue<T>(*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 <typename T>
static PIVariant fromValue(const T & v) {
PIVariant ret;
ret.initType<T>(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 <typename T> inline static Type getType() {return pivCustom;}
template <typename T> inline void initType(const T & v) {
_content.clear();
_content << v;
_type = getType<T>();
#ifdef CUSTOM_PIVARIANT
if (_type == pivCustom) {
_info = __PIVariantInfoStorage__::get()->map->value(__PIVariantFunctions__<T>::typeNameHelper(), 0);
if (!_info)
piCout << "Can`t initialize PIVariant from unregistered type!";
} else
_info = 0;
#endif
}
template<typename T> inline static T getAsValue(const PIVariant & v) {
#ifdef CUSTOM_PIVARIANT
if (v._content.isEmpty() || !v._info) return T();
PIString cn = __PIVariantFunctions__<T>::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<bool>() {return PIVariant::pivBool;}
template<> inline PIVariant::Type PIVariant::getType<char>() {return PIVariant::pivChar;}
template<> inline PIVariant::Type PIVariant::getType<uchar>() {return PIVariant::pivUChar;}
template<> inline PIVariant::Type PIVariant::getType<short>() {return PIVariant::pivShort;}
template<> inline PIVariant::Type PIVariant::getType<ushort>() {return PIVariant::pivUShort;}
template<> inline PIVariant::Type PIVariant::getType<int>() {return PIVariant::pivInt;}
template<> inline PIVariant::Type PIVariant::getType<uint>() {return PIVariant::pivUInt;}
template<> inline PIVariant::Type PIVariant::getType<llong>() {return PIVariant::pivLLong;}
template<> inline PIVariant::Type PIVariant::getType<ullong>() {return PIVariant::pivULLong;}
template<> inline PIVariant::Type PIVariant::getType<float>() {return PIVariant::pivFloat;}
template<> inline PIVariant::Type PIVariant::getType<double>() {return PIVariant::pivDouble;}
template<> inline PIVariant::Type PIVariant::getType<ldouble>() {return PIVariant::pivLDouble;}
template<> inline PIVariant::Type PIVariant::getType<PIBitArray>() {return PIVariant::pivBitArray;}
template<> inline PIVariant::Type PIVariant::getType<PIByteArray>() {return PIVariant::pivByteArray;}
template<> inline PIVariant::Type PIVariant::getType<PIString>() {return PIVariant::pivString;}
template<> inline PIVariant::Type PIVariant::getType<PIStringList>() {return PIVariant::pivStringList;}
template<> inline PIVariant::Type PIVariant::getType<PITime>() {return PIVariant::pivTime;}
template<> inline PIVariant::Type PIVariant::getType<PIDate>() {return PIVariant::pivDate;}
template<> inline PIVariant::Type PIVariant::getType<PIDateTime>() {return PIVariant::pivDateTime;}
template<> inline PIVariant::Type PIVariant::getType<PISystemTime>() {return PIVariant::pivSystemTime;}
template<> inline PIVariant::Type PIVariant::getType<PIVariantTypes::Enum>() {return PIVariant::pivEnum;}
template<> inline PIVariant::Type PIVariant::getType<PIVariantTypes::File>() {return PIVariant::pivFile;}
template<> inline PIVariant::Type PIVariant::getType<PIVariantTypes::Dir>() {return PIVariant::pivDir;}
template<> inline PIVariant::Type PIVariant::getType<PIVariantTypes::Color>() {return PIVariant::pivColor;}
template<> inline PIVariant::Type PIVariant::getType<PIVariantTypes::IODevice>() {return PIVariant::pivIODevice;}
template<> inline PIVariant::Type PIVariant::getType<PIPointd>() {return PIVariant::pivPoint;}
template<> inline PIVariant::Type PIVariant::getType<PIRectd>() {return PIVariant::pivRect;}
template<> inline PIVariant::Type PIVariant::getType<PILined>() {return PIVariant::pivLine;}
template<> inline PIVariant::Type PIVariant::getType<PIMathVectord>() {return PIVariant::pivMathVector;}
template<> inline PIVariant::Type PIVariant::getType<PIMathMatrixd>() {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