PIP_ADD_COUNTER now almost unique across different cpp

add PIValueTree
This commit is contained in:
2022-11-28 14:41:12 +03:00
parent ab0b6a7649
commit d3d2b4281c
6 changed files with 296 additions and 157 deletions

View File

@@ -367,9 +367,9 @@
name& operator=(const name&) = delete;
#define _PIP_ADD_COUNTER_WS(a, cnt) a##cnt
#define _PIP_ADD_COUNTER_WF(a, cnt) _PIP_ADD_COUNTER_WS(a, cnt)
#define _PIP_ADD_COUNTER(a) _PIP_ADD_COUNTER_WF(a, __COUNTER__)
#define _PIP_ADD_COUNTER_WS(a, cnt, line) a##cnt##_##line
#define _PIP_ADD_COUNTER_WF(a, cnt, line) _PIP_ADD_COUNTER_WS(a, cnt, line)
#define _PIP_ADD_COUNTER(a) _PIP_ADD_COUNTER_WF(a, __COUNTER__, __LINE__)
#define STATIC_INITIALIZER_BEGIN \

View File

@@ -57,5 +57,6 @@
#include "pitime.h"
#include "pipropertystorage.h"
#include "pivariantsimple.h"
#include "pivaluetree.h"
#endif // PITYPESMODULE_H

View File

@@ -0,0 +1,125 @@
/*
PIP - Platform Independent Primitives
Attributed values tree
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "pivaluetree.h"
//! \class PIValueTree pivaluetree.h
//! \details
//! \~english \section PIValueTree_sec0 Synopsis
//! \~russian \section PIValueTree_sec0 Краткий обзор
//! \~english
//!
//! \~russian
//!
PIValueTree::PIValueTree() {
}
PIValueTree::PIValueTree(const PIVariant & v) {
setValue(v);
}
PIValueTree::PIValueTree(const PIString & n, const PIVariant & v) {
setName(n);
setValue(v);
}
void PIValueTree::setName(const PIString & n) {
if (_is_null) return;
_name = n;
}
void PIValueTree::setComment(const PIString & c) {
if (_is_null) return;
_comment = c;
}
void PIValueTree::setValue(const PIVariant & v) {
if (_is_null) return;
_value = v;
}
bool PIValueTree::contains(const PIString & name) const {
if (_is_null) return true;
for (const auto & c: _children)
if (c.name() == name)
return true;
return false;
}
PIValueTree PIValueTree::child(const PIString & name) const {
if (_is_null) return PIValueTree();
for (const auto & c: _children)
if (c.name() == name)
return c;
return PIValueTree();
}
PIValueTree & PIValueTree::child(const PIString & name) {
if (_is_null) return nullValue();
for (auto & c: _children)
if (c.name() == name)
return c;
return nullValue();
}
PIValueTree & PIValueTree::addChild(const PIValueTree & n) {
if (_is_null) return nullValue();
for (auto & c: _children)
if (c.name() == n.name()) {
c = n;
return *this;
}
_children << n;
return *this;
}
PIValueTree & PIValueTree::addChildren(const PIVector<PIValueTree> & n) {
if (_is_null) return nullValue();
for (const auto & c: n)
addChild(c);
return *this;
}
PIValueTree & PIValueTree::remove(const PIString & name) {
if (_is_null) return nullValue();
_children.removeWhere([name](const PIValueTree & i){return i.name() == name;});
return *this;
}
PIValueTree & PIValueTree::nullValue() {
static PIValueTree ret;
ret._is_null = true;
return ret;
}

View File

@@ -0,0 +1,148 @@
/*! \file pivaluetree.h
* \ingroup Types
* \brief
* \~english Attributed values tree
* \~russian Дерево атрибутированных значений
*/
/*
PIP - Platform Independent Primitives
Attributed values tree
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIVALUETREE_H
#define PIVALUETREE_H
#include "pivariant.h"
#include "pichunkstream.h"
class PIP_EXPORT PIValueTree {
BINARY_STREAM_FRIEND(PIValueTree);
public:
PIValueTree();
PIValueTree(const PIVariant & v);
PIValueTree(const PIString & n, const PIVariant & v);
enum FlagsRole {
Standard,
Custom,
FlagsRoleCount
};
enum FlagStandard {
Hidden = 0x01,
Editable = 0x02,
Label = 0x04,
ArrayReorder = 0x1001,
ArrayResize = 0x1002,
};
static constexpr char attributeArrayType [] = "arrayType" ;
static constexpr char attributeArrayMinCount[] = "arrayMinCount";
static constexpr char attributeArrayMaxCount[] = "arrayMaxCount";
static constexpr char attributeMinimum [] = "minimum" ;
static constexpr char attributeMaximum [] = "maximum" ;
static constexpr char attributeSingleStep [] = "singleStep" ;
static constexpr char attributeDecimals [] = "decimals" ;
static constexpr char attributePrefix [] = "prefix" ;
static constexpr char attributeSuffix [] = "suffix" ;
//static constexpr char attribute[] = "";
bool isNull() const {return _is_null;}
bool isValid() const {return _value.isValid();}
const PIString & name() const {return _name;}
void setName(const PIString & n);
const PIString & comment() const {return _comment;}
void setComment(const PIString & c);
const PIVariant & value() const {return _value;}
void setValue(const PIVariant & v);
const PIVariantMap & attributes() const {return _attributes;}
PIVariantMap & attributes() {return _attributes;}
PIFlags<FlagStandard> flagsStandard() {return _flags[Standard];}
uint flags(FlagsRole role) {return _flags[role];}
const PIVector<PIValueTree> & children() const {return _children;}
bool contains(const PIString & name) const;
PIValueTree child(const PIString & name) const;
PIValueTree & child(const PIString & name);
PIValueTree & addChild(const PIValueTree & n);
PIValueTree & addChildren(const PIVector<PIValueTree> & n);
PIValueTree & remove(const PIString & name);
private:
static PIValueTree & nullValue();
PIString _name;
PIString _comment;
PIVariantMap _attributes;
PIVariant _value;
PIVector<PIValueTree> _children;
uint _flags[FlagsRoleCount] = {Editable, 0};
bool _is_null = false;
};
//! \relatesalso PIBinaryStream
//! \~english Store operator.
//! \~russian Оператор сохранения.
BINARY_STREAM_WRITE(PIValueTree) {
PIChunkStream cs;
cs.add(1, v._name)
.add(2, v._comment)
.add(3, v._attributes)
.add(4, v._value)
.add(5, v._name)
.add(6, v._children);
for (int i = 0; i < PIValueTree::FlagsRoleCount; ++i)
cs.add(100 + i, v._flags[i]);
s << cs.data();
return s;
}
//! \relatesalso PIBinaryStream
//! \~english Restore operator.
//! \~russian Оператор извлечения.
BINARY_STREAM_READ (PIValueTree) {
PIByteArray csba; s >> csba;
PIChunkStream cs(csba);
while (!cs.atEnd()) {
switch (cs.read()) {
case 1: cs.get(v._name);
case 2: cs.get(v._comment);
case 3: cs.get(v._attributes);
case 4: cs.get(v._value);
case 5: cs.get(v._name);
case 6: cs.get(v._children);
default:
if (cs.getID() >= 100 && cs.getID() < (100 + PIValueTree::FlagsRoleCount)) {
v._flags[cs.getID() - 100] = cs.getData<uint>();
}
}
}
return s;
}
#endif // PIVALUETREE_H

View File

@@ -807,6 +807,9 @@ private:
};
typedef PIMap<PIString, PIVariant> PIVariantMap;
typedef PIVector<PIVariant> PIVariantVector;
template<> inline bool PIVariant::value() const {return toBool();}
template<> inline char PIVariant::value() const {return (char)toInt();}
template<> inline uchar PIVariant::value() const {return (uchar)toInt();}
@@ -931,6 +934,8 @@ REGISTER_VARIANT(PIRectd)
REGISTER_VARIANT(PILined)
REGISTER_VARIANT(PIMathVectord)
REGISTER_VARIANT(PIMathMatrixd)
REGISTER_VARIANT(PIVariantMap);
REGISTER_VARIANT(PIVariantVector);
//! \relatesalso PIBinaryStream

168
main.cpp
View File

@@ -3,151 +3,10 @@
#include "pibytearray.h"
#include "pimathbase.h"
#include "pijson.h"
#include "piwaitevent_p.h"
#include "pivaluetree.h"
using namespace PICoutManipulators;
typedef PIMap<PIString, PIVariant> PIVariantMap;
typedef PIVector<PIVariant> PIVariantVector;
REGISTER_VARIANT(PIVariantMap);
REGISTER_VARIANT(PIVariantVector);
class PIValueTree {
public:
PIValueTree();
PIValueTree(const PIVariant & v);
PIValueTree(const PIString & n, const PIVariant & v);
enum FlagStandard {
Hidden = 0x01,
Editable = 0x02,
Label = 0x04,
ArrayReorder = 0x1001,
ArrayResize = 0x1002,
};
bool isNull() const {return _is_null;}
bool isValid() const {return _value.isValid();}
const PIString & name() const {return _name;}
void setName(const PIString & n);
const PIVariant & value() const {return _value;}
void setValue(const PIVariant & v);
const PIVector<PIValueTree> & children() const {return _children;}
const PIVariantMap & attributes() const {return _attributes;}
PIVariantMap & attributes() {return _attributes;}
PIFlags<FlagStandard> flagsStandard() {return _flags_standard;}
uint flagsCustom() {return _flags_custom;}
bool contains(const PIString & name) const;
PIValueTree child(const PIString & name) const;
PIValueTree & child(const PIString & name);
PIValueTree & insert(const PIValueTree & n);
PIValueTree & remove(const PIString & name);
private:
static PIValueTree & nullValue();
PIString _name;
PIVariantMap _attributes;
PIVariant _value;
PIVector<PIValueTree> _children;
uint _flags_standard = Editable;
uint _flags_custom = 0u;
bool _is_null = false;
};
PIValueTree::PIValueTree() {
}
PIValueTree::PIValueTree(const PIVariant & v) {
setValue(v);
}
PIValueTree::PIValueTree(const PIString & n, const PIVariant & v) {
setName(n);
setValue(v);
}
void PIValueTree::setName(const PIString & n) {
if (_is_null) return;
_name = n;
}
void PIValueTree::setValue(const PIVariant & v) {
if (_is_null) return;
_value = v;
}
bool PIValueTree::contains(const PIString & name) const {
if (_is_null) return true;
for (const auto & c: _children)
if (c.name() == name)
return true;
return false;
}
PIValueTree PIValueTree::child(const PIString & name) const {
if (_is_null) return PIValueTree();
for (const auto & c: _children)
if (c.name() == name)
return c;
return PIValueTree();
}
PIValueTree & PIValueTree::child(const PIString & name) {
if (_is_null) return nullValue();
for (auto & c: _children)
if (c.name() == name)
return c;
return nullValue();
}
PIValueTree & PIValueTree::insert(const PIValueTree & n) {
if (_is_null) return nullValue();
for (auto & c: _children)
if (c.name() == n.name()) {
c = n;
return *this;
}
_children << n;
return *this;
}
PIValueTree & PIValueTree::remove(const PIString & name) {
if (_is_null) return nullValue();
_children.removeWhere([name](const PIValueTree & i){return i.name() == name;});
return *this;
}
PIValueTree & PIValueTree::nullValue() {
static PIValueTree ret;
ret._is_null = true;
return ret;
}
struct SomeType {
int i;
float f;
@@ -169,18 +28,19 @@ REGISTER_VARIANT_CAST(PIString, SomeType) {
int main(int argc, char * argv[]) {
PIValueTree root;
root.insert({"bool", PIVariant(false)});
root.insert({"integer", PIVariant(256)});
root.insert({"string", PIVariant("str")});
//for (auto it: root.children()) {
// piCout << it.name() << it.value();
//}
PIVariant v = PIVariant::fromType("PIVariantTypes::IODevice");
piCout << v;
piCout << v.toString();
v.setValueFromString("2;-0.1");
piCout << v.value<PIVariantTypes::IODevice>();
piCout << v.toString();
root.addChild({"bool", PIVariant(false)});
root.addChild({"integer", PIVariant(256)});
root.addChild({"string", PIVariant("str")});
for (auto it: root.children()) {
piCout << it.name() << it.value();
}
piCout << piSerialize(root);
//PIVariant v = PIVariant::fromType(PIVariant::typeID<double>());
//piCout << v;
//piCout << v.toString();
//v.setValueFromString("2E-3");
//piCout << v.value<double>();
//piCout << v.toString();
return 0;
}