diff --git a/doc/doxygen_sqlite3.db b/doc/doxygen_sqlite3.db
new file mode 100644
index 00000000..838dc510
Binary files /dev/null and b/doc/doxygen_sqlite3.db differ
diff --git a/doc/events_handlers.odp b/doc/events_handlers.odp
new file mode 100644
index 00000000..09be151b
Binary files /dev/null and b/doc/events_handlers.odp differ
diff --git a/doc/packet_detection.odp b/doc/packet_detection.odp
new file mode 100644
index 00000000..a80ffb1f
Binary files /dev/null and b/doc/packet_detection.odp differ
diff --git a/doc/piconnection.odg b/doc/piconnection.odg
new file mode 100644
index 00000000..0bcdb024
Binary files /dev/null and b/doc/piconnection.odg differ
diff --git a/doc/piconnection_conf.odg b/doc/piconnection_conf.odg
new file mode 100644
index 00000000..8428ed7c
Binary files /dev/null and b/doc/piconnection_conf.odg differ
diff --git a/doc/piconnection_filters.odg b/doc/piconnection_filters.odg
new file mode 100644
index 00000000..57a5df56
Binary files /dev/null and b/doc/piconnection_filters.odg differ
diff --git a/doc/piconnection_senders.odg b/doc/piconnection_senders.odg
new file mode 100644
index 00000000..5a1fee1b
Binary files /dev/null and b/doc/piconnection_senders.odg differ
diff --git a/doc/piconsole_layout.odp b/doc/piconsole_layout.odp
new file mode 100644
index 00000000..e94ce3e0
Binary files /dev/null and b/doc/piconsole_layout.odp differ
diff --git a/src/_unsused/pigeometry.h b/src/_unsused/pigeometry.h
new file mode 100755
index 00000000..dd8c25f6
--- /dev/null
+++ b/src/_unsused/pigeometry.h
@@ -0,0 +1,137 @@
+/*
+ PIP - Platform Independent Primitives
+ Geometry
+ Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifndef PIGEOMETRY_H
+#define PIGEOMETRY_H
+
+#include "pimath.h"
+
+template
+class PIP_EXPORT PIPoint {
+public:
+ Type x;
+ Type y;
+
+ PIPoint() {x = y = 0;};
+ PIPoint(Type x_, Type y_) {set(x_, y_);}
+
+ PIPoint & set(Type x_, Type y_) {x = x_; y = y_; return *this;}
+ PIPoint & move(Type x_, Type y_) {x += x_; y += y_; return *this;}
+ PIPoint & move(const PIPoint & p) {x += p.x; y += p.y; return *this;}
+ double angleRad() const {return atan2(y, x);}
+ int angleDeg() const {return round(atan2(y, x) * 180. / M_PI);}
+ PIPoint toPolar(bool isDeg = false) const {return PIPoint(sqrt(x*x + y*y), isDeg ? angleDeg() : angleRad());}
+ static PIPoint fromPolar(const PIPoint & p) {return PIPoint(p.y * cos(p.x), p.y * sin(p.x));}
+
+ PIPoint operator +(const PIPoint & p) {return PIPoint(x + p.x, y + p.y);}
+ PIPoint operator +(const Type & p) {return PIPoint(x + p, y + p);}
+ PIPoint operator -(const PIPoint & p) {return PIPoint(x - p.x, y - p.y);}
+ PIPoint operator -(const Type & p) {return PIPoint(x - p, y - p);}
+ PIPoint operator -() {return PIPoint(-x, -y);}
+ PIPoint operator *(const Type & d) {return PIPoint(x * d, y * d);}
+ PIPoint operator /(const Type & d) {return PIPoint(x / d, y / d);}
+ bool operator ==(const PIPoint & p) const {return (x == p.x && y == p.y);}
+ bool operator !=(const PIPoint & p) const {return (x != p.x || y != p.y);}
+
+};
+
+template
+std::ostream & operator <<(std::ostream & s, const PIPoint & v) {s << '{' << v.x << ", " << v.y << '}'; return s;}
+
+template
+class PIP_EXPORT PIRect {
+public:
+ Type x0;
+ Type y0;
+ Type x1;
+ Type y1;
+
+ PIRect() {x0 = y0 = x1 = y1 = 0;};
+ PIRect(Type x, Type y, Type w, Type h) {set(x, y, w, h);}
+ PIRect(const PIPoint & tl, const PIPoint & br) {set(tl.x, tl.y, br.x, br.y);}
+ PIRect(const PIPoint & p0, const PIPoint & p1, const PIPoint & p2) {set(piMin(p0.x, p1.x, p2.x), piMin(p0.y, p1.y, p2.y),
+ piMax(p0.x, p1.x, p2.x), piMax(p0.y, p1.y, p2.y));}
+
+ PIRect & set(Type x, Type y, Type w, Type h) {x0 = x; y0 = y; x1 = x + w; y1 = y + h; return *this;}
+ bool pointIn(Type x, Type y) const {return (x <= x1 && x >= x0 && y <= y1 && y >= y0);}
+ bool pointIn(const PIPoint & p) const {return pointIn(p.x, p.y);}
+ bool isEmpty() const {return (x1 - x0 == 0 && y1 - y0 == 0);}
+ PIRect & translate(Type x, Type y) {x0 += x; x1 += x; y0 += y; y1 += y; return *this;}
+ PIRect & translate(const PIPoint & p) {x0 += p.x; x1 += p.x; y0 += p.y; y1 += p.y; return *this;}
+ PIRect translated(Type x, Type y) {PIRect r(*this); r.translate(x, y); return r;}
+ PIRect translated(const PIPoint & p) {PIRect r(*this); r.translate(p); return r;}
+ PIRect & scale(Type x, Type y) {setWidth(width() * x); setHeight(height() * y); return *this;}
+ PIRect & scale(const PIPoint & p) {setWidth(width() * p.x); setHeight(height() * p.y); return *this;}
+ PIRect scaled(Type x, Type y) {PIRect r(*this); r.scale(x, y); return r;}
+ PIRect scaled(const PIPoint & p) {PIRect r(*this); r.scale(p); return r;}
+ PIRect & normalize() {if (x0 > x1) piSwap(x0, x1); if (y0 > y1) piSwap(y0, y1); return *this;}
+ PIRect normalized() {PIRect r(*this); r.normalize(); return r;}
+ PIRect & unite(const PIRect & r) {x0 = piMin(x0, r.x0); y0 = piMin(y0, r.y0); x1 = piMax(x1, r.x1); y1 = piMax(y1, r.y1); return *this;}
+ PIRect united(const PIRect & rect) {PIRect r(*this); r.unite(rect); return r;}
+ PIRect & intersect(const PIRect & r) {x0 = piMax(x0, r.x0); y0 = piMax(y0, r.y0); x1 = piMin(x1, r.x1); y1 = piMin(y1, r.y1); if (x0 > x1 || y0 > y1) x0 = x1 = y0 = y1 = Type(0); return *this;}
+ PIRect intersected(const PIRect & rect) {PIRect r(*this); r.intersect(rect); return r;}
+ Type top() const {return y0;}
+ Type left() const {return x0;}
+ Type right() const {return x1;}
+ Type bottom() const {return y1;}
+ Type width() const {return x1 - x0;}
+ Type height() const {return y1 - y0;}
+ PIPoint topLeft() {return PIPoint(x0, y0);}
+ PIPoint topRigth() {return PIPoint(x1, y0);}
+ PIPoint bottomLeft() {return PIPoint(x0, y1);}
+ PIPoint bottomRight() {return PIPoint(x1, y1);}
+ void setTop(Type v) {y0 = v;}
+ void setLeft(Type v) {x0 = v;}
+ void setRigth(Type v) {x1 = v;}
+ void setBottom(Type v) {y1 = v;}
+ void setWidth(Type v) {x1 = x0 + v;}
+ void setHeight(Type v) {y1 = y0 + v;}
+
+ PIRect operator -() {return PIRect(-x0, -y0, -width(), -height());}
+ void operator +=(Type x) {translate(x, x);}
+ void operator +=(const PIPoint & p) {translate(p);}
+ void operator -=(Type x) {translate(-x, -x);}
+ void operator -=(const PIPoint & p) {translate(-p);}
+ void operator *=(Type p) {x0 *= p; x1 *= p; y0 *= p; y1 *= p;}
+ void operator /=(Type p) {x0 /= p; x1 /= p; y0 /= p; y1 /= p;}
+ void operator |=(const PIRect & r) {unite(r);}
+ void operator &=(const PIRect & r) {intersect(r);}
+ PIRect operator +(const PIPoint & p) {return PIRect(*this).translated(p);}
+ PIRect operator -(const PIPoint & p) {return PIRect(*this).translated(-p);}
+ PIRect operator |(const PIRect & r) {return PIRect(*this).united(r);}
+ PIRect operator &(const PIRect & r) {return PIRect(*this).intersected(r);}
+ bool operator ==(const PIRect & r) const {return (x0 == r.x0 && y0 == r.y0 && x1 == r.x1 && y1 == r.y10);}
+ bool operator !=(const PIRect & r) const {return (x0 != r.x0 || y0 != r.y0 || x1 != r.x1 || y1 != r.y10);}
+
+};
+
+template
+std::ostream & operator <<(std::ostream & s, const PIRect & v) {s << '{' << v.x0 << ", " << v.y0 << "; " << v.x1 - v.x0 << ", " << v.y1 - v.y0 << '}'; return s;}
+
+typedef PIPoint PIPointi;
+typedef PIPoint PIPointu;
+typedef PIPoint PIPointf;
+typedef PIPoint PIPointd;
+
+typedef PIRect PIRecti;
+typedef PIRect PIRectu;
+typedef PIRect PIRectf;
+typedef PIRect PIRectd;
+
+#endif // PIGEOMETRY_H
diff --git a/src/_unsused/pivariable.cpp b/src/_unsused/pivariable.cpp
new file mode 100755
index 00000000..f39d806a
--- /dev/null
+++ b/src/_unsused/pivariable.cpp
@@ -0,0 +1,249 @@
+/*
+ PIP - Platform Independent Primitives
+ Variable, Struct (simple serialization)
+ Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include "pivariable.h"
+
+
+bool PIVariant::operator ==(const PIVariant & v) const {
+ if (type != v.type) return false;
+ switch (type) {
+ case PIVariant::Bool: return vBool == v.vBool;
+ case PIVariant::Char: return vChar == v.vChar;
+ case PIVariant::Short: return vShort == v.vShort;
+ case PIVariant::Int: return vInt == v.vInt;
+ case PIVariant::Long: return vLong == v.vLong;
+ case PIVariant::LLong: return vLLong == v.vLLong;
+ case PIVariant::UChar: return vUChar == v.vUChar;
+ case PIVariant::UShort: return vUShort == v.vUShort;
+ case PIVariant::UInt: return vUInt == v.vUInt;
+ case PIVariant::ULong: return vULong == v.vULong;
+ case PIVariant::ULLong: return vULLong == v.vULLong;
+ case PIVariant::Float: return vFloat == v.vFloat;
+ case PIVariant::Double: return vDouble == v.vDouble;
+ case PIVariant::LDouble: return vLDouble == v.vLDouble;
+ case PIVariant::String: return vString == v.vString;
+ case PIVariant::StringList: return vStringList == v.vStringList;
+ };
+ return false;
+}
+
+
+void PIVariant::setValueOnly(const PIString & s) {
+ switch (type) {
+ case PIVariant::Bool: vBool = s.toBool(); break;
+ case PIVariant::Char: vChar = s.toChar(); break;
+ case PIVariant::Short: vShort = s.toShort(); break;
+ case PIVariant::Int: vInt = s.toInt(); break;
+ case PIVariant::Long: vLong = s.toLong(); break;
+ case PIVariant::LLong: vLLong = s.toLLong(); break;
+ case PIVariant::UChar: vUChar = s.toChar(); break;
+ case PIVariant::UShort: vUShort = s.toShort(); break;
+ case PIVariant::UInt: vUInt = s.toInt(); break;
+ case PIVariant::ULong: vULong = s.toLong(); break;
+ case PIVariant::ULLong: vULLong = s.toLLong(); break;
+ case PIVariant::Float: vFloat = s.toFloat(); break;
+ case PIVariant::Double: vDouble = s.toDouble(); break;
+ case PIVariant::LDouble: vLDouble = s.toLDouble(); break;
+ case PIVariant::String: vString = s; break;
+ case PIVariant::StringList: vStringList = s.split("%|%"); break;
+ };
+}
+
+
+PIString PIVariant::stringValue() const {
+ switch (type) {
+ case PIVariant::Bool: return (vBool ? "true" : "false");
+ case PIVariant::Char: return PIString::fromNumber(vChar);
+ case PIVariant::Short: return PIString::fromNumber(vShort);
+ case PIVariant::Int: return PIString::fromNumber(vInt);
+ case PIVariant::Long: return PIString::fromNumber(vLong);
+ case PIVariant::LLong: return PIString::fromNumber(static_cast(vLLong));
+ case PIVariant::UChar: return PIString::fromNumber(vUChar);
+ case PIVariant::UShort: return PIString::fromNumber(vUShort);
+ case PIVariant::UInt: return PIString::fromNumber(vUInt);
+ case PIVariant::ULong: return PIString::fromNumber(static_cast(vULong));
+ case PIVariant::ULLong: return PIString::fromNumber(static_cast(vULLong));
+ case PIVariant::Float: return PIString::fromNumber(vFloat);
+ case PIVariant::Double: return PIString::fromNumber(vDouble);
+ case PIVariant::LDouble: return PIString::fromNumber(vLDouble);
+ case PIVariant::String: return vString;
+ case PIVariant::StringList: return vStringList.join("%|%");
+ };
+ return vString;
+}
+
+
+PIVariant PIVariant::readFromString(const PIString & s) {
+ int i = s.find(':');
+ if (i < 0 || s.length() < 2) return PIVariant(s);
+ PIVariant ret;
+ ret.type = PIVariant::fromString(s.left(i));
+ ret.setValueOnly(s.right(s.length() - i - 1));
+ return ret;
+}
+
+
+PIVariant::Type PIVariant::fromString(const PIString & str) {
+ PIString s = str.trimmed().toLowerCase().replace(" ", "");
+ if (s == "bool") return PIVariant::Bool;
+ if (s == "char" || s == "sbyte") return PIVariant::Char;
+ if (s == "short" || s == "short int" || s == "signed short" || s == "signed short int" || s == "sword") return PIVariant::Short;
+ if (s == "int" || s == "signed" || s == "signed int") return PIVariant::Int;
+ if (s == "long" || s == "long int" || s == "signed long" || s == "signed long int" || s == "sdword") return PIVariant::Long;
+ if (s == "llong" || s == "long long" || s == "long long int" || s == "signed long long" || s == "signed long long int" || s == "sqword") return PIVariant::LLong;
+ if (s == "uchar" || s == "byte") return PIVariant::UChar;
+ if (s == "ushort" || s == "unsigned short" || s == "unsigned short int" || s == "word") return PIVariant::UShort;
+ if (s == "uint" || s == "unsigned" || s == "unsigned int") return PIVariant::UInt;
+ if (s == "ulong" || s == "unsigned long" || s == "unsigned long int" || s == "dword") return PIVariant::ULong;
+ if (s == "ullong" || s == "unsigned long long" || s == "unsigned long long int" || s == "qword") return PIVariant::ULLong;
+ if (s == "float") return PIVariant::Float;
+ if (s == "double" || s == "real") return PIVariant::Double;
+ if (s == "ldouble" || s == "long double") return PIVariant::LDouble;
+ if (s == "pistring" || s == "string") return PIVariant::String;
+ if (s == "pistringlist" || s == "vector" || s == "vector" || s == "pivector" || s == "pivector") return PIVariant::StringList;
+ return PIVariant::Double;
+}
+
+
+PIString PIVariant::toString(const PIVariant::Type & var) {
+ switch (var) {
+ case PIVariant::Bool: return "bool";
+ case PIVariant::Char: return "char";
+ case PIVariant::Short: return "short";
+ case PIVariant::Int: return "int";
+ case PIVariant::Long: return "long";
+ case PIVariant::LLong: return "llong";
+ case PIVariant::UChar: return "uchar";
+ case PIVariant::UShort: return "ushort";
+ case PIVariant::UInt: return "uint";
+ case PIVariant::ULong: return "ulong";
+ case PIVariant::ULLong: return "ullong";
+ case PIVariant::Float: return "float";
+ case PIVariant::Double: return "double";
+ case PIVariant::LDouble: return "ldouble";
+ case PIVariant::String: return "string";
+ case PIVariant::StringList: return "stringlist";
+ }
+ return "double";
+}
+
+
+uint PIVariant::variableSize(const PIVariant::Type & var) {
+ switch (var) {
+ case PIVariant::Bool: return sizeof(bool);
+ case PIVariant::Char: return sizeof(char);
+ case PIVariant::Short: return sizeof(short);
+ case PIVariant::Int: return sizeof(int);
+ case PIVariant::Long: return sizeof(long);
+ case PIVariant::LLong: return sizeof(llong);
+ case PIVariant::UChar: return sizeof(uchar);
+ case PIVariant::UShort: return sizeof(ushort);
+ case PIVariant::UInt: return sizeof(uint);
+ case PIVariant::ULong: return sizeof(ulong);
+ case PIVariant::ULLong: return sizeof(ullong);
+ case PIVariant::Float: return sizeof(float);
+ case PIVariant::Double: return sizeof(double);
+ case PIVariant::LDouble: return sizeof(ldouble);
+ default: break;
+ }
+ return 0;
+}
+
+
+double PIVariant::variableValue(const void * var_ptr, const PIVariant::Type & var) {
+ switch (var) {
+ case PIVariant::Bool: return (double)(*((bool * )var_ptr));
+ case PIVariant::Char: return (double)(*((char * )var_ptr));
+ case PIVariant::Short: return (double)(*((short * )var_ptr));
+ case PIVariant::Int: return (double)(*((int * )var_ptr));
+ case PIVariant::Long: return (double)(*((long * )var_ptr));
+ case PIVariant::LLong: return (double)(*((llong * )var_ptr));
+ case PIVariant::UChar: return (double)(*((uchar * )var_ptr));
+ case PIVariant::UShort: return (double)(*((ushort * )var_ptr));
+ case PIVariant::UInt: return (double)(*((uint * )var_ptr));
+ case PIVariant::ULong: return (double)(*((ulong * )var_ptr));
+ case PIVariant::ULLong: return (double)(*((ullong * )var_ptr));
+ case PIVariant::Float: return (double)(*((float * )var_ptr));
+ case PIVariant::Double: return (double)(*((double * )var_ptr));
+ case PIVariant::LDouble: return (ldouble)(*((ldouble * )var_ptr));
+ default: break;
+ }
+ return 0.;
+}
+
+
+void PIVariable::setVariable(const PIString & str) {
+ type_ = PIVariant::fromString(str);
+ size_ = PIVariant::variableSize(type_);
+}
+
+
+void PIVariable::writeVariable(void * dest) {
+ switch (type_) {
+ case PIVariant::Bool: *((bool * )((ullong)dest + offset)) = value_ > 0.; return;
+ case PIVariant::Char: *((char * )((ullong)dest + offset)) = char(value_); return;
+ case PIVariant::Short: *((short * )((ullong)dest + offset)) = short(value_); return;
+ case PIVariant::Int: *((int * )((ullong)dest + offset)) = int(value_); return;
+ case PIVariant::Long: *((long * )((ullong)dest + offset)) = long(value_); return;
+ case PIVariant::LLong: *((llong * )((ullong)dest + offset)) = llong(value_); return;
+ case PIVariant::UChar: *((uchar * )((ullong)dest + offset)) = uchar(value_); return;
+ case PIVariant::UShort: *((ushort * )((ullong)dest + offset)) = ushort(value_); return;
+ case PIVariant::UInt: *((uint * )((ullong)dest + offset)) = uint(value_); return;
+ case PIVariant::ULong: *((ulong * )((ullong)dest + offset)) = ulong(value_); return;
+ case PIVariant::ULLong: *((ullong * )((ullong)dest + offset)) = ullong(value_); return;
+ case PIVariant::Float: *((float * )((ullong)dest + offset)) = float(value_); return;
+ case PIVariant::Double: *((double * )((ullong)dest + offset)) = value_; return;
+ case PIVariant::LDouble: *((ldouble * )((ullong)dest + offset)) = ldouble(value_); return;
+ default: break;
+ }
+}
+
+
+void PIStruct::parseFile(const PIString & file) {
+ PIConfig conf(file, PIIODevice::ReadOnly);
+ PIVariable var;
+ PIString ts;
+ uint sz = 0;
+ vars.clear();
+ for (int i = 0; i < conf.entriesCount(); ++i) {
+ var.setVariable(conf.getValue(i));
+ var.setName(conf.getName(i));
+ var.offset = sz;
+ sz += var.size();
+ ts = conf.getComment(i);
+ if (ts.length() > 0)
+ var.setValue(ts.toDouble());
+ else var.setValue(0.);
+ vars.push_back(var);
+ }
+ size_ = sz;
+}
+
+
+void PIStruct::readData(const void * data) {
+ for (uint i = 0; i < vars.size(); ++i)
+ vars[i].readVariable(data);
+}
+
+
+void PIStruct::writeData(void * data) {
+ for (uint i = 0; i < vars.size(); ++i)
+ vars[i].writeVariable(data);
+}
+
diff --git a/src/_unsused/pivariable.cpp_ b/src/_unsused/pivariable.cpp_
new file mode 100644
index 00000000..f39d806a
--- /dev/null
+++ b/src/_unsused/pivariable.cpp_
@@ -0,0 +1,249 @@
+/*
+ PIP - Platform Independent Primitives
+ Variable, Struct (simple serialization)
+ Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include "pivariable.h"
+
+
+bool PIVariant::operator ==(const PIVariant & v) const {
+ if (type != v.type) return false;
+ switch (type) {
+ case PIVariant::Bool: return vBool == v.vBool;
+ case PIVariant::Char: return vChar == v.vChar;
+ case PIVariant::Short: return vShort == v.vShort;
+ case PIVariant::Int: return vInt == v.vInt;
+ case PIVariant::Long: return vLong == v.vLong;
+ case PIVariant::LLong: return vLLong == v.vLLong;
+ case PIVariant::UChar: return vUChar == v.vUChar;
+ case PIVariant::UShort: return vUShort == v.vUShort;
+ case PIVariant::UInt: return vUInt == v.vUInt;
+ case PIVariant::ULong: return vULong == v.vULong;
+ case PIVariant::ULLong: return vULLong == v.vULLong;
+ case PIVariant::Float: return vFloat == v.vFloat;
+ case PIVariant::Double: return vDouble == v.vDouble;
+ case PIVariant::LDouble: return vLDouble == v.vLDouble;
+ case PIVariant::String: return vString == v.vString;
+ case PIVariant::StringList: return vStringList == v.vStringList;
+ };
+ return false;
+}
+
+
+void PIVariant::setValueOnly(const PIString & s) {
+ switch (type) {
+ case PIVariant::Bool: vBool = s.toBool(); break;
+ case PIVariant::Char: vChar = s.toChar(); break;
+ case PIVariant::Short: vShort = s.toShort(); break;
+ case PIVariant::Int: vInt = s.toInt(); break;
+ case PIVariant::Long: vLong = s.toLong(); break;
+ case PIVariant::LLong: vLLong = s.toLLong(); break;
+ case PIVariant::UChar: vUChar = s.toChar(); break;
+ case PIVariant::UShort: vUShort = s.toShort(); break;
+ case PIVariant::UInt: vUInt = s.toInt(); break;
+ case PIVariant::ULong: vULong = s.toLong(); break;
+ case PIVariant::ULLong: vULLong = s.toLLong(); break;
+ case PIVariant::Float: vFloat = s.toFloat(); break;
+ case PIVariant::Double: vDouble = s.toDouble(); break;
+ case PIVariant::LDouble: vLDouble = s.toLDouble(); break;
+ case PIVariant::String: vString = s; break;
+ case PIVariant::StringList: vStringList = s.split("%|%"); break;
+ };
+}
+
+
+PIString PIVariant::stringValue() const {
+ switch (type) {
+ case PIVariant::Bool: return (vBool ? "true" : "false");
+ case PIVariant::Char: return PIString::fromNumber(vChar);
+ case PIVariant::Short: return PIString::fromNumber(vShort);
+ case PIVariant::Int: return PIString::fromNumber(vInt);
+ case PIVariant::Long: return PIString::fromNumber(vLong);
+ case PIVariant::LLong: return PIString::fromNumber(static_cast(vLLong));
+ case PIVariant::UChar: return PIString::fromNumber(vUChar);
+ case PIVariant::UShort: return PIString::fromNumber(vUShort);
+ case PIVariant::UInt: return PIString::fromNumber(vUInt);
+ case PIVariant::ULong: return PIString::fromNumber(static_cast(vULong));
+ case PIVariant::ULLong: return PIString::fromNumber(static_cast(vULLong));
+ case PIVariant::Float: return PIString::fromNumber(vFloat);
+ case PIVariant::Double: return PIString::fromNumber(vDouble);
+ case PIVariant::LDouble: return PIString::fromNumber(vLDouble);
+ case PIVariant::String: return vString;
+ case PIVariant::StringList: return vStringList.join("%|%");
+ };
+ return vString;
+}
+
+
+PIVariant PIVariant::readFromString(const PIString & s) {
+ int i = s.find(':');
+ if (i < 0 || s.length() < 2) return PIVariant(s);
+ PIVariant ret;
+ ret.type = PIVariant::fromString(s.left(i));
+ ret.setValueOnly(s.right(s.length() - i - 1));
+ return ret;
+}
+
+
+PIVariant::Type PIVariant::fromString(const PIString & str) {
+ PIString s = str.trimmed().toLowerCase().replace(" ", "");
+ if (s == "bool") return PIVariant::Bool;
+ if (s == "char" || s == "sbyte") return PIVariant::Char;
+ if (s == "short" || s == "short int" || s == "signed short" || s == "signed short int" || s == "sword") return PIVariant::Short;
+ if (s == "int" || s == "signed" || s == "signed int") return PIVariant::Int;
+ if (s == "long" || s == "long int" || s == "signed long" || s == "signed long int" || s == "sdword") return PIVariant::Long;
+ if (s == "llong" || s == "long long" || s == "long long int" || s == "signed long long" || s == "signed long long int" || s == "sqword") return PIVariant::LLong;
+ if (s == "uchar" || s == "byte") return PIVariant::UChar;
+ if (s == "ushort" || s == "unsigned short" || s == "unsigned short int" || s == "word") return PIVariant::UShort;
+ if (s == "uint" || s == "unsigned" || s == "unsigned int") return PIVariant::UInt;
+ if (s == "ulong" || s == "unsigned long" || s == "unsigned long int" || s == "dword") return PIVariant::ULong;
+ if (s == "ullong" || s == "unsigned long long" || s == "unsigned long long int" || s == "qword") return PIVariant::ULLong;
+ if (s == "float") return PIVariant::Float;
+ if (s == "double" || s == "real") return PIVariant::Double;
+ if (s == "ldouble" || s == "long double") return PIVariant::LDouble;
+ if (s == "pistring" || s == "string") return PIVariant::String;
+ if (s == "pistringlist" || s == "vector" || s == "vector" || s == "pivector" || s == "pivector") return PIVariant::StringList;
+ return PIVariant::Double;
+}
+
+
+PIString PIVariant::toString(const PIVariant::Type & var) {
+ switch (var) {
+ case PIVariant::Bool: return "bool";
+ case PIVariant::Char: return "char";
+ case PIVariant::Short: return "short";
+ case PIVariant::Int: return "int";
+ case PIVariant::Long: return "long";
+ case PIVariant::LLong: return "llong";
+ case PIVariant::UChar: return "uchar";
+ case PIVariant::UShort: return "ushort";
+ case PIVariant::UInt: return "uint";
+ case PIVariant::ULong: return "ulong";
+ case PIVariant::ULLong: return "ullong";
+ case PIVariant::Float: return "float";
+ case PIVariant::Double: return "double";
+ case PIVariant::LDouble: return "ldouble";
+ case PIVariant::String: return "string";
+ case PIVariant::StringList: return "stringlist";
+ }
+ return "double";
+}
+
+
+uint PIVariant::variableSize(const PIVariant::Type & var) {
+ switch (var) {
+ case PIVariant::Bool: return sizeof(bool);
+ case PIVariant::Char: return sizeof(char);
+ case PIVariant::Short: return sizeof(short);
+ case PIVariant::Int: return sizeof(int);
+ case PIVariant::Long: return sizeof(long);
+ case PIVariant::LLong: return sizeof(llong);
+ case PIVariant::UChar: return sizeof(uchar);
+ case PIVariant::UShort: return sizeof(ushort);
+ case PIVariant::UInt: return sizeof(uint);
+ case PIVariant::ULong: return sizeof(ulong);
+ case PIVariant::ULLong: return sizeof(ullong);
+ case PIVariant::Float: return sizeof(float);
+ case PIVariant::Double: return sizeof(double);
+ case PIVariant::LDouble: return sizeof(ldouble);
+ default: break;
+ }
+ return 0;
+}
+
+
+double PIVariant::variableValue(const void * var_ptr, const PIVariant::Type & var) {
+ switch (var) {
+ case PIVariant::Bool: return (double)(*((bool * )var_ptr));
+ case PIVariant::Char: return (double)(*((char * )var_ptr));
+ case PIVariant::Short: return (double)(*((short * )var_ptr));
+ case PIVariant::Int: return (double)(*((int * )var_ptr));
+ case PIVariant::Long: return (double)(*((long * )var_ptr));
+ case PIVariant::LLong: return (double)(*((llong * )var_ptr));
+ case PIVariant::UChar: return (double)(*((uchar * )var_ptr));
+ case PIVariant::UShort: return (double)(*((ushort * )var_ptr));
+ case PIVariant::UInt: return (double)(*((uint * )var_ptr));
+ case PIVariant::ULong: return (double)(*((ulong * )var_ptr));
+ case PIVariant::ULLong: return (double)(*((ullong * )var_ptr));
+ case PIVariant::Float: return (double)(*((float * )var_ptr));
+ case PIVariant::Double: return (double)(*((double * )var_ptr));
+ case PIVariant::LDouble: return (ldouble)(*((ldouble * )var_ptr));
+ default: break;
+ }
+ return 0.;
+}
+
+
+void PIVariable::setVariable(const PIString & str) {
+ type_ = PIVariant::fromString(str);
+ size_ = PIVariant::variableSize(type_);
+}
+
+
+void PIVariable::writeVariable(void * dest) {
+ switch (type_) {
+ case PIVariant::Bool: *((bool * )((ullong)dest + offset)) = value_ > 0.; return;
+ case PIVariant::Char: *((char * )((ullong)dest + offset)) = char(value_); return;
+ case PIVariant::Short: *((short * )((ullong)dest + offset)) = short(value_); return;
+ case PIVariant::Int: *((int * )((ullong)dest + offset)) = int(value_); return;
+ case PIVariant::Long: *((long * )((ullong)dest + offset)) = long(value_); return;
+ case PIVariant::LLong: *((llong * )((ullong)dest + offset)) = llong(value_); return;
+ case PIVariant::UChar: *((uchar * )((ullong)dest + offset)) = uchar(value_); return;
+ case PIVariant::UShort: *((ushort * )((ullong)dest + offset)) = ushort(value_); return;
+ case PIVariant::UInt: *((uint * )((ullong)dest + offset)) = uint(value_); return;
+ case PIVariant::ULong: *((ulong * )((ullong)dest + offset)) = ulong(value_); return;
+ case PIVariant::ULLong: *((ullong * )((ullong)dest + offset)) = ullong(value_); return;
+ case PIVariant::Float: *((float * )((ullong)dest + offset)) = float(value_); return;
+ case PIVariant::Double: *((double * )((ullong)dest + offset)) = value_; return;
+ case PIVariant::LDouble: *((ldouble * )((ullong)dest + offset)) = ldouble(value_); return;
+ default: break;
+ }
+}
+
+
+void PIStruct::parseFile(const PIString & file) {
+ PIConfig conf(file, PIIODevice::ReadOnly);
+ PIVariable var;
+ PIString ts;
+ uint sz = 0;
+ vars.clear();
+ for (int i = 0; i < conf.entriesCount(); ++i) {
+ var.setVariable(conf.getValue(i));
+ var.setName(conf.getName(i));
+ var.offset = sz;
+ sz += var.size();
+ ts = conf.getComment(i);
+ if (ts.length() > 0)
+ var.setValue(ts.toDouble());
+ else var.setValue(0.);
+ vars.push_back(var);
+ }
+ size_ = sz;
+}
+
+
+void PIStruct::readData(const void * data) {
+ for (uint i = 0; i < vars.size(); ++i)
+ vars[i].readVariable(data);
+}
+
+
+void PIStruct::writeData(void * data) {
+ for (uint i = 0; i < vars.size(); ++i)
+ vars[i].writeVariable(data);
+}
+
diff --git a/src/_unsused/pivariable.h b/src/_unsused/pivariable.h
new file mode 100755
index 00000000..44ba5fd8
--- /dev/null
+++ b/src/_unsused/pivariable.h
@@ -0,0 +1,196 @@
+/*
+ PIP - Platform Independent Primitives
+ Variable, Struct (simple serialization)
+ Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifndef PIVARIABLE_H
+#define PIVARIABLE_H
+
+#include "piconfig.h"
+
+class PIP_EXPORT PIVariant {
+ friend class PIVariable;
+public:
+ enum Type {Bool, Char, Short, Int, Long, LLong, UChar, UShort, UInt, ULong, ULLong, Float, Double, LDouble, String, StringList};
+
+ PIVariant() {setValue(0.);}
+ PIVariant(const char * v) {setValue(v);}
+ PIVariant(const bool & v) {setValue(v);}
+ PIVariant(const char & v) {setValue(v);}
+ PIVariant(const short & v) {setValue(v);}
+ PIVariant(const int & v) {setValue(v);}
+ PIVariant(const long & v) {setValue(v);}
+ PIVariant(const llong & v) {setValue(v);}
+ PIVariant(const uchar & v) {setValue(v);}
+ PIVariant(const ushort & v) {setValue(v);}
+ PIVariant(const uint & v) {setValue(v);}
+ PIVariant(const ulong & v) {setValue(v);}
+ PIVariant(const ullong & v) {setValue(v);}
+ PIVariant(const float & v) {setValue(v);}
+ PIVariant(const double & v) {setValue(v);}
+ PIVariant(const ldouble & v) {setValue(v);}
+ PIVariant(const PIString & v) {setValue(v);}
+ PIVariant(const PIStringList & v) {setValue(v);}
+
+ void setValue(const char * v) {setValue(PIString(v));}
+ void setValue(const bool & v) {type = PIVariant::Bool; vBool = v;}
+ void setValue(const char & v) {type = PIVariant::Char; vChar = v;}
+ void setValue(const short & v) {type = PIVariant::Short; vShort = v;}
+ void setValue(const int & v) {type = PIVariant::Int; vInt = v;}
+ void setValue(const long & v) {type = PIVariant::Long; vLong = v;}
+ void setValue(const llong & v) {type = PIVariant::LLong; vLLong = v;}
+ void setValue(const uchar & v) {type = PIVariant::UChar; vUChar = v;}
+ void setValue(const ushort & v) {type = PIVariant::UShort; vUShort = v;}
+ void setValue(const uint & v) {type = PIVariant::UInt; vUInt = v;}
+ void setValue(const ulong & v) {type = PIVariant::ULong; vULong = v;}
+ void setValue(const ullong & v) {type = PIVariant::ULLong; vULLong = v;}
+ void setValue(const float & v) {type = PIVariant::Float; vFloat = v;}
+ void setValue(const double & v) {type = PIVariant::Double; vDouble = v;}
+ void setValue(const ldouble & v) {type = PIVariant::LDouble; vLDouble = v;}
+ void setValue(const PIString & v) {type = PIVariant::String; vString = v;}
+ void setValue(const PIStringList & v) {type = PIVariant::StringList; vStringList = v;}
+ void setValueOnly(const PIString & v);
+ PIString typeName() const {return PIVariant::toString(type);}
+ double doubleValue() const {return PIVariant::variableValue(&vChar, type);}
+ PIString stringValue() const;
+ void typeFromString(const PIString & str) {type = PIVariant::fromString(str);}
+ PIString typeToString() const {return PIVariant::toString(type);}
+ uint size() {if (type != PIVariant::String && type != PIVariant::StringList) return PIVariant::variableSize(type); if (type == PIVariant::String) return vString.size(); else return vStringList.contentSize();}
+ PIString writeToString() const {return typeName() + ":" + stringValue();}
+
+#ifdef QNX
+ void operator =(const PIVariant & v) {type = v.type; vLDouble = v.vLDouble; vString = v.vString; vStringList = v.vStringList;}
+#endif
+ void operator =(const char * v) {setValue(PIString(v));}
+ void operator =(const bool & v) {type = PIVariant::Bool; vBool = v;}
+ void operator =(const char & v) {type = PIVariant::Char; vChar = v;}
+ void operator =(const short & v) {type = PIVariant::Short; vShort = v;}
+ void operator =(const int & v) {type = PIVariant::Int; vInt = v;}
+ void operator =(const long & v) {type = PIVariant::Long; vLong = v;}
+ void operator =(const llong & v) {type = PIVariant::LLong; vLLong = v;}
+ void operator =(const uchar & v) {type = PIVariant::UChar; vUChar = v;}
+ void operator =(const ushort & v) {type = PIVariant::UShort; vUShort = v;}
+ void operator =(const uint & v) {type = PIVariant::UInt; vUInt = v;}
+ void operator =(const ulong & v) {type = PIVariant::ULong; vULong = v;}
+ void operator =(const ullong & v) {type = PIVariant::ULLong; vULLong = v;}
+ void operator =(const float & v) {type = PIVariant::Float; vFloat = v;}
+ void operator =(const double & v) {type = PIVariant::Double; vDouble = v;}
+ void operator =(const ldouble & v) {type = PIVariant::LDouble; vLDouble = v;}
+ void operator =(const PIString & v) {type = PIVariant::String; vString = v;}
+ void operator =(const PIStringList & v) {type = PIVariant::StringList; vStringList = v;}
+
+ bool operator ==(const PIVariant & v) const;
+ bool operator !=(const PIVariant & v) const {return !(*this == v);}
+
+ PIVariant::Type type;
+ union {
+ bool vBool;
+ char vChar;
+ short vShort;
+ int vInt;
+ long vLong;
+ llong vLLong;
+ uchar vUChar;
+ ushort vUShort;
+ uint vUInt;
+ ulong vULong;
+ ullong vULLong;
+ float vFloat;
+ double vDouble;
+ ldouble vLDouble;
+ };
+ PIString vString;
+ PIStringList vStringList;
+
+ static PIVariant readFromString(const PIString & s);
+
+private:
+ static PIVariant::Type fromString(const PIString & str);
+ static PIString toString(const PIVariant::Type & var);
+ static uint variableSize(const PIVariant::Type & var);
+ static double variableValue(const void * var_ptr, const PIVariant::Type & var);
+
+};
+
+inline std::ostream & operator <<(std::ostream & s, const PIVariant & v) {s << v.typeName() << ": " << v.stringValue(); return s;}
+
+class PIP_EXPORT PIVariable {
+public:
+ PIVariable() {;}
+ PIVariable(const PIString & str) {setVariable(str);}
+ ~PIVariable() {;}
+
+ void setVariable(const PIString & str);
+ void writeVariable(void * dest);
+ void readVariable(const void * var_ptr) {value_ = PIVariant::variableValue((char * )((long)var_ptr + offset), type_);}
+ PIVariant::Type type() const {return type_;}
+ uint size() const {return size_;}
+ const PIString & name() {return name_;}
+ void setName(const PIString & str) {name_ = str;}
+ double value() const {return value_;}
+ void setValue(const double & val) {value_ = val;}
+
+ int offset;
+
+private:
+ PIVariant::Type type_;
+ uint size_;
+ PIString name_;
+ double value_;
+
+};
+
+
+/*
+ * PIStruct is abstract structure, described by *.conf file with format of each line:
+ * " = # ".
+ * e.g. "pi = double #f 3.1418"
+ *
+ * You can write or read binary content of this struct
+ * by functions "writeData" and "readData", e.g.
+ * "char * data = new char[struct.size()];
+ * struct.writeData(data);"
+ *
+ * Access to each variable in struct is looks like
+ * "double value = struct["pi"].value();"
+*/
+
+class PIP_EXPORT PIStruct {
+public:
+ PIStruct() {;}
+ PIStruct(const PIString & str) {parseFile(str);}
+
+ void parseFile(const PIString & file);
+ void readData(const void * data);
+ void writeData(void * data);
+ void clear() {vars.clear(); size_ = 0;}
+ uint count() const {return vars.size();}
+ uint size() const {return size_;}
+ const PIString & name() {return name_;}
+ void setName(const PIString & str) {name_ = str;}
+ PIVariable & operator[](const uint & index) {return vars[index];}
+ PIVariable & operator[](const PIString & name) {for (uint i = 0; i < vars.size(); ++i) if (vars[i].name() == name) return vars[i]; return def;}
+
+private:
+ uint size_;
+ PIString name_;
+ PIVariable def;
+ PIVector vars;
+
+};
+
+#endif // PIVARIABLE_H
diff --git a/src/_unsused/pivariable.h_ b/src/_unsused/pivariable.h_
new file mode 100644
index 00000000..44ba5fd8
--- /dev/null
+++ b/src/_unsused/pivariable.h_
@@ -0,0 +1,196 @@
+/*
+ PIP - Platform Independent Primitives
+ Variable, Struct (simple serialization)
+ Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifndef PIVARIABLE_H
+#define PIVARIABLE_H
+
+#include "piconfig.h"
+
+class PIP_EXPORT PIVariant {
+ friend class PIVariable;
+public:
+ enum Type {Bool, Char, Short, Int, Long, LLong, UChar, UShort, UInt, ULong, ULLong, Float, Double, LDouble, String, StringList};
+
+ PIVariant() {setValue(0.);}
+ PIVariant(const char * v) {setValue(v);}
+ PIVariant(const bool & v) {setValue(v);}
+ PIVariant(const char & v) {setValue(v);}
+ PIVariant(const short & v) {setValue(v);}
+ PIVariant(const int & v) {setValue(v);}
+ PIVariant(const long & v) {setValue(v);}
+ PIVariant(const llong & v) {setValue(v);}
+ PIVariant(const uchar & v) {setValue(v);}
+ PIVariant(const ushort & v) {setValue(v);}
+ PIVariant(const uint & v) {setValue(v);}
+ PIVariant(const ulong & v) {setValue(v);}
+ PIVariant(const ullong & v) {setValue(v);}
+ PIVariant(const float & v) {setValue(v);}
+ PIVariant(const double & v) {setValue(v);}
+ PIVariant(const ldouble & v) {setValue(v);}
+ PIVariant(const PIString & v) {setValue(v);}
+ PIVariant(const PIStringList & v) {setValue(v);}
+
+ void setValue(const char * v) {setValue(PIString(v));}
+ void setValue(const bool & v) {type = PIVariant::Bool; vBool = v;}
+ void setValue(const char & v) {type = PIVariant::Char; vChar = v;}
+ void setValue(const short & v) {type = PIVariant::Short; vShort = v;}
+ void setValue(const int & v) {type = PIVariant::Int; vInt = v;}
+ void setValue(const long & v) {type = PIVariant::Long; vLong = v;}
+ void setValue(const llong & v) {type = PIVariant::LLong; vLLong = v;}
+ void setValue(const uchar & v) {type = PIVariant::UChar; vUChar = v;}
+ void setValue(const ushort & v) {type = PIVariant::UShort; vUShort = v;}
+ void setValue(const uint & v) {type = PIVariant::UInt; vUInt = v;}
+ void setValue(const ulong & v) {type = PIVariant::ULong; vULong = v;}
+ void setValue(const ullong & v) {type = PIVariant::ULLong; vULLong = v;}
+ void setValue(const float & v) {type = PIVariant::Float; vFloat = v;}
+ void setValue(const double & v) {type = PIVariant::Double; vDouble = v;}
+ void setValue(const ldouble & v) {type = PIVariant::LDouble; vLDouble = v;}
+ void setValue(const PIString & v) {type = PIVariant::String; vString = v;}
+ void setValue(const PIStringList & v) {type = PIVariant::StringList; vStringList = v;}
+ void setValueOnly(const PIString & v);
+ PIString typeName() const {return PIVariant::toString(type);}
+ double doubleValue() const {return PIVariant::variableValue(&vChar, type);}
+ PIString stringValue() const;
+ void typeFromString(const PIString & str) {type = PIVariant::fromString(str);}
+ PIString typeToString() const {return PIVariant::toString(type);}
+ uint size() {if (type != PIVariant::String && type != PIVariant::StringList) return PIVariant::variableSize(type); if (type == PIVariant::String) return vString.size(); else return vStringList.contentSize();}
+ PIString writeToString() const {return typeName() + ":" + stringValue();}
+
+#ifdef QNX
+ void operator =(const PIVariant & v) {type = v.type; vLDouble = v.vLDouble; vString = v.vString; vStringList = v.vStringList;}
+#endif
+ void operator =(const char * v) {setValue(PIString(v));}
+ void operator =(const bool & v) {type = PIVariant::Bool; vBool = v;}
+ void operator =(const char & v) {type = PIVariant::Char; vChar = v;}
+ void operator =(const short & v) {type = PIVariant::Short; vShort = v;}
+ void operator =(const int & v) {type = PIVariant::Int; vInt = v;}
+ void operator =(const long & v) {type = PIVariant::Long; vLong = v;}
+ void operator =(const llong & v) {type = PIVariant::LLong; vLLong = v;}
+ void operator =(const uchar & v) {type = PIVariant::UChar; vUChar = v;}
+ void operator =(const ushort & v) {type = PIVariant::UShort; vUShort = v;}
+ void operator =(const uint & v) {type = PIVariant::UInt; vUInt = v;}
+ void operator =(const ulong & v) {type = PIVariant::ULong; vULong = v;}
+ void operator =(const ullong & v) {type = PIVariant::ULLong; vULLong = v;}
+ void operator =(const float & v) {type = PIVariant::Float; vFloat = v;}
+ void operator =(const double & v) {type = PIVariant::Double; vDouble = v;}
+ void operator =(const ldouble & v) {type = PIVariant::LDouble; vLDouble = v;}
+ void operator =(const PIString & v) {type = PIVariant::String; vString = v;}
+ void operator =(const PIStringList & v) {type = PIVariant::StringList; vStringList = v;}
+
+ bool operator ==(const PIVariant & v) const;
+ bool operator !=(const PIVariant & v) const {return !(*this == v);}
+
+ PIVariant::Type type;
+ union {
+ bool vBool;
+ char vChar;
+ short vShort;
+ int vInt;
+ long vLong;
+ llong vLLong;
+ uchar vUChar;
+ ushort vUShort;
+ uint vUInt;
+ ulong vULong;
+ ullong vULLong;
+ float vFloat;
+ double vDouble;
+ ldouble vLDouble;
+ };
+ PIString vString;
+ PIStringList vStringList;
+
+ static PIVariant readFromString(const PIString & s);
+
+private:
+ static PIVariant::Type fromString(const PIString & str);
+ static PIString toString(const PIVariant::Type & var);
+ static uint variableSize(const PIVariant::Type & var);
+ static double variableValue(const void * var_ptr, const PIVariant::Type & var);
+
+};
+
+inline std::ostream & operator <<(std::ostream & s, const PIVariant & v) {s << v.typeName() << ": " << v.stringValue(); return s;}
+
+class PIP_EXPORT PIVariable {
+public:
+ PIVariable() {;}
+ PIVariable(const PIString & str) {setVariable(str);}
+ ~PIVariable() {;}
+
+ void setVariable(const PIString & str);
+ void writeVariable(void * dest);
+ void readVariable(const void * var_ptr) {value_ = PIVariant::variableValue((char * )((long)var_ptr + offset), type_);}
+ PIVariant::Type type() const {return type_;}
+ uint size() const {return size_;}
+ const PIString & name() {return name_;}
+ void setName(const PIString & str) {name_ = str;}
+ double value() const {return value_;}
+ void setValue(const double & val) {value_ = val;}
+
+ int offset;
+
+private:
+ PIVariant::Type type_;
+ uint size_;
+ PIString name_;
+ double value_;
+
+};
+
+
+/*
+ * PIStruct is abstract structure, described by *.conf file with format of each line:
+ * " = # ".
+ * e.g. "pi = double #f 3.1418"
+ *
+ * You can write or read binary content of this struct
+ * by functions "writeData" and "readData", e.g.
+ * "char * data = new char[struct.size()];
+ * struct.writeData(data);"
+ *
+ * Access to each variable in struct is looks like
+ * "double value = struct["pi"].value();"
+*/
+
+class PIP_EXPORT PIStruct {
+public:
+ PIStruct() {;}
+ PIStruct(const PIString & str) {parseFile(str);}
+
+ void parseFile(const PIString & file);
+ void readData(const void * data);
+ void writeData(void * data);
+ void clear() {vars.clear(); size_ = 0;}
+ uint count() const {return vars.size();}
+ uint size() const {return size_;}
+ const PIString & name() {return name_;}
+ void setName(const PIString & str) {name_ = str;}
+ PIVariable & operator[](const uint & index) {return vars[index];}
+ PIVariable & operator[](const PIString & name) {for (uint i = 0; i < vars.size(); ++i) if (vars[i].name() == name) return vars[i]; return def;}
+
+private:
+ uint size_;
+ PIString name_;
+ PIVariable def;
+ PIVector vars;
+
+};
+
+#endif // PIVARIABLE_H
diff --git a/src/code/picodeinfo.cpp b/src/code/picodeinfo.cpp
new file mode 100755
index 00000000..ef2801b3
--- /dev/null
+++ b/src/code/picodeinfo.cpp
@@ -0,0 +1,42 @@
+/*
+ PIP - Platform Independent Primitives
+ C++ code info structs
+ Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include "picodeinfo.h"
+
+
+PIString PICodeInfo::EnumInfo::memberName(int value_) const {
+ piForeachC (PICodeInfo::EnumeratorInfo & e, members)
+ if (e.value == value_)
+ return e.name;
+ return PIString();
+}
+
+
+int PICodeInfo::EnumInfo::memberValue(const PIString & name_) const {
+ piForeachC (PICodeInfo::EnumeratorInfo & e, members)
+ if (e.name == name_)
+ return e.value;
+ return -1;
+}
+
+
+PIMap * PICodeInfo::classesInfo;
+PIMap * PICodeInfo::enumsInfo;
+
+bool __PICodeInfoInitializer__::_inited_ = false;
diff --git a/src/code/picodeinfo.h b/src/code/picodeinfo.h
new file mode 100755
index 00000000..c6f45125
--- /dev/null
+++ b/src/code/picodeinfo.h
@@ -0,0 +1,158 @@
+/*! \file picodeinfo.h
+ * \brief C++ code info structs
+*/
+/*
+ PIP - Platform Independent Primitives
+ C++ code info structs
+ Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+
+#ifndef PICODEINFO_H
+#define PICODEINFO_H
+
+#include "pistring.h"
+
+namespace PICodeInfo {
+
+enum TypeFlag {
+ NoFlag,
+ Const = 0x01,
+ Static = 0x02,
+ Mutable = 0x04,
+ Volatile = 0x08,
+ Inline = 0x10,
+ Virtual = 0x20,
+ Extern = 0x40
+};
+
+typedef PIFlags TypeFlags;
+
+struct TypeInfo {
+ TypeInfo(const PIString & n = PIString(), const PIString & t = PIString(), PICodeInfo::TypeFlags f = 0) {name = n; type = t; flags = f;}
+ PIString name;
+ PIString type;
+ PICodeInfo::TypeFlags flags;
+};
+
+struct FunctionInfo {
+ PIString name;
+ TypeInfo return_type;
+ PIVector arguments;
+};
+
+struct ClassInfo {
+ PIString name;
+ PIStringList parents;
+ PIVector variables;
+ PIVector functions;
+};
+
+struct EnumeratorInfo {
+ EnumeratorInfo(const PIString & n = PIString(), int v = 0) {name = n; value = v;}
+ PIString name;
+ int value;
+};
+
+struct EnumInfo {
+ PIString memberName(int value) const;
+ int memberValue(const PIString & name) const;
+ PIString name;
+ PIVector members;
+};
+
+
+inline PICout operator <<(PICout s, const PICodeInfo::TypeInfo & v) {
+ if (v.flags[Inline]) s << "inline ";
+ if (v.flags[Virtual]) s << "virtual ";
+ if (v.flags[Mutable]) s << "mutable ";
+ if (v.flags[Volatile]) s << "volatile ";
+ if (v.flags[Static]) s << "static ";
+ if (v.flags[Const]) s << "const ";
+ s << v.type;
+ if (!v.name.isEmpty())
+ s << " " << v.name;
+ return s;
+}
+
+inline PICout operator <<(PICout s, const PICodeInfo::EnumeratorInfo & v) {s << v.name << " = " << v.value; return s;}
+
+inline PICout operator <<(PICout s, const PICodeInfo::ClassInfo & v) {
+ s.setControl(0, true);
+ s << "class " << v.name;
+ if (!v.parents.isEmpty()) {
+ s << ": ";
+ bool first = true;
+ piForeachC (PIString & i, v.parents) {
+ if (first) first = false;
+ else s << ", ";
+ s << i;
+ }
+ }
+ s << " {\n";
+ piForeachC (FunctionInfo & i, v.functions) {
+ s << Tab << i.return_type << " " << i.name << "(";
+ bool fa = true;
+ piForeachC (TypeInfo & a, i.arguments) {
+ if (fa) fa = false;
+ else s << ", ";
+ s << a;
+ }
+ s << ");\n";
+ }
+ if (!v.functions.isEmpty() && !v.variables.isEmpty())
+ s << "\n";
+ piForeachC (TypeInfo & i, v.variables) {
+ s << Tab << i << ";\n";
+ }
+ s << "}\n";
+ s.restoreControl();
+ return s;
+}
+
+inline PICout operator <<(PICout s, const PICodeInfo::EnumInfo & v) {
+ s.setControl(0, true);
+ s << "enum " << v.name << " {\n";
+ piForeachC (EnumeratorInfo & i, v.members) {
+ bool f = true;
+ if (f) f = false;
+ else s << ", ";
+ s << Tab << i << "\n";
+ }
+ s << "}\n";
+ s.restoreControl();
+ return s;
+}
+
+extern PIMap * classesInfo;
+extern PIMap * enumsInfo;
+
+}
+
+class __PICodeInfoInitializer__ {
+public:
+ __PICodeInfoInitializer__() {
+ if (_inited_) return;
+ _inited_ = true;
+ PICodeInfo::classesInfo = new PIMap;
+ PICodeInfo::enumsInfo = new PIMap;
+ }
+ static bool _inited_;
+};
+
+static __PICodeInfoInitializer__ __picodeinfoinitializer__;
+
+#endif // PICODEINFO_H
diff --git a/src/code/picodeparser.cpp b/src/code/picodeparser.cpp
new file mode 100755
index 00000000..36722d2e
--- /dev/null
+++ b/src/code/picodeparser.cpp
@@ -0,0 +1,846 @@
+/*
+ PIP - Platform Independent Primitives
+ C++ code parser
+ Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include "picodeparser.h"
+
+
+
+PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const {
+ PIStringList arg_vals;
+ while (!args_.isEmpty()) {
+ int ci = args_.find(","), bi = args_.find("(");
+ if (ci < 0) {
+ arg_vals << args_;
+ break;
+ }
+ PIString ca;
+ if (bi >= 0 && bi < ci) {
+ ca = args_.left(args_.takeLeft(bi));
+ ci -= ca.size_s(); bi -= ca.size_s();
+ ca += "(" + args_.takeRange("(", ")") + ")";
+ } else {
+ ca = args_.takeLeft(ci);
+ }
+ arg_vals << ca;
+ args_.trim(); args_.takeLeft(1); args_.trim();
+ }
+ if (args.size() != arg_vals.size()) {
+ piCout << ("Error: in expansion of macro \"" + name + "(" + args.join(", ") + ")\": expect")
+ << args.size() << "arguments but takes" << arg_vals.size() << "!";
+ if (ok != 0) *ok = false;
+ return PIString();
+ }
+ PIString ret = value;
+ for (int i = 0; i < args.size_s(); ++i) {
+ const PIString & an(args[i]), av(arg_vals[i]);
+ int ind(-1);
+ while ((ind = ret.find(an, ind + 1)) >= 0) {
+ PIChar ppc(0), pc(0), nc(0);
+ if (ind > 1) ppc = ret[ind - 2];
+ if (ind > 0) pc = ret[ind - 1];
+ if (ind + an.size_s() < ret.size_s()) nc = ret[ind + an.size_s()];
+ if (ppc != '#' && pc == '#' && !_isCChar(nc)) { // to chars
+ ind--;
+ ret.replace(ind, an.size_s() + 1, "\"" + av + "\"");
+ ind -= an.size_s() - av.size_s() - 1;
+ continue;
+ }
+ if (_isCChar(pc) || _isCChar(nc)) continue;
+ ret.replace(ind, an.size_s(), av);
+ ind -= an.size_s() - av.size_s();
+ }
+ }
+ ret.replaceAll("##", "");
+ if (ok != 0) *ok = true;
+ return ret;
+}
+
+
+
+PICodeParser::PICodeParser() {
+ macros_iter = 32;
+ with_includes = true;
+ clear();
+ includes << "";
+}
+
+
+void PICodeParser::parseFile(const PIString & file, bool follow_includes) {
+ clear();
+ parseFileInternal(file, follow_includes);
+ /*piCout << "\n\nDefines:";
+ piForeachC (Define & m, defines)
+ piCout << "define" << m.first << m.second;
+ piCout << "\n\nMacros:";
+ piForeachC (Macro & m, macros)
+ piCout << "Macro:" << m.name << m.args << m.value;
+ piCout << "\n\nClasses:";
+ piForeachC (Entity * c, entities)
+ piCout << "class" << c->name << c->parents;
+ piCout << "\n\nEnums:";
+ piForeachC (Enum & c, enums)
+ piCout << "enum" << c.name << c.members;
+ piCout << "\n\nTypedefs:";
+ piForeachC (Typedef & c, typedefs)
+ piCout << "typedef" << c;*/
+}
+
+
+void PICodeParser::parseFiles(const PIStringList & files, bool follow_includes) {
+ clear();
+ piForeachC (PIString & f, files)
+ parseFileInternal(f, follow_includes);
+ /*piCout << "\n\nDefines:";
+ piForeachC (Define & m, defines)
+ piCout << "define" << m.first << m.second;
+ piCout << "\n\nMacros:";
+ piForeachC (Macro & m, macros)
+ piCout << "Macro:" << m.name << m.args << m.value;
+ piCout << "\n\nClasses:";
+ piForeachC (Entity * c, entities)
+ piCout << "class" << c->name << c->parents;
+ piCout << "\n\nEnums:";
+ piForeachC (Enum & c, enums)
+ piCout << "enum" << c.name << c.members;
+ piCout << "\n\nTypedefs:";
+ piForeachC (Typedef & c, typedefs)
+ piCout << "typedef" << c;*/
+}
+
+
+bool PICodeParser::isEnum(const PIString & name) {
+ piForeachC (Enum & e, enums)
+ if (e.name == name)
+ return true;
+ return false;
+}
+
+
+bool PICodeParser::parseFileInternal(const PIString & file, bool follow_includes) {
+ if (proc_files[file]) return true;
+ with_includes = follow_includes;
+ cur_file = file;
+ PIFile f(file, PIIODevice::ReadOnly);
+ int ii = 0;
+ while (!f.isOpened() && ii < (includes.size_s() - 1)) {
+ f.setPath(includes[++ii] + "/" + file);
+ //piCout << "try" << f.path();
+ f.open(PIIODevice::ReadOnly);
+ }
+ if (!f.isOpened()) {
+ //piCout << ("Error: can`t open file \"" + file + "\"!");
+ return false;
+ }
+ //piCout << "add" << file;
+ proc_files << f.path();
+ PIString fc = f.readAll();
+ piCout << "parsing" << f.path() << "...";
+ bool is_main = isMainFile(fc);
+ if (is_main) main_file = f.path();
+ bool ret = parseFileContent(fc, is_main);
+ piCout << "parsing" << f.path() << "done";
+ return ret;
+}
+
+
+void PICodeParser::clear() {
+ piForeach (Entity * i, entities) delete i;
+ defines.clear();
+ macros.clear();
+ enums.clear();
+ typedefs.clear();
+ entities.clear();
+ proc_files.clear();
+ cur_namespace.clear();
+ main_file.clear();
+ evaluator.clearCustomVariables();
+ defines << Define("PICODE", "") << custom_defines;
+}
+
+
+bool PICodeParser::parseFileContent(PIString & fc, bool main) {
+ bool mlc = false, cc = false;
+ int mls = 0, ole = -1, /*ccs = 0,*/ end = 0;
+ char c = 0, pc = 0;
+ PIString pfc, line, ccmn, tmp;
+ PIMap cchars;
+
+ /// Remove comments, join multiline "*" and replace "*" to $n (cchars)
+ fc.replaceAll("\r\n", "\n");
+ fc.replaceAll("\r", "\n");
+ for (int i = 0; i < fc.size_s() - 1; ++i) {
+ if (i > 0) pc = c;
+ c = fc[i].toAscii();
+ if (c == '"' && !mlc && pc != '\'') {
+ if (i > 0) if (fc[i - 1] == '\\') continue;
+ cc = !cc;
+ /*if (cc) ccs = i;
+ if (!cc) {
+ ccmn = "$" + PIString::fromNumber(cchars.size());
+ cchars[ccmn] = fc.mid(ccs, i - ccs + 1);
+ fc.replace(ccs, i - ccs + 1, ccmn);
+ i = ccs - 1 + ccmn.size_s();
+ }*/
+ continue;
+ }
+ if (i > 0)
+ if (c == '\\' && fc[i - 1].toAscii() != '\\') {
+ fc.cutMid(i, 2);
+ --i;
+ continue;
+ }
+ if (cc) continue;
+ if (fc.mid(i, 2) == "/*") {mlc = true; mls = i; ++i; continue;}
+ if (fc.mid(i, 2) == "*/" && mlc) {mlc = false; fc.cutMid(mls, i - mls + 2); i = mls - 1; continue;}
+ if (fc.mid(i, 2) == "//" && !mlc) {ole = fc.find('\n', i); fc.cutMid(i, ole < 0 ? -1 : ole - i); --i; continue;}
+ }
+ //piCout << fc;
+ pfc = procMacros(fc);
+
+ if (main) return true;
+
+ bool replaced = true;
+ int replaced_cnt = 0;
+ while (replaced) {
+ //piCout << "MACRO iter" << replaced_cnt;
+ if (replaced_cnt >= macros_iter) {
+ piCout << "Error: recursive macros detected!";
+ break;//return false;
+ }
+ replaced_cnt++;
+ replaced = false;
+ piForeachC (Define & d, defines) {
+ int ind(-1);
+ while ((ind = pfc.find(d.first, ind + 1)) >= 0) {
+ PIChar pc(0), nc(0);
+ if (ind > 0) pc = pfc[ind - 1];
+ if (ind + d.first.size_s() < pfc.size_s()) nc = pfc[ind + d.first.size_s()];
+ if (_isCChar(pc) || _isCChar(nc) || nc.isDigit()) continue;
+ pfc.replace(ind, d.first.size_s(), d.second);
+ ind -= d.first.size_s() - d.second.size_s();
+ replaced = true;
+ }
+ }
+ piForeachC (Macro & m, macros) {
+ int ind(-1);
+ while ((ind = pfc.find(m.name, ind + 1)) >= 0) {
+ PIChar pc(0), nc(0);
+ if (ind > 0) pc = pfc[ind - 1];
+ if (ind + m.name.size_s() < pfc.size_s()) nc = pfc[ind + m.name.size_s()];
+ if (_isCChar(pc) || _isCChar(nc) || nc.isDigit()) continue;
+ PIString ret, range; bool ok(false);
+ range = pfc.mid(ind + m.name.size_s()).takeRange("(", ")");
+ ret = m.expand(range, &ok);
+ if (!ok) return false;
+ int rlen = pfc.find(range, ind + m.name.size_s()) + range.size_s() + 1 - ind;
+ pfc.replace(ind, rlen, ret);
+ ind -= rlen - ret.size_s();
+ replaced = true;
+ }
+ }
+ }
+
+ //piCout << NewLine << "file" << cur_file << pfc;
+ int pl = -1;
+ while (!pfc.isEmpty()) {
+ pfc.trim();
+ int nl = pfc.size_s();
+ if (pl == nl) break;
+ pl = nl;
+ if (pfc.left(9) == "namespace") {
+ pfc.cutLeft(pfc.find("{") + 1);
+ continue;
+ }
+ if (pfc.left(8) == "template") {
+ pfc.cutLeft(8);
+ pfc.takeRange("<", ">");
+ bool def = !isDeclaration(pfc, 0, &end);
+ pfc.cutLeft(end);
+ if (def) pfc.takeRange("{", "}");
+ else pfc.takeSymbol();
+ continue;
+ }
+ if (pfc.left(5) == "class" || pfc.left(6) == "struct") {
+ int dind = pfc.find("{", 0), find = pfc.find(";", 0);
+ if (dind < 0 && find < 0) {pfc.cutLeft(6); continue;}
+ if (dind < 0 || find < dind) {pfc.cutLeft(6); continue;}
+ ccmn = pfc.left(dind) + "{\n" + pfc.mid(dind).takeRange('{', '}') + "\n}\n";
+ pfc.remove(0, ccmn.size());
+ parseClass(ccmn);
+ continue;
+ }
+ if (pfc.left(4) == "enum") {
+ pfc.cutLeft(4);
+ tmp = pfc.takeCWord();
+ parseEnum(cur_namespace + tmp, pfc.takeRange("{", "}"));
+ pfc.takeSymbol();
+ continue;
+ }
+ if (pfc.left(7) == "typedef") {
+ pfc.cutLeft(7);
+ typedefs << parseTypedef(pfc.takeLeft(pfc.find(";")));
+ if (typedefs.back().first.isEmpty()) typedefs.pop_back();
+ else root_.typedefs << typedefs.back();
+ pfc.takeSymbol();
+ continue;
+ }
+ int sci = pfc.find(";", 0), obi = pfc.find("{", 0);
+ if (sci < 0 && obi < 0) {
+ pfc.takeLeft(1);
+ continue;
+ }
+ PIString str;
+ if (sci < obi) {
+ str = pfc.takeLeft(sci + 1);
+ } else {
+ str = pfc.takeLeft(obi);
+ pfc.cutLeft(pfc.takeRange("{", "}"));
+ }
+ parseMember(&root_, str);
+ }
+
+ return true;
+}
+
+
+PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc) {
+ PIString cd = fc.trimmed().removeAll('\n').replaceAll("\t", " ").replaceAll(" ", " "), pn;
+ //piCout << "found class <****\n" << cd << "\n****>";
+ int ind = cd.find(":");
+ PIVector parents;
+ if (ind > 0) {
+ PIStringList pl = cd.takeMid(ind + 1).trim().split(",");
+ cd.cutRight(1);
+ Entity * pe = 0;
+ piForeachC (PIString & p, pl) {
+ if (p.contains(" ")) pn = p.mid(p.find(" ") + 1);
+ else pn = p;
+ pe = findEntityByName(pn);
+ if (pe == 0) ;//{piCout << "Error: can`t find" << pn;}
+ else parents << pe;
+ }
+ }
+ bool is_class = cd.left(5) == "class";
+ cur_def_vis = (is_class ? Private : Public);
+ PIString cn = cd.mid(6).trim();
+ if (cn.isEmpty()) return 0;
+ Entity * e = new Entity();
+ e->name = cur_namespace + cn;
+ e->type = (is_class ? "class" : "struct");
+ e->parents = parents;
+ e->file = cur_file;
+ entities << e;
+ return e;
+}
+
+
+PIString PICodeParser::parseClass(PIString & fc) {
+ Visibility prev_vis = cur_def_vis;
+ int dind = fc.find("{"), find = fc.find(";"), end = 0;
+ if (dind < 0 && find < 0) return PIString();
+ if (dind < 0 || find < dind) return fc.left(find);
+ Entity * ce = parseClassDeclaration(fc.takeLeft(dind));
+ fc.trim().cutLeft(1).cutRight(1).trim();
+ //piCout << "found class <****\n" << fc << "\n****>";
+ if (!ce) return PIString();
+ int ps = -1;
+ bool def = false;
+ PIString prev_namespace = cur_namespace, stmp;
+ cur_namespace = ce->name + "::";
+ //piCout << "parse class" << ce->name << "namespace" << cur_namespace;
+ //piCout << "\nparse class" << ce->name << "namespace" << cur_namespace;
+ while (!fc.isEmpty()) {
+ PIString cw = fc.takeCWord(), tmp;
+ //piCout << "\ntaked word" << cw;
+ if (cw == "public") {cur_def_vis = Public; fc.cutLeft(1); continue;}
+ if (cw == "protected") {cur_def_vis = Protected; fc.cutLeft(1); continue;}
+ if (cw == "private") {cur_def_vis = Private; fc.cutLeft(1); continue;}
+ if (cw == "class") {if (isDeclaration(fc, 0, &end)) {fc.cutLeft(end); fc.takeSymbol(); continue;} tmp = fc.takeLeft(fc.find("{")); stmp = fc.takeRange("{", "}"); fc.takeSymbol(); stmp = "class " + tmp + "{" + stmp + "}"; parseClass(stmp); continue;}
+ if (cw == "struct") {if (isDeclaration(fc, 0, &end)) {fc.cutLeft(end); fc.takeSymbol(); continue;} tmp = fc.takeLeft(fc.find("{")); stmp = fc.takeRange("{", "}"); fc.takeSymbol(); stmp = "struct " + tmp + "{" + stmp + "}"; parseClass(stmp); continue;}
+ if (cw == "enum") {tmp = fc.takeCWord(); parseEnum(cur_namespace + tmp, fc.takeRange("{", "}")); fc.takeSymbol(); continue;}
+ if (cw == "friend") {fc.cutLeft(fc.find(";") + 1); continue;}
+ if (cw == "typedef") {ce->typedefs << parseTypedef(fc.takeLeft(fc.find(";"))); typedefs << ce->typedefs.back(); typedefs.back().first.insert(0, cur_namespace); if (ce->typedefs.back().first.isEmpty()) ce->typedefs.pop_back(); fc.takeSymbol(); continue;}
+ if (cw == "template") {
+ fc.takeRange("<", ">");
+ def = !isDeclaration(fc, 0, &end);
+ fc.cutLeft(end);
+ if (def) fc.takeRange("{", "}");
+ else fc.takeSymbol();
+ continue;
+ }
+ def = !isDeclaration(fc, 0, &end);
+ tmp = (cw + fc.takeLeft(end)).trim();
+ if (!tmp.isEmpty())
+ parseMember(ce, tmp);
+ if (def) fc.takeRange("{", "}");
+ else fc.takeSymbol();
+ if (ps == fc.size_s()) {/*cur_namespace = prev_namespace;*/ fc.cutLeft(1);/*return false*/;}
+ ps = fc.size_s();
+ }
+ cur_def_vis = prev_vis;
+ cur_namespace = prev_namespace;
+ return ce->name;
+}
+
+
+bool PICodeParser::parseEnum(const PIString & name, PIString fc) {
+ //piCout << "enum" << name << fc;
+ Enum e(name);
+ PIStringList vl(fc.split(","));
+ PIString vn;
+ int cv = -1, ind = 0;
+ piForeachC (PIString & v, vl) {
+ vn = v; ind = v.find("=");
+ if (ind > 0) {cv = v.right(v.size_s() - ind - 1).toInt(); vn = v.left(ind);}
+ if (ind < 0) ++cv;
+ e.members << Enumerator(vn.trim(), cv);
+ }
+ enums << e;
+ return true;
+}
+
+
+PICodeParser::Typedef PICodeParser::parseTypedef(PIString fc) {
+ //piCout << "parse typedef" << fc;
+ Typedef td;
+ fc.replaceAll("\t", " ");
+
+ if (fc.contains("(")) {
+ int start = fc.find("("), end = fc.find(")");
+ td.first = fc.takeMid(start + 1, end - start - 1).trim();
+ if (td.first.left(1) == "*") {td.first.cutLeft(1).trim(); fc.insert(start + 1, "*");}
+ td.second = fc.trim();
+ } else {
+ td.first = fc.takeMid(fc.findLast(" ")).trim();
+ td.second = fc.trim();
+ }
+ //piCout << "found typedef" << td;
+ return td;
+}
+
+
+bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
+ if (fc.trim().isEmpty()) return true;
+ if (fc.find("operator") >= 0) return true;
+ tmp_temp.clear();
+ //piCout << "parse member" << fc;
+ int ts = fc.find("<"), te = 0;
+ PIString ctemp, crepl;
+ while (ts >= 0) {
+ ctemp = fc.mid(ts).takeRange("<", ">");
+ if (ctemp.isEmpty()) {te = ts + 1; ts = fc.find("<", te); continue;}
+ crepl = "$" + PIString::fromNumber(tmp_temp.size_s()).expandLeftTo(3, "0");
+ fc.replace(ts, ctemp.size_s() + 2, crepl);
+ tmp_temp[crepl] = "<" + ctemp + ">";
+ ts = fc.find("<", te);
+ }
+ fc.replaceAll("\n", " ").replaceAll("\t", " ").replaceAll(" ", " ").replaceAll(", ", ",");
+ PIStringList tl, al;
+ Member me;
+ //piCout << fc;
+ if (fc.contains("(")) {
+ fc.cutRight(fc.size_s() - fc.findLast(")") - 1);
+ te = fc.find("(");
+ //piCout << fc;
+ for (ts = te - 1; ts >= 0; --ts)
+ if (!_isCChar(fc[ts]) && !(fc[ts].isDigit())) break;
+ //piCout << "takeMid" << ts + 1 << te - ts - 1;
+ me.name = fc.takeMid(ts + 1, te - ts - 1);
+ if (me.name == parent->name) return true;
+ me.arguments_full = fc.takeMid(ts + 2).cutRight(1).split(",");
+ me.type = fc.cutRight(1).trim();
+ me.visibility = cur_def_vis;
+ if (me.type.find("inline ") >= 0) {
+ me.attributes |= Inline;
+ me.type.removeAll("inline ");
+ }
+ if (me.type.find("static ") >= 0) {
+ me.attributes |= Static;
+ me.type.removeAll("static ");
+ }
+ if (me.type.find("virtual ") >= 0) {
+ me.attributes |= Virtual;
+ me.type.removeAll("virtual ");
+ }
+ normalizeEntityNamespace(me.type);
+ int i = 0;
+ //piCout << me.arguments_full;
+ piForeach (PIString & a, me.arguments_full)
+ if ((i = a.find("=")) > 0)
+ a.cutRight(a.size_s() - i).trim();
+ for (int j = 0; j < me.arguments_full.size_s(); ++j)
+ if (me.arguments_full[j] == "void") {
+ me.arguments_full.remove(j);
+ --j;
+ }
+ me.arguments_type = me.arguments_full;
+ piForeach (PIString & a, me.arguments_type) {
+ crepl.clear();
+ if (a.contains("["))
+ crepl = a.takeMid(a.find("["), a.findLast("]") - a.find("[") + 1);
+ for (ts = a.size_s() - 1; ts >= 0; --ts)
+ if (!_isCChar(a[ts]) && !(a[ts].isDigit())) break;
+ a.cutRight(a.size_s() - ts - 1);
+ normalizeEntityNamespace(a);
+ a += crepl;
+ a.trim();
+ }
+ restoreTmpTemp(&me);
+ //piCout << "func" << me.type << me.name << me.arguments_full << me.arguments_type;
+ parent->functions << me;
+ } else {
+ if (fc.endsWith(";")) fc.cutRight(1);
+ if (fc.startsWith("using") || !(fc.contains(' ') || fc.contains('\t') || fc.contains('\n'))) return true;
+ tl = fc.split(",");
+ //piCout << "\tmember" << fc;
+ if (tl.isEmpty()) return true;
+ bool vn = true;
+ ctemp = tl.front();
+ for (ts = ctemp.size_s() - 1; ts > 0; --ts) {
+ if (vn) {if (!_isCChar(ctemp[ts]) && !ctemp[ts].isDigit() && ctemp[ts] != '[' && ctemp[ts] != ']') vn = false;}
+ else {if (_isCChar(ctemp[ts]) || ctemp[ts].isDigit()) break;}
+ }
+ me.type = ctemp.takeLeft(ts + 1);
+ me.visibility = cur_def_vis;
+ restoreTmpTemp(&me);
+ PIString type = " " + me.type;
+ if (type.find(" const ") >= 0) {
+ me.attributes |= Const;
+ type.replaceAll(" const ", " ");
+ }
+ if (type.find(" static ") >= 0) {
+ me.attributes |= Static;
+ type.replaceAll(" static ", " ");
+ }
+ if (type.find(" mutable ") >= 0) {
+ me.attributes |= Mutable;
+ type.replaceAll(" mutable ", " ");
+ }
+ if (type.find(" volatile ") >= 0) {
+ me.attributes |= Volatile;
+ type.replaceAll(" volatile ", " ");
+ }
+ if (type.find(" extern ") >= 0) {
+ me.attributes |= Extern;
+ type.replaceAll(" extern ", " ");
+ }
+ type.trim();
+ normalizeEntityNamespace(type);
+ tl[0] = ctemp.trim();
+ piForeachC (PIString & v, tl) {
+ crepl.clear();
+ me.name = v.trimmed();
+ me.type = type;
+ if (me.name.isEmpty()) continue;
+ if (me.name.contains("["))
+ crepl = me.name.takeMid(me.name.find("["), me.name.findLast("]") - me.name.find("[") + 1);
+ while (!me.name.isEmpty()) {
+ if (me.name.front() == "*" || me.name.front() == "&") {
+ me.type += me.name.takeLeft(1);
+ me.name.trim();
+ } else break;
+ }
+ me.is_type_ptr = (me.type.right(1) == "]" || me.type.right(1) == "*");
+ me.type += crepl;
+ //piCout << "var" << me.type << me.name << me.is_const << me.is_static;
+ parent->members << me;
+ }
+ }
+ //piCout << "parse member" << fc;
+ return true;
+}
+
+
+void PICodeParser::normalizeEntityNamespace(PIString & n) {
+ PIString suff, pref;
+ for (int i = n.size_s() - 1; i > 0; --i)
+ if (_isCChar(n[i]) || n[i].isDigit()) {
+ suff = n.right(n.size_s() - i - 1);
+ n.cutRight(suff.size_s());
+ break;
+ }
+ n.push_front(" ");
+ if (n.find(" static ") >= 0) {n.replaceAll(" static ", ""); pref += "static ";}
+ if (n.find(" const ") >= 0) {n.replaceAll(" const ", ""); pref += "const ";}
+ if (n.find(" mutable ") >= 0) {n.replaceAll(" mutable ", ""); pref += "mutable ";}
+ if (n.find(" volatile ") >= 0) {n.replaceAll(" volatile ", ""); pref += "volatile ";}
+ n.trim();
+ int f = 0;
+ piForeachC (Entity * e, entities) {
+ if (e->name == n) {
+ n = (pref + n + suff).trim();
+ return;
+ }
+ if ((f = e->name.find(n)) >= 0)
+ if (e->name.mid(f - 1, 1) == ":")
+ if (e->name.find(cur_namespace) >= 0) {
+ n = pref + e->name + suff;
+ return;
+ }
+ }
+ piForeachC (Enum & e, enums)
+ if ((f = e.name.find(n)) >= 0)
+ if (e.name.mid(f - 1, 1) == ":")
+ if (e.name.find(cur_namespace) >= 0) {
+ //piCout << "change" << n << "to" << e.name + suff;
+ n = pref + e.name + suff;
+ return;
+ }
+ piForeachC (Typedef & e, typedefs)
+ if ((f = e.first.find(n)) >= 0)
+ if (e.first.mid(f - 1, 1) == ":")
+ if (e.first.find(cur_namespace) >= 0) {
+ //piCout << "change" << n << "to" << e.name + suff;
+ n = pref + e.first + suff;
+ return;
+ }
+ n = (pref + n + suff).trim();
+}
+
+
+void PICodeParser::restoreTmpTemp(Member * e) {
+ int i = 0;
+ piForeach (PIString & a, e->arguments_full) {
+ while ((i = a.find("$")) >= 0)
+ a.replace(i, 4, tmp_temp[a.mid(i, 4)]);
+ }
+ piForeach (PIString & a, e->arguments_type) {
+ while ((i = a.find("$")) >= 0)
+ a.replace(i, 4, tmp_temp[a.mid(i, 4)]);
+ }
+ while ((i = e->type.find("$")) >= 0)
+ e->type.replace(i, 4, tmp_temp[e->type.mid(i, 4)]);
+}
+
+
+bool PICodeParser::macroCondition(const PIString & mif, PIString mifcond) {
+ //piCout << "macroCondition" << mif << mifcond;
+ if (mif == "ifdef") return isDefineExists(mifcond);
+ if (mif == "ifndef") return !isDefineExists(mifcond);
+ if (mif == "if" || mif == "elif") {
+ mifcond.removeAll(" ").removeAll("\t");
+ return procMacrosCond(mifcond) > 0.;
+ }
+ return false;
+}
+
+
+double PICodeParser::procMacrosCond(PIString fc) {
+ bool neg = false, first = true, br = false;
+ double ret = 0., brv = 0.;
+ int oper = 0, ps = -1;
+ char cc, nc;
+ PIString ce;
+ fc.removeAll("defined");
+ //piCout << "procMacrosCond" << fc;
+ while (!fc.isEmpty()) {
+ cc = fc[0].toAscii();
+ nc = (fc.size() > 1 ? fc[1].toAscii() : 0);
+ if (cc == '!') {neg = true; fc.pop_front(); continue;}
+ if (cc == '(') {br = true; brv = procMacrosCond(fc.takeRange('(', ')'));}
+ if (cc == '&' && nc == '&') {fc.remove(0, 2); oper = 1; continue;}
+ if (cc == '|' && nc == '|') {fc.remove(0, 2); oper = 2; continue;}
+ if (!br) {
+ ce = fc.takeCWord();
+ if (ce.isEmpty()) ce = fc.takeNumber();
+ }
+ if (first) {
+ first = false;
+ ret = br ? brv : defineValue(ce);
+ if (neg) ret = -ret;
+ } else {
+ //piCout << "oper" << oper << "with" << ce;
+ if (!br) brv = defineValue(ce);
+ switch (oper) {
+ case 1: ret = ret && (neg ? -brv : brv); break;
+ case 2: ret = ret || (neg ? -brv : brv); break;
+ }
+ }
+ if (ps == fc.size_s()) fc.cutLeft(1);
+ ps = fc.size_s();
+ br = neg = false;
+ }
+ //piCout << "return" << ret;
+ return ret;
+}
+
+
+bool PICodeParser::isDefineExists(const PIString & dn) {
+ piForeachC (Define & d, defines) {
+ if (d.first == dn)
+ return true;
+ }
+ return false;
+}
+
+
+double PICodeParser::defineValue(const PIString & dn) {
+ piForeachC (Define & d, defines) {
+ if (d.first == dn)
+ return d.second.isEmpty() ? 1. : d.second.toDouble();
+ }
+ return dn.toDouble();
+}
+
+
+PICodeParser::Entity * PICodeParser::findEntityByName(const PIString & en) {
+ piForeach (Entity * e, entities)
+ if (e->name == en)
+ return e;
+ return 0;
+}
+
+
+bool PICodeParser::isDeclaration(const PIString & fc, int start, int * end) {
+ int dind = fc.find("{", start), find = fc.find(";", start);
+ //piCout << "isDeclaration" << dind << find;
+ if (dind < 0 && find < 0) {if (end) *end = -1; return true;}
+ if (dind < 0 || find < dind) {if (end) *end = find; return true;}
+ if (end) *end = dind;
+ return false;
+}
+
+
+bool PICodeParser::isMainFile(const PIString & fc) {
+ int si = 0;
+ while (si >= 0) {
+ int csi = fc.find(" main", si);
+ if (csi < 0) csi = fc.find("\tmain", si);
+ if (csi < 0) csi = fc.find("\nmain", si);
+ if (csi < 0) return false;
+ si = csi;
+ int fi = fc.find("(", si + 5);
+ if (fi < 0) return false;
+ if (fi - si < 10) {
+ PIString ms(fc.mid(si, fi - si + 1));
+ ms.removeAll(" ").removeAll("\t").removeAll("\n");
+ if (ms == "main(") return true;
+ }
+ si += 5;
+ }
+ return false;
+}
+
+
+PIString PICodeParser::procMacros(PIString fc) {
+ if (fc.isEmpty()) return PIString();
+ int ifcnt = 0;
+ bool grab = false, skip = false, cond_ok = false;
+ PIString pfc, nfc, line, mif, mifcond;
+ //piCout << "procMacros\n<******" << fc << "\n******>";
+ fc += "\n";
+ while (!fc.isEmpty()) {
+ line = fc.takeLine().trimmed();
+ if (line.left(1) == "#") {
+ mifcond = line.mid(1);
+ mif = mifcond.takeCWord();
+ //piCout << "mif mifcond" << mif << mifcond << ifcnt;
+ if (skip || grab) {
+ if (mif.left(2) == "if") ifcnt++;
+ if (mif.left(5) == "endif") {
+ if (ifcnt > 0) ifcnt--;
+ else {
+ //piCout << "main endif" << skip << grab;
+ if (grab) pfc << procMacros(nfc);
+ skip = grab = false;
+ continue;
+ }
+ }
+ if (mif.left(4) == "elif" && ifcnt == 0) {
+ //piCout << "main elif" << skip << grab << cond_ok;
+ if (cond_ok) {
+ if (grab) {
+ pfc << procMacros(nfc);
+ skip = true; grab = false;
+ }
+ continue;
+ }
+ if (skip) {
+ //piCout << "check elif" << skip << grab << cond_ok;
+ if (!macroCondition(mif, mifcond.trimmed())) continue;
+ //piCout << "check elif ok";
+ skip = false; grab = cond_ok = true;
+ continue;
+ }
+ continue;
+ }
+ if (mif.left(4) == "else" && ifcnt == 0) {
+ //piCout << "main else" << skip << grab;
+ if (grab) pfc << procMacros(nfc);
+ if (skip && !cond_ok) {skip = false; grab = true;}
+ else {skip = true; grab = false;}
+ continue;
+ }
+ if (grab) nfc << line << "\n";
+ continue;
+ }
+ if (mif.left(2) == "if") {
+ //piCout << "main if";
+ skip = grab = cond_ok = false;
+ if (macroCondition(mif, mifcond.trimmed())) grab = cond_ok = true;
+ else skip = true;
+ ifcnt = 0;
+ nfc.clear();
+ } else {
+ if (!parseDirective(line.cutLeft(1).trim()))
+ ;//return false; /// WARNING
+ }
+ } else {
+ if (grab) nfc << line << "\n";
+ else if (!skip) pfc << line << "\n";
+ }
+ }
+ return pfc;
+}
+
+
+bool PICodeParser::parseDirective(PIString d) {
+ if (d.isEmpty()) return true;
+ PIString dname = d.takeCWord();
+ //piCout << "parseDirective" << d;
+ if (dname == "include") {
+ d.replaceAll("<", "\"").replaceAll(">", "\"");
+ PIString cf = cur_file, ifc = d.takeRange("\"", "\"");
+ if (with_includes) {
+ bool ret = parseFileInternal(ifc, with_includes);
+ cur_file = cf;
+ return ret;
+ }
+ }
+ if (dname == "define") {
+ PIString mname = d.takeCWord();
+ if (d.left(1) == "(") { // macro
+ PIStringList args = d.takeRange("(", ")").split(",").trim();
+ macros << Macro(mname, d.trim(), args);
+ } else { // define
+ d.trim();
+ //if (mname == d) d.clear();
+ defines << Define(mname, d);
+ evaluator.setVariable(mname, complexd_1);
+ }
+ return true;
+ }
+ if (dname == "undef") {
+ PIString mname = d.takeCWord();
+ for (int i = 0; i < defines.size_s(); ++i)
+ if (defines[i].first == mname) {defines.remove(i); --i;}
+ return true;
+ }
+ return true;
+}
diff --git a/src/code/picodeparser.h b/src/code/picodeparser.h
new file mode 100755
index 00000000..133361ca
--- /dev/null
+++ b/src/code/picodeparser.h
@@ -0,0 +1,162 @@
+/*! \file picodeparser.h
+ * \brief C++ code parser
+*/
+/*
+ PIP - Platform Independent Primitives
+ C++ code parser
+ Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+
+#ifndef PICODEPARSER_H
+#define PICODEPARSER_H
+
+#include "pifile.h"
+#include "pievaluator.h"
+
+inline bool _isCChar(const PIChar & c) {return (c.isAlpha() || (c.toAscii() == '_'));}
+inline bool _isCChar(const PIString & c) {if (c.isEmpty()) return false; return _isCChar(c[0]);}
+
+class PIP_EXPORT PICodeParser {
+public:
+ PICodeParser();
+
+ enum PIP_EXPORT Visibility {Global, Public, Protected, Private};
+ enum PIP_EXPORT Attribute {
+ NoAttributes = 0x0,
+ Const = 0x01,
+ Static = 0x02,
+ Mutable = 0x04,
+ Volatile = 0x08,
+ Inline = 0x10,
+ Virtual = 0x20,
+ Extern = 0x40
+ };
+
+ typedef PIFlags Attributes;
+ typedef PIPair Define;
+ typedef PIPair Typedef;
+ typedef PIPair Enumerator;
+
+ struct PIP_EXPORT Macro {
+ Macro(const PIString & n = PIString(), const PIString & v = PIString(), const PIStringList & a = PIStringList()) {
+ name = n;
+ value = v;
+ args = a;
+ }
+ PIString expand(PIString args_, bool * ok = 0) const;
+ PIString name;
+ PIString value;
+ PIStringList args;
+ };
+
+ struct PIP_EXPORT Member {
+ Member() {
+ visibility = Global;
+ size = 0;
+ is_type_ptr = false;
+ attributes = NoAttributes;
+ }
+ PIString type;
+ PIString name;
+ PIStringList arguments_full;
+ PIStringList arguments_type;
+ Visibility visibility;
+ Attributes attributes;
+ bool is_type_ptr;
+ int size;
+ };
+
+ struct PIP_EXPORT Entity {
+ Entity() {
+ visibility = Global;
+ size = 0;
+ }
+ PIString type;
+ PIString name;
+ PIString file;
+ Visibility visibility;
+ int size;
+ PIVector parents;
+ //PIVector children;
+ PIVector functions;
+ PIVector members;
+ PIVector typedefs;
+ };
+
+ struct PIP_EXPORT Enum {
+ Enum(const PIString & n = PIString()) {
+ name = n;
+ }
+ PIString name;
+ PIVector members;
+ };
+
+ void parseFile(const PIString & file, bool follow_includes = true);
+ void parseFiles(const PIStringList & files, bool follow_includes = true);
+
+ void includeDirectory(const PIString & dir) {includes << dir;}
+ void addDefine(const PIString & def_name, const PIString & def_value) {custom_defines << Define(def_name, def_value);}
+ bool isEnum(const PIString & name);
+ Entity * findEntityByName(const PIString & en);
+ PIStringList parsedFiles() const {return PIStringList(proc_files.toVector());}
+ PIString mainFile() const {return main_file;}
+ const PICodeParser::Entity * global() const {return &root_;}
+
+ int macrosSubstitutionMaxIterations() const {return macros_iter;}
+ void setMacrosSubstitutionMaxIterations(int value) {macros_iter = value;}
+
+ PIVector defines, custom_defines;
+ PIVector macros;
+ PIVector enums;
+ PIVector typedefs;
+ PIVector entities;
+
+private:
+ void clear();
+ bool parseFileInternal(const PIString & file, bool follow_includes);
+ bool parseFileContent(PIString & fc, bool main);
+ bool parseDirective(PIString d);
+ Entity * parseClassDeclaration(const PIString & fc);
+ PIString parseClass(PIString & fc);
+ bool parseEnum(const PIString & name, PIString fc);
+ Typedef parseTypedef(PIString fc);
+ bool parseMember(Entity * parent, PIString & fc);
+ void restoreTmpTemp(Member * e);
+ bool macroCondition(const PIString & mif, PIString mifcond);
+ bool isDefineExists(const PIString & dn);
+ double defineValue(const PIString & dn);
+ PIString procMacros(PIString fc);
+ double procMacrosCond(PIString fc);
+ bool isDeclaration(const PIString & fc, int start, int * end);
+ bool isMainFile(const PIString & fc);
+ void normalizeEntityNamespace(PIString & n);
+
+ int macros_iter;
+ bool with_includes;
+ PIEvaluator evaluator;
+ //PIVector tree;
+ PISet proc_files;
+ PIString cur_file, main_file;
+ PIStringList includes;
+ Entity root_;
+ Visibility cur_def_vis;
+ PIString cur_namespace;
+ PIMap tmp_temp;
+
+};
+
+#endif // PICODEPARSER_H
diff --git a/src/containers/picontainers.cpp b/src/containers/picontainers.cpp
new file mode 100755
index 00000000..0c4dd3a0
--- /dev/null
+++ b/src/containers/picontainers.cpp
@@ -0,0 +1,175 @@
+/*
+ PIP - Platform Independent Primitives
+ Generic containers
+ Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+// * This class based on std::vector, expanding his functionality
+
+/** \class PIVector
+ * \brief Dynamic array of any type
+ * \details This class used to store dynamic array of any
+ * type of data. In memory data stored linear. You can insert
+ * item in any place of remove some items from any place.
+ * For quick add elements this is stream operator <<.
+
+ * \fn PIVector::PIVector();
+ * Contructs an empty vector
+
+ * \fn PIVector::PIVector(ullong size, const Type & value = Type());
+ * \brief Contructs vector with size "size" filled elements "value"
+ * \details Example: \snippet picontainers.cpp PIVector::PIVector
+
+ * \fn const Type & PIVector::at(ullong index) const;
+ * \brief Read-only access to element by index "index"
+ * \details Example: \snippet picontainers.cpp PIVector::at_c
+ * \sa \a operator[]
+
+ * \fn Type & PIVector::at(ullong index);
+ * \brief Full access to element by index "index"
+ * \details Example: \snippet picontainers.cpp PIVector::at
+ * \sa \a operator[]
+
+ * \fn const Type * PIVector::data(ullong index = 0) const;
+ * \brief Read-only pointer to element by index "index"
+ * \details Example: \snippet picontainers.cpp PIVector::data_c
+
+ * \fn Type * PIVector::data(ullong index = 0);
+ * \brief Pointer to element by index "index"
+ * \details Example: \snippet picontainers.cpp PIVector::data
+
+ * \fn ullong PIVector::size() const;
+ * \brief Elements count
+
+ * \fn int PIVector::size_s() const;
+ * \brief Elements count
+
+ * \fn bool PIVector::isEmpty() const;
+ * \brief Return \c "true" if vector is empty, i.e. size = 0
+
+ * \fn bool PIVector::has(const Type & t) const;
+
+ * \fn bool PIVector::contains(const Type & v) const;
+ * \brief Return \c "true" if vector has at least one element equal "t"
+
+ * \fn int PIVector::etries(const Type & t) const;
+ * \brief Return how many times element "t" appears in vector
+
+ * \fn static int PIVector::compare_func(const Type * t0, const Type * t1);
+ * \brief Standard compare function for type "Type". Return 0 if t0 = t1, -1 if t0 < t1 and 1 if t0 > t1.
+
+ * \fn void PIVector::resize(ullong size, const Type & new_type = Type());
+ * \brief Resize vector to size "size"
+ * \details Elements removed from end of vector if new size < old size, or added new elements = "new_type" if new size > old size.\n
+ * Example: \snippet picontainers.cpp PIVector::resize
+ * \sa \a size(), \a clear()
+
+ * \fn PIVector & PIVector::enlarge(ullong size);
+ * \brief Increase vector size with "size" elements
+
+ * \fn void PIVector::clear();
+ * \brief Clear vector. Equivalent to call "resize(0)"
+
+ * \fn PIVector & PIVector::sort(CompareFunc compare = compare_func);
+ * \brief Sort vector using quick sort algorithm and standard compare function
+ * \details Example: \snippet picontainers.cpp PIVector::sort_0
+ * With custom compare function: \snippet picontainers.cpp PIVector::sort_1
+
+ * \fn PIVector & PIVector::fill(const Type & t);
+ * \brief Fill vector with elements "t" leave size is unchanged and return reference to vector
+ * \details Example: \snippet picontainers.cpp PIVector::fill
+
+ * \fn Type & PIVector::back();
+ * \brief Last element of the vector
+
+ * \fn const Type & PIVector::back() const;
+ * \brief Last element of the vector
+
+ * \fn Type & PIVector::front();
+ * \brief First element of the vector
+
+ * \fn const Type & PIVector::front() const;
+ * \brief First element of the vector
+
+ * \fn PIVector & PIVector::push_back(const Type & t);
+ * \brief Add new element "t" at the end of vector and return reference to vector
+
+ * \fn PIVector & PIVector::push_front(const Type & t);
+ * \brief Add new element "t" at the beginning of vector and return reference to vector
+
+ * \fn PIVector & PIVector::pop_back();
+ * \brief Remove one element from the end of vector and return reference to vector
+
+ * \fn PIVector & PIVector::pop_front();
+ * \brief Remove one element from the beginning of vector and return reference to vector
+
+ * \fn Type PIVector::take_back();
+ * \brief Remove one element from the end of vector and return it
+
+ * \fn Type PIVector::take_front();
+ * \brief Remove one element from the beginning of vector and return it
+
+ * \fn PIVector & PIVector::remove(uint index);
+ * \brief Remove one element by index "index" and return reference to vector
+ * \details Example: \snippet picontainers.cpp PIVector::remove_0
+ * \sa \a removeOne(), \a removeAll()
+
+ * \fn PIVector & PIVector::remove(uint index, uint count);
+ * \brief Remove "count" elements by first index "index" and return reference to vector
+ * \details Example: \snippet picontainers.cpp PIVector::remove_1
+ * \sa \a removeOne(), \a removeAll()
+
+ * \fn PIVector & PIVector::removeOne(const Type & v);
+ * \brief Remove no more than one element equal "v" and return reference to vector
+ * \details Example: \snippet picontainers.cpp PIVector::removeOne
+ * \sa \a remove(), \a removeAll()
+
+ * \fn PIVector & PIVector::removeAll(const Type & v);
+ * \brief Remove all elements equal "v" and return reference to vector
+ * \details Example: \snippet picontainers.cpp PIVector::removeAll
+ * \sa \a remove(), \a removeOne()
+
+ * \fn PIVector & PIVector::insert(uint pos, const Type & t);
+ * \brief Insert element "t" after index "pos" and return reference to vector
+ * \details Example: \snippet picontainers.cpp PIVector::insert_0
+
+ * \fn PIVector & PIVector::insert(uint pos, const PIVector & t);
+ * \brief Insert other vector "t" after index "pos" and return reference to vector
+ * \details Example: \snippet picontainers.cpp PIVector::insert_1
+
+ * \fn Type & PIVector::operator [](uint index);
+ * \brief Full access to element by index "index"
+ * \details Example: \snippet picontainers.cpp PIVector::()
+ * \sa \a at()
+
+ * \fn const Type & PIVector::operator [](uint index) const;
+ * \brief Read-only access to element by index "index"
+ * \details Example: \snippet picontainers.cpp PIVector::()_c
+ * \sa \a at()
+
+ * \fn PIVector & PIVector::operator <<(const Type & t);
+ * \brief Add new element "t" at the end of vector and return reference to vector
+
+ * \fn PIVector & PIVector::operator <<(const PIVector & t);
+ * \brief Add vector "t" at the end of vector and return reference to vector
+
+ * \fn bool PIVector::operator ==(const PIVector & t);
+ * \brief Compare with vector "t"
+
+ * \fn bool PIVector::operator !=(const PIVector & t);
+ * \brief Compare with vector "t"
+
+ * */
diff --git a/src/containers/picontainers.h b/src/containers/picontainers.h
new file mode 100755
index 00000000..6be2bf61
--- /dev/null
+++ b/src/containers/picontainers.h
@@ -0,0 +1,286 @@
+/*! \file picontainers.h
+ * \brief Generic containers
+ *
+ * This file declare all containers and useful macros
+ * to use them
+*/
+/*
+ PIP - Platform Independent Primitives
+ Generic containers
+ Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifndef PICONTAINERS_H
+#define PICONTAINERS_H
+
+#include "picout.h"
+
+template
+class PIP_EXPORT PIPair {
+public:
+ PIPair() {first = Type0(); second = Type1();}
+ PIPair(const Type0 & value0, const Type1 & value1) {first = value0; second = value1;}
+ Type0 first;
+ Type1 second;
+};
+template
+inline bool operator <(const PIPair & value0, const PIPair & value1) {return value0.first < value1.first;}
+template
+inline bool operator ==(const PIPair & value0, const PIPair & value1) {return (value0.first == value1.first) && (value0.second == value1.second);}
+template
+inline bool operator !=(const PIPair & value0, const PIPair & value1) {return (value0.first != value1.first) || (value0.second != value1.second);}
+template
+inline std::ostream & operator <<(std::ostream & s, const PIPair & v) {s << "(" << v.first << ", " << v.second << ")"; return s;}
+template
+inline PICout operator <<(PICout s, const PIPair & v) {s.space(); s.setControl(0, true); s << "(" << v.first << ", " << v.second << ")"; s.restoreControl(); return s;}
+
+#include "pivector.h"
+#include "pistack.h"
+#include "piqueue.h"
+#include "pideque.h"
+#include "pimap.h"
+#include "piset.h"
+
+#ifdef DOXYGEN
+
+/*!\brief Macro for iterate any container
+ * \details Use this macros instead of standard "for"
+ * to get read/write access to each element of container.
+ * Pass direction is direct \n
+ * Example: \snippet picontainers.cpp foreach
+ */
+# define piForeach(i,c)
+
+/*!\brief Macro for iterate any container only for read
+ * \details Use this macros instead of standard "for"
+ * to get read access to each element of container.
+ * Pass direction is direct \n
+ * Example: \snippet picontainers.cpp foreachC
+ */
+# define piForeachC(i,c)
+
+/*!\brief Macro for iterate any container with reverse direction
+ * \details Use this macros instead of standard "for"
+ * to get read/write access to each element of container.
+ * Pass direction is reverse \n
+ * Example: \snippet picontainers.cpp foreachR
+ */
+# define piForeachR(i,c)
+
+/*!\brief Macro for iterate any container only for read with reverse direction
+ * \details Use this macros instead of standard "for"
+ * to get read access to each element of container.
+ * Pass direction is reverse \n
+ * Example: \snippet picontainers.cpp foreachCR
+ */
+# define piForeachCR(i,c)
+
+/*!\brief Macro for break from any piForeach* loop
+ * \details \warning C++ ordinary "break" doesn`t work inside piForeach*
+ * loops! Always use "piBreak" instead!
+ */
+# define piBreak
+
+#else
+
+# define piBreak {_for._end = true; break;}
+
+# define piForTimes(c) for(int _i##c = 0; _i##c < c; ++_i##c)
+
+#ifdef CC_GCC
+
+template
+class _PIForeach {
+public:
+ _PIForeach(Type & t): _t(t), _break(false), _end(false) {_it = _t.begin();}
+ typename Type::value_type _var;
+ typename Type::iterator _it;
+ Type & _t;
+ bool _break, _end;
+ inline bool isEnd() {return _it == _t.end();}
+ inline void operator ++() {if (_end) _it = _t.end(); else _it++; _break = false;}
+};
+
+template
+class _PIForeachR {
+public:
+ _PIForeachR(Type & t): _t(t), _break(false), _end(false) {_rit = _t.rbegin();}
+ typename Type::value_type _var;
+ typename Type::reverse_iterator _rit;
+ Type & _t;
+ bool _break, _end;
+ inline bool isEnd() {return _rit == _t.rend();}
+ inline void operator ++() {if (_end) _rit = _t.rend(); else _rit++; _break = false;}
+};
+
+template
+class _PIForeachC {
+public:
+ _PIForeachC(const Type & t): _t(t), _break(false), _end(false) {_it = _t.begin();}
+ typename Type::value_type _var;
+ typename Type::const_iterator _it;
+ const Type & _t;
+ bool _break, _end;
+ inline bool isEnd() {return _it == _t.end();}
+ inline void operator ++() {if (_end) _it = _t.end(); else _it++; _break = false;}
+};
+
+template
+class _PIForeachCR {
+public:
+ _PIForeachCR(const Type & t): _t(t), _break(false), _end(false) {_rit = _t.rbegin();}
+ typename Type::value_type _var;
+ typename Type::const_reverse_iterator _rit;
+ const Type & _t;
+ bool _break, _end;
+ inline bool isEnd() {return _rit == _t.rend();}
+ inline void operator ++() {if (_end) _rit = _t.rend(); else _rit++; _break = false;}
+};
+
+#define piForeach(i,c) for(_PIForeach _for(c); !_for.isEnd(); ++_for) \
+ for(i(*_for._it); !_for._break; _for._break = true)
+#define piForeachR(i,c) for(_PIForeachR _for(c); !_for.isEnd(); ++_for) \
+ for(i(*_for._rit); !_for._break; _for._break = true)
+#define piForeachA(i,c) for(_PIForeach _for(c); !_for.isEnd(); ++_for) \
+ for(typeof(_for._var) & i(*_for._it); !_for._break; _for._break = true)
+#define piForeachAR(i,c) for(_PIForeachR _for(c); !_for.isEnd(); ++_for) \
+ for(typeof(_for._var) & i(*_for._rit); !_for._break; _for._break = true)
+#define piForeachC(i,c) for(_PIForeachC _for(c); !_for.isEnd(); ++_for) \
+ for(const i(*_for._it); !_for._break; _for._break = true)
+#define piForeachCR(i,c) for(_PIForeachCR _for(c); !_for.isEnd(); ++_for) \
+ for(const i(*_for._rit); !_for._break; _for._break = true)
+#define piForeachCA(i,c) for(_PIForeachC _for(c); !_for.isEnd(); ++_for) \
+ for(const typeof(_for._var) & i(*_for._it); !_for._break; _for._break = true)
+#define piForeachCAR(i,c) for(_PIForeachCR _for(c); !_for.isEnd(); ++_for) \
+ for(const typeof(_for._var) & i(*_for._rit); !_for._break; _for._break = true)
+
+#define piForeachRA piForeachAR
+#define piForeachAC piForeachCA
+#define piForeachCRA piForeachCAR
+#define piForeachARC piForeachCAR
+#define piForeachACR piForeachCAR
+#define piForeachRCA piForeachCAR
+#define piForeachRAC piForeachCAR
+
+#else
+
+struct _PIForeachBase {mutable bool _break, _end;};
+
+template
+class _PIForeach: public _PIForeachBase {
+public:
+ _PIForeach(Type & t, bool i = false): _break(false), _end(false), _t(t), _inv(i) {if (_inv) _rit = _t.rbegin(); else _it = _t.begin();}
+ mutable typename Type::value_type _var;
+ mutable typename Type::iterator _it;
+ mutable typename Type::reverse_iterator _rit;
+ Type & _t;
+ bool _inv;
+ bool isEnd() {if (_inv) return _rit == _t.rend(); else return _it == _t.end();}
+ void operator ++() {if (_inv) {if (_end) _rit = _t.rend(); else _rit++;} else {if (_end) _it = _t.end(); else _it++;} _break = false;}
+};
+
+template
+class _PIForeachC: public _PIForeachBase {
+public:
+ _PIForeachC(const Type & t, bool i = false): _break(false), _end(false), _t(t), _inv(i) {if (_inv) _rit = _t.rbegin(); else _it = _t.begin();}
+ mutable typename Type::value_type _var;
+ mutable typename Type::const_iterator _it;
+ mutable typename Type::const_reverse_iterator _rit;
+ const Type & _t;
+ bool _inv;
+ bool isEnd() {if (_inv) return _rit == _t.rend(); else return _it == _t.end();}
+ void operator ++() {if (_inv) {if (_end) _rit = _t.rend(); else _rit++;} else {if (_end) _it = _t.end(); else _it++;} _break = false;}
+};
+
+template inline _PIForeach _PIForeachNew(T & t, bool i = false) {return _PIForeach(t, i);}
+template inline _PIForeach * _PIForeachCast(_PIForeachBase & c, T & ) {return static_cast<_PIForeach * >(&c);}
+
+template inline _PIForeachC _PIForeachNewC(const T & t, bool i = false) {return _PIForeachC(t, i);}
+template inline _PIForeachC * _PIForeachCastC(_PIForeachBase & c, const T & ) {return static_cast<_PIForeachC * >(&c);}
+
+#define piForeach(i,c) for(_PIForeachBase & _for = _PIForeachNew(c); !_PIForeachCast(_for, c)->isEnd(); ++(*_PIForeachCast(_for, c))) \
+ for(i = *(_PIForeachCast(_for, c)->_it); !_for._break; _for._break = true)
+#define piForeachR(i,c) for(_PIForeachBase & _for = _PIForeachNew(c, true); !_PIForeachCast(_for, c)->isEnd(); ++(*_PIForeachCast(_for, c))) \
+ for(i = *(_PIForeachCast(_for, c)->_rit); !_for._break; _for._break = true)
+#define piForeachC(i,c) for(_PIForeachBase & _for = _PIForeachNewC(c); !_PIForeachCastC(_for, c)->isEnd(); ++(*_PIForeachCastC(_for, c))) \
+ for(const i = *(_PIForeachCastC(_for, c)->_it); !_for._break; _for._break = true)
+#define piForeachCR(i,c) for(_PIForeachBase & _for = _PIForeachNewC(c, false); !_PIForeachCastC(_for, c)->isEnd(); ++(*_PIForeachCastC(_for, c))) \
+ for(const i = *(_PIForeachCastC(_for, c)->_rit); !_for._break; _for._break = true)
+
+#endif
+
+#define piForeachRC piForeachCR
+
+#endif // DOXYGEN
+
+template >
+class PIP_EXPORT PIList: public list {
+ typedef PIList _CList;
+ typedef list _stlc;
+public:
+ PIList() {piMonitor.containers++;}
+ PIList(const Type & value) {piMonitor.containers++; _stlc::resize(1, value);}
+ PIList(const Type & v0, const Type & v1) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1);}
+ PIList(const Type & v0, const Type & v1, const Type & v2) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2);}
+ PIList(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2); _stlc::push_back(v3);}
+ PIList(uint size, const Type & value = Type()) {piMonitor.containers++; _stlc::resize(size, value);}
+ ~PIList() {piMonitor.containers--;}
+ Type & operator [](uint index) {return (*this)[index];}
+ Type & operator [](uint index) const {return (*this)[index];}
+ const Type * data(uint index = 0) const {return &(*this)[index];}
+ Type * data(uint index = 0) {return &(*this)[index];}
+ int size_s() const {return static_cast(_stlc::size());}
+ bool isEmpty() const {return _stlc::empty();}
+ bool has(const Type & t) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) return true; return false;}
+ int etries(const Type & t) const {int ec = 0; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) ++ec; return ec;}
+ _CList & fill(const Type & t) {_stlc::assign(_stlc::size(), t); return *this;}
+ _CList & remove(uint index) {_stlc::erase(_stlc::begin() + index); return *this;}
+ _CList & remove(uint index, uint count) {_stlc::erase(_stlc::begin() + index, _stlc::begin() + index + count); return *this;}
+ _CList & insert(uint pos, const Type & t) {_stlc::insert(_stlc::begin() + pos, t); return *this;}
+ _CList & operator <<(const Type & t) {_stlc::push_back(t); return *this;}
+ PIVector toVector() const {PIVector v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
+};
+
+
+#ifndef PIP_CONTAINERS_STL
+
+# define __PICONTAINERS_SIMPLE_TYPE__(T) \
+__PIDEQUE_SIMPLE_TYPE__(T)\
+__PIVECTOR_SIMPLE_TYPE__(T)
+
+__PICONTAINERS_SIMPLE_TYPE__(bool)
+__PICONTAINERS_SIMPLE_TYPE__(char)
+__PICONTAINERS_SIMPLE_TYPE__(uchar)
+__PICONTAINERS_SIMPLE_TYPE__(short)
+__PICONTAINERS_SIMPLE_TYPE__(ushort)
+__PICONTAINERS_SIMPLE_TYPE__(int)
+__PICONTAINERS_SIMPLE_TYPE__(uint)
+__PICONTAINERS_SIMPLE_TYPE__(long)
+__PICONTAINERS_SIMPLE_TYPE__(ulong)
+__PICONTAINERS_SIMPLE_TYPE__(llong)
+__PICONTAINERS_SIMPLE_TYPE__(ullong)
+__PICONTAINERS_SIMPLE_TYPE__(float)
+__PICONTAINERS_SIMPLE_TYPE__(double)
+__PICONTAINERS_SIMPLE_TYPE__(ldouble)
+__PICONTAINERS_SIMPLE_TYPE__(complexi)
+__PICONTAINERS_SIMPLE_TYPE__(complexf)
+__PICONTAINERS_SIMPLE_TYPE__(complexd)
+__PICONTAINERS_SIMPLE_TYPE__(complexld)
+
+#endif
+
+
+#endif // PICONTAINERS_H
diff --git a/src/containers/pideque.h b/src/containers/pideque.h
new file mode 100755
index 00000000..c92e112c
--- /dev/null
+++ b/src/containers/pideque.h
@@ -0,0 +1,480 @@
+/*! \file pideque.h
+ * \brief Dynamic array of any type
+ *
+ * This file declares PIDeque
+*/
+/*
+ PIP - Platform Independent Primitives
+ Dynamic array of any type
+ Copyright (C) 2014 Ivan Pelipenko peri4ko@gmail.com
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifndef PIDEQUE_H
+#define PIDEQUE_H
+
+#include "piincludes.h"
+
+
+#if !defined(PIP_CONTAINERS_STL) || defined(DOXYGEN)
+
+
+template
+class PIDeque {
+public:
+ PIDeque(): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
+ //printf("new vector 1 %p (%s) ... !{\n", this, typeid(T).name());
+ //printf("(s=%d, d=%p) }!\n", int(pid_size), pid_data);
+ }
+ PIDeque(const PIDeque & other): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
+ //printf("new vector 2 %p (%s) ... !{\n", this, typeid(T).name());
+ alloc(other.pid_size, true);
+ newT(pid_data + pid_start, other.pid_data + other.pid_start, pid_size);
+ //printf("(s=%d, d=%p) }!\n", int(pid_size), pid_data);
+ }
+ PIDeque(const T * data, size_t size): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
+ //printf("new vector 2 %p (%s) ... !{\n", this, typeid(T).name());
+ alloc(size, true);
+ newT(pid_data + pid_start, data, pid_size);
+ //printf("(s=%d, d=%p) }!\n", int(pid_size), pid_data);
+ }
+ PIDeque(size_t pid_size, const T & f = T()): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
+ //printf("new vector 3 %p (%s) ... !{\n", this, typeid(T).name());
+ resize(pid_size, f);
+ //printf("(s=%d, d=%p) }!\n", int(pid_size), pid_data);
+ }
+ ~PIDeque() {
+ //printf("delete deque %p (%s) (s=%d, rs=%d, st=%d, d=%p) ... ~{\n", this, typeid(T).name(), int(pid_size), int(pid_rsize), int(pid_start), pid_data);
+ deleteT(pid_data + pid_start, pid_size);
+ dealloc();
+ //deleteRaw(pid_tdata);
+ _reset();
+ //printf("}~\n");
+ }
+
+ PIDeque & operator =(const PIDeque & other) {
+ if (this == &other) return *this;
+ deleteT(pid_data + pid_start, pid_size);
+ alloc(other.pid_size, true);
+ newT(pid_data + pid_start, other.pid_data + other.pid_start, pid_size);
+ return *this;
+ }
+
+ typedef T value_type;
+
+ class iterator {
+ friend class PIDeque;
+ private:
+ iterator(PIDeque * v, size_t p): parent(v), pos(p) {}
+ PIDeque * parent;
+ size_t pos;
+ public:
+ iterator(): parent(0) {}
+ T & operator *() {return (*parent)[pos];}
+ const T & operator *() const {return (*parent)[pos];}
+ void operator ++() {++pos;}
+ void operator ++(int) {++pos;}
+ void operator --() {--pos;}
+ void operator --(int) {--pos;}
+ bool operator ==(const iterator & it) const {return (pos == it.pos);}
+ bool operator !=(const iterator & it) const {return (pos != it.pos);}
+ };
+
+ class const_iterator {
+ friend class PIDeque;
+ private:
+ const_iterator(const PIDeque * v, size_t p): parent(v), pos(p) {}
+ const PIDeque * parent;
+ size_t pos;
+ public:
+ const_iterator(): parent(0) {}
+ //T & operator *() {return (*parent)[pos];}
+ const T & operator *() const {return (*parent)[pos];}
+ void operator ++() {++pos;}
+ void operator ++(int) {++pos;}
+ void operator --() {--pos;}
+ void operator --(int) {--pos;}
+ bool operator ==(const const_iterator & it) const {return (pos == it.pos);}
+ bool operator !=(const const_iterator & it) const {return (pos != it.pos);}
+ };
+
+ class reverse_iterator {
+ friend class PIDeque;
+ private:
+ reverse_iterator(PIDeque * v, size_t p): parent(v), pos(p) {}
+ PIDeque * parent;
+ size_t pos;
+ public:
+ reverse_iterator(): parent(0) {}
+ T & operator *() {return (*parent)[pos];}
+ const T & operator *() const {return (*parent)[pos];}
+ void operator ++() {--pos;}
+ void operator ++(int) {--pos;}
+ void operator --() {++pos;}
+ void operator --(int) {++pos;}
+ bool operator ==(const reverse_iterator & it) const {return (pos == it.pos);}
+ bool operator !=(const reverse_iterator & it) const {return (pos != it.pos);}
+ };
+
+ class const_reverse_iterator {
+ friend class PIDeque;
+ private:
+ const_reverse_iterator(const PIDeque