git-svn-id: svn://db.shs.com.ru/pip@310 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5

This commit is contained in:
2017-02-21 10:12:11 +00:00
parent c2e7c8b46b
commit 5c83617458
5 changed files with 327 additions and 5 deletions

View File

@@ -11,7 +11,7 @@ REGISTER_VARIANT(__S__)
REGISTER_VARIANT_CAST(__S__, PIString) {return v.text + PIString::fromNumber(v.i);}
REGISTER_VARIANT_CAST(__S__, int) {return v.i;}
*/
const char app_config[] =
/*const char app_config[] =
"include = cd_ip.conf\n\
port_rec = 2\n\
port_send = 1\n\
@@ -30,7 +30,7 @@ const char pult_config[] =
[]\n\
connectionmodel = AAAM2Xja7VXLTttAFD12QpsikKjUSixYlLbKEpIUtVIlVEfqhk2FWuiGRRolUYtoHgrmpYiv6IItf8AveMMH9E/YsG6Ph3sde5hGoQoblLGuPHfunTPjc49nADxDA110+LTYC7FrPCAPeAO+vZu+aX7c/8PGd45WCJC0OGcfT6FDnmfSTPtwhZFt3HjgDs/Qtu5jPbZHtI/x50XfIzMQbdwEolbg9INP4ku++myPaUtCHYRaT2j1ldIh3VP60/Qff8vSfXLu9BP6JX9K/0TVH6jqVe22P1X/fao/oddWu/paDs1vBf9Jv/EZ91clbyHqv7BL6sscDOd4v4WTqs6jzaHGJ8QJerxlpJSpdZ7IWFJvDW7I2JxZqIM62k6A57RZmMQGmlyrxdV+WGBnmR01mXPI267hBKwp4FeBeo9VPtssxyb7rzHg1B7T9nCMU45U8BZlWuVWtIcD/CRGOqtsbW09851tXsHN0UTlLIAdASjSXnLyLn+H7L2+xbGYvC63Ezqg543egkLmn8qnRF6USbM4Qp9godkhzI777Ne5bCIt/5UtGz2o/yGby0nKpjqmbOa1ynkjmyzIrzvIZUeBPjvlUmbh32EFJbGyJZhR8YcvlS+3TpjhqeWSyvUkpbI9plSWtcKLcsK05beOJVEnhaEFfHEH+RwpeMcpn1JKGqWMNOL+G6wZyahlpdVOtufKfbDS+guLke9O\n\
";
*/
int main(int argc, char *argv[]) {
/*__S__ s, s1;
s.text = "123";
@@ -50,7 +50,8 @@ int main(int argc, char *argv[]) {
piCout << s1;
s1.subtract(s0);
piCout << s1;*/
PIConnection c;
/*PIConnection c;
PIString s(app_config);
c.configureFromString(&s);
c.start();
@@ -60,7 +61,15 @@ int main(int argc, char *argv[]) {
c.removeAllDevices();
c.configureFromString(&s);
c.start();
piMSleep(3000);
piMSleep(3000);*/
PIStringList sl;
sl << "one" << "two" << "three";
PIVariantTypes::Enum e;
e << sl;
e.selectValue(1);
PIVariant v = e;
piCout << v.value<PIVariantTypes::Enum>();
return 0;
}

View File

@@ -110,6 +110,9 @@ PIVariant::Type PIVariant::typeFromName(const PIString & tname) {
if (s == "pidate" || s == "date") return PIVariant::pivDate;
if (s == "pidatetime" || s == "datetime") return PIVariant::pivDateTime;
if (s == "pisystemtime" || s == "systemtime") return PIVariant::pivSystemTime;
if (s == "enum") return PIVariant::pivEnum;
if (s == "file" || s == "path") return PIVariant::pivFile;
if (s == "dir" || s == "directory") return PIVariant::pivDir;
return PIVariant::pivInvalid;
}
@@ -147,6 +150,9 @@ PIString PIVariant::typeName(PIVariant::Type type) {
case PIVariant::pivDate: return "Date";
case PIVariant::pivDateTime: return "DateTime";
case PIVariant::pivSystemTime: return "SystemTime";
case PIVariant::pivEnum: return "Enum";
case PIVariant::pivFile: return "File";
case PIVariant::pivDir: return "Dir";
case PIVariant::pivCustom: return "Custom";
default: break;
}
@@ -212,6 +218,7 @@ int PIVariant::toInt() const {
case PIVariant::pivComplexld: {complexld r; ba >> r; return r.real();}
case PIVariant::pivString: {PIString r; ba >> r; return r.toInt();}
case PIVariant::pivStringList: {PIStringList r; ba >> r; if (r.isEmpty()) return 0; return r.front().toInt();}
case PIVariant::pivEnum: {PIVariantTypes::Enum r; ba >> r; return r.selectedValue();}
case PIVariant::pivCustom: return getAsValue<int>(*this);
default: break;
}
@@ -244,6 +251,7 @@ llong PIVariant::toLLong() const {
case PIVariant::pivComplexld: {complexld r; ba >> r; return r.real();}
case PIVariant::pivString: {PIString r; ba >> r; return r.toLLong();}
case PIVariant::pivStringList: {PIStringList r; ba >> r; if (r.isEmpty()) return 0L; return r.front().toLLong();}
case PIVariant::pivEnum: {PIVariantTypes::Enum r; ba >> r; return llong(r.selectedValue());}
case PIVariant::pivCustom: return getAsValue<llong>(*this);
default: break;
}
@@ -276,6 +284,7 @@ float PIVariant::toFloat() const {
case PIVariant::pivComplexld: {complexld r; ba >> r; return r.real();}
case PIVariant::pivString: {PIString r; ba >> r; return r.toFloat();}
case PIVariant::pivStringList: {PIStringList r; ba >> r; if (r.isEmpty()) return 0.f; return r.front().toFloat();}
case PIVariant::pivEnum: {PIVariantTypes::Enum r; ba >> r; return float(r.selectedValue());}
case PIVariant::pivCustom: return getAsValue<float>(*this);
default: break;
}
@@ -308,6 +317,7 @@ double PIVariant::toDouble() const {
case PIVariant::pivComplexld: {complexld r; ba >> r; return r.real();}
case PIVariant::pivString: {PIString r; ba >> r; return r.toDouble();}
case PIVariant::pivStringList: {PIStringList r; ba >> r; if (r.isEmpty()) return 0.; return r.front().toDouble();}
case PIVariant::pivEnum: {PIVariantTypes::Enum r; ba >> r; return double(r.selectedValue());}
case PIVariant::pivCustom: return getAsValue<double>(*this);
default: break;
}
@@ -340,6 +350,7 @@ ldouble PIVariant::toLDouble() const {
case PIVariant::pivComplexld: {complexld r; ba >> r; return r.real();}
case PIVariant::pivString: {PIString r; ba >> r; return r.toLDouble();}
case PIVariant::pivStringList: {PIStringList r; ba >> r; if (r.isEmpty()) return 0.; return r.front().toLDouble();}
case PIVariant::pivEnum: {PIVariantTypes::Enum r; ba >> r; return ldouble(r.selectedValue());}
case PIVariant::pivCustom: return getAsValue<float>(*this);
default: break;
}
@@ -372,6 +383,7 @@ complexd PIVariant::toComplexd() const {
case PIVariant::pivComplexld: {complexld r; ba >> r; return r.real();}
case PIVariant::pivString: {PIString r; ba >> r; return r.toDouble();}
case PIVariant::pivStringList: {PIStringList r; ba >> r; if (r.isEmpty()) return complexd_0; return r.front().toDouble();}
case PIVariant::pivEnum: {PIVariantTypes::Enum r; ba >> r; return complexd(r.selectedValue());}
case PIVariant::pivCustom: return getAsValue<complexd>(*this);
default: break;
}
@@ -404,6 +416,7 @@ complexld PIVariant::toComplexld() const {
case PIVariant::pivComplexld: {complexld r; ba >> r; return r.real();}
case PIVariant::pivString: {PIString r; ba >> r; return r.toLDouble();}
case PIVariant::pivStringList: {PIStringList r; ba >> r; if (r.isEmpty()) return complexld_0; return r.front().toLDouble();}
case PIVariant::pivEnum: {PIVariantTypes::Enum r; ba >> r; return complexld(r.selectedValue());}
case PIVariant::pivCustom: return getAsValue<complexld>(*this);
default: break;
}
@@ -492,6 +505,9 @@ PIString PIVariant::toString() const {
case PIVariant::pivComplexld: {complexld r; ba >> r; return PIString::fromNumber(r.real());}
case PIVariant::pivString: {PIString r; ba >> r; return r;}
case PIVariant::pivStringList: {PIStringList r; ba >> r; if (r.isEmpty()) return PIString(); return r.front();}
case PIVariant::pivEnum: {PIVariantTypes::Enum r; ba >> r; return r.selectedName();}
case PIVariant::pivFile: {PIVariantTypes::File r; ba >> r; return r.file;}
case PIVariant::pivDir: {PIVariantTypes::Dir r; ba >> r; return r.dir;}
case PIVariant::pivCustom: return getAsValue<PIString>(*this);
default: break;
}
@@ -505,6 +521,7 @@ PIString PIVariant::toString() const {
PIStringList PIVariant::toStringList() const {
PIByteArray ba(_content);
if (_type == PIVariant::pivStringList) {PIStringList r; ba >> r; return r;}
if (_type == PIVariant::pivEnum) {PIVariantTypes::Enum r; ba >> r; return r.names();}
if (_type == PIVariant::pivCustom) {return getAsValue<PIStringList>(*this);}
return PIStringList(toString());
}
@@ -530,3 +547,44 @@ PIByteArray PIVariant::toByteArray() const {
if (_type == PIVariant::pivCustom) {return getAsValue<PIByteArray>(*this);}
return PIByteArray();
}
/** \brief Returns variant content as enum
* \details In case of Enum type returns enum value. \n
* In case of String returns Enum with one member. \n
* In case of StringList returns Enum with corresponding members. \n
* In case of other types returns empty Enum. */
PIVariantTypes::Enum PIVariant::toEnum() const {
PIByteArray ba(_content);
if (_type == PIVariant::pivEnum) {PIVariantTypes::Enum r; ba >> r; return r;}
if (_type == PIVariant::pivString) {PIString v; ba >> v; PIVariantTypes::Enum r; r << v; return r;}
if (_type == PIVariant::pivStringList) {PIStringList v; ba >> v; PIVariantTypes::Enum r; r << v; return r;}
if (_type == PIVariant::pivCustom) {return getAsValue<PIVariantTypes::Enum>(*this);}
return PIVariantTypes::Enum();
}
/** \brief Returns variant content as file
* \details In case of File type returns file value. \n
* In case of String returns File with string value path. \n
* In case of other types returns empty Enum. */
PIVariantTypes::File PIVariant::toFile() const {
PIByteArray ba(_content);
if (_type == PIVariant::pivFile) {PIVariantTypes::File r; ba >> r; return r;}
if (_type == PIVariant::pivString) {PIString v; ba >> v; PIVariantTypes::File r; r.file = v; return r;}
if (_type == PIVariant::pivCustom) {return getAsValue<PIVariantTypes::File>(*this);}
return PIVariantTypes::File();
}
/** \brief Returns variant content as dir
* \details In case of Dir type returns dir value. \n
* In case of Dir returns Dir with string value path. \n
* In case of other types returns empty Enum. */
PIVariantTypes::Dir PIVariant::toDir() const {
PIByteArray ba(_content);
if (_type == PIVariant::pivDir) {PIVariantTypes::Dir r; ba >> r; return r;}
if (_type == PIVariant::pivString) {PIString v; ba >> v; PIVariantTypes::Dir r; r.dir = v; return r;}
if (_type == PIVariant::pivCustom) {return getAsValue<PIVariantTypes::Dir>(*this);}
return PIVariantTypes::Dir();
}

View File

@@ -25,7 +25,7 @@
#ifndef PIVARIANT_H
#define PIVARIANT_H
#include "pistring.h"
#include "pivarianttypes.h"
#include "pibitarray.h"
#include "pitime.h"
#include "pimathbase.h"
@@ -67,6 +67,9 @@ public:
#define REGISTER_VARIANT_H(classname) \
template<> inline PIString __PIVariantFunctions__< classname >::typeNameHelper() {static PIString tn = PIStringAscii(#classname); return tn;}
#define REGISTER_NS_VARIANT_H(ns, classname) \
template<> inline PIString __PIVariantFunctions__< ns::classname >::typeNameHelper() {static PIString tn = PIStringAscii(#ns"::"#classname); return tn;}
#define REGISTER_VARIANT_CPP(classname) \
template <typename T> \
class __##classname##_PIVariantInitializer__ { \
@@ -80,14 +83,35 @@ public: \
} \
};
#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 \
@@ -131,6 +155,10 @@ classname_to __PIVariantFunctions__<classname_from>::castVariant<classname_to>(c
#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)
@@ -171,6 +199,9 @@ public:
pivDate /** PIDate */ ,
pivDateTime /** PIDateTime */ ,
pivSystemTime /** PISystemTime */ ,
pivEnum /** PIVariantTypes::Enum */ ,
pivFile /** PIVariantTypes::File */ ,
pivDir /** PIVariantTypes::Dir */ ,
pivCustom /** Custom */ = 0xFF
};
@@ -248,6 +279,15 @@ public:
//! Constructs variant from system time
PIVariant(const PISystemTime & v) {initType(v);}
//! Constructs variant from enum
PIVariant(const PIVariantTypes::Enum & v) {initType(v);}
//! Constructs variant from file
PIVariant(const PIVariantTypes::File & v) {initType(v);}
//! Constructs variant from dir
PIVariant(const PIVariantTypes::Dir & v) {initType(v);}
//! Set variant content and type to string
void setValue(const char * v) {setValue(PIString(v));}
@@ -318,6 +358,15 @@ public:
//! Set variant content and type to system time
void setValue(const PISystemTime & v) {initType(v);}
//! Set variant content and type to enum
void setValue(const PIVariantTypes::Enum & v) {initType(v);}
//! Set variant content and type to file
void setValue(const PIVariantTypes::File & v) {initType(v);}
//! Set variant content and type to dir
void setValue(const PIVariantTypes::Dir & v) {initType(v);}
bool toBool() const;
int toInt() const;
@@ -335,6 +384,9 @@ public:
PIStringList toStringList() const;
PIBitArray toBitArray() const;
PIByteArray toByteArray() const;
PIVariantTypes::Enum toEnum() const;
PIVariantTypes::File toFile() const;
PIVariantTypes::Dir toDir() const;
/** \brief Returns variant content as custom type
@@ -418,6 +470,12 @@ public:
PIVariant & operator =(const PIDateTime & v) {setValue(v); return *this;}
//! Assign operator
PIVariant & operator =(const PISystemTime & v) {setValue(v); return *this;}
//! Assign operator
PIVariant & operator =(const PIVariantTypes::Enum & v) {setValue(v); return *this;}
//! Assign operator
PIVariant & operator =(const PIVariantTypes::File & v) {setValue(v); return *this;}
//! Assign operator
PIVariant & operator =(const PIVariantTypes::Dir & v) {setValue(v); return *this;}
//! Compare operator
@@ -542,6 +600,9 @@ 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 PIVariant PIVariant::fromValue(const char * v) {return PIVariant(PIString(v));}
template<> inline PIVariant PIVariant::fromValue(const bool & v) {return PIVariant(v);}
@@ -566,6 +627,9 @@ template<> inline PIVariant PIVariant::fromValue(const PITime & v) {return PIVar
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::Type PIVariant::getType<bool>() {return PIVariant::pivBool;}
template<> inline PIVariant::Type PIVariant::getType<char>() {return PIVariant::pivChar;}
@@ -589,6 +653,9 @@ template<> inline PIVariant::Type PIVariant::getType<PITime>() {return PIVariant
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;}
REGISTER_VARIANT(bool)
REGISTER_VARIANT(char)
@@ -612,6 +679,9 @@ 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)
inline PIByteArray & operator <<(PIByteArray & s, const PIVariant & v) {
s << v._content << int(v._type);

View File

@@ -0,0 +1,93 @@
/*
PIP - Platform Independent Primitives
Variant types
Copyright (C) 2017 Ivan Pelipenko peri4ko@yandex.ru
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 <http://www.gnu.org/licenses/>.
*/
#include "pivarianttypes.h"
int PIVariantTypes::Enum::selectedValue() const {
piForeachC (Enumerator & e, enum_list)
if (e.name == selected)
return e.value;
return 0;
}
bool PIVariantTypes::Enum::selectValue(int v) {
piForeachC (Enumerator & e, enum_list)
if (e.value == v) {
selected = e.name;
return true;
}
return false;
}
bool PIVariantTypes::Enum::selectName(const PIString & n) {
piForeachC (Enumerator & e, enum_list)
if (e.name == n) {
selected = e.name;
return true;
}
return false;
}
int PIVariantTypes::Enum::value(const PIString & n) const {
piForeachC (Enumerator & e, enum_list)
if (e.name == n)
return e.value;
return 0;
}
PIString PIVariantTypes::Enum::name(int v) const {
piForeachC (Enumerator & e, enum_list)
if (e.value == v)
return e.name;
return PIString();
}
PIVector<int> PIVariantTypes::Enum::values() const {
PIVector<int> ret;
piForeachC (Enumerator & e, enum_list)
ret << e.value;
return ret;
}
PIStringList PIVariantTypes::Enum::names() const {
PIStringList ret;
piForeachC (Enumerator & e, enum_list)
ret << e.name;
return ret;
}
PIVariantTypes::Enum & PIVariantTypes::Enum::operator <<(const PIString & v) {
enum_list << Enumerator(enum_list.size(), v);
return *this;
}
PIVariantTypes::Enum & PIVariantTypes::Enum::operator <<(const PIStringList & v) {
piForeachC (PIString & s, v)
(*this) << s;
return *this;
}

92
src/core/pivarianttypes.h Normal file
View File

@@ -0,0 +1,92 @@
/*! \file pivarianttypes.h
* \brief Variant type
*
* This file declares PIVariant
*/
/*
PIP - Platform Independent Primitives
Variant types
Copyright (C) 2017 Ivan Pelipenko peri4ko@yandex.ru
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 <http://www.gnu.org/licenses/>.
*/
#ifndef PIVARIANTYPES_H
#define PIVARIANTYPES_H
#include "pistring.h"
#include "pibytearray.h"
namespace PIVariantTypes {
struct Enumerator {
Enumerator(int v = 0, const PIString & n = PIString()): value(v), name(n) {}
int value;
PIString name;
};
struct Enum {
Enum(const PIString & n = PIString()): enum_name(n) {}
PIString toString() const {return selected;} // obsolete
int selectedValue() const;
PIString selectedName() const {return selected;}
bool selectValue(int v);
bool selectName(const PIString & n);
int value(const PIString & n) const;
PIString name(int v) const;
PIVector<int> values() const;
PIStringList names() const;
PIString enum_name;
PIString selected;
PIVector<Enumerator> enum_list;
Enum & operator <<(const PIString & v);
Enum & operator <<(const PIStringList & v);
};
struct File {
File(const PIString & p = PIString(), const PIString & f = PIString(), bool abs = false): file(p), filter(f), is_abs(abs) {}
PIString toString() const {return file;}
PIString file;
PIString filter;
bool is_abs;
};
struct Dir {
Dir(const PIString & d = PIString(), bool abs = false): dir(d), is_abs(abs) {}
PIString toString() const {return dir;}
PIString dir;
bool is_abs;
};
}
inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::Enumerator & v) {s << v.value << v.name; return s;}
inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::Enumerator & v) {s >> v.value >> v.name; return s;}
inline PICout operator <<(PICout s, const PIVariantTypes::Enumerator & v) {s << v.name << "(" << v.value << ")"; return s;}
inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::Enum & v) {s << v.enum_name << v.selected << v.enum_list; return s;}
inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::Enum & v) {s >> v.enum_name >> v.selected >> v.enum_list; return s;}
inline PICout operator <<(PICout s, const PIVariantTypes::Enum & v) {s << "Enum(" << v.selectedValue() << "=" << v.selectedName() << ")"; return s;}
inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::File & v) {s << v.file << v.filter << v.is_abs; return s;}
inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::File & v) {s >> v.file >> v.filter >> v.is_abs; return s;}
inline PICout operator <<(PICout s, const PIVariantTypes::File & v) {s << "File(\"" << v.file << "\")"; return s;}
inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::Dir & v) {s << v.dir << v.is_abs; return s;}
inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::Dir & v) {s >> v.dir >> v.is_abs; return s;}
inline PICout operator <<(PICout s, const PIVariantTypes::Dir & v) {s << "Dir(\"" << v.dir << "\")"; return s;}
#endif // PIVARIANTYPES_H