summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2023-08-20 01:35:19 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2023-08-20 01:35:19 +0100
commit876e40db376ae5cb0bc3c97c5fd70b2b1bee4d46 (patch)
tree8313c31744b4aa952a595ea76dcedccf457fe115
parentRemove enable_shared_from_this from ModelPart (diff)
downloadslicer-876e40db376ae5cb0bc3c97c5fd70b2b1bee4d46.tar.bz2
slicer-876e40db376ae5cb0bc3c97c5fd70b2b1bee4d46.tar.xz
slicer-876e40db376ae5cb0bc3c97c5fd70b2b1bee4d46.zip
Logical inversion
Removes ChildRef and changes ModelPart returning ModelPart functions with functions accepting a callback. Removes the need to maintain and pass around ModelPart pointers. ~30% performance increase processing large DB datasets.
-rw-r--r--slicer/db/sqlInsertSerializer.cpp7
-rw-r--r--slicer/db/sqlSelectDeserializer.cpp58
-rw-r--r--slicer/db/sqlTablePatchSerializer.cpp17
-rw-r--r--slicer/db/sqlUpdateSerializer.cpp7
-rw-r--r--slicer/json/serializer.cpp121
-rw-r--r--slicer/slicer/modelParts.cpp33
-rw-r--r--slicer/slicer/modelParts.h42
-rw-r--r--slicer/slicer/modelPartsTypes.cpp113
-rw-r--r--slicer/slicer/modelPartsTypes.h47
-rw-r--r--slicer/slicer/modelPartsTypes.impl.h85
-rw-r--r--slicer/slicer/slicer.cpp23
-rw-r--r--slicer/test/compilation.cpp73
-rw-r--r--slicer/xml/serializer.cpp165
13 files changed, 385 insertions, 406 deletions
diff --git a/slicer/db/sqlInsertSerializer.cpp b/slicer/db/sqlInsertSerializer.cpp
index c99df57..0881a1b 100644
--- a/slicer/db/sqlInsertSerializer.cpp
+++ b/slicer/db/sqlInsertSerializer.cpp
@@ -49,9 +49,10 @@ namespace Slicer {
void
SqlInsertSerializer::SerializeSequence(ModelPartParam mp) const
{
- auto ins = createInsert(mp->GetContainedModelPart());
- mp->OnEachChild([&ins, this](auto &&, auto && cmp, auto &&) {
- bindObjectAndExecute(cmp, ins.get());
+ mp->OnContained([this, mp](auto && cmp) {
+ mp->OnEachChild([ins = createInsert(cmp), this](auto &&, auto && chmp, auto &&) {
+ bindObjectAndExecute(chmp, ins.get());
+ });
});
}
diff --git a/slicer/db/sqlSelectDeserializer.cpp b/slicer/db/sqlSelectDeserializer.cpp
index 526f4b7..e11493e 100644
--- a/slicer/db/sqlSelectDeserializer.cpp
+++ b/slicer/db/sqlSelectDeserializer.cpp
@@ -47,10 +47,11 @@ namespace Slicer {
return;
}
if (!(*cmd)[0].isNull()) {
- auto fmp = mp->GetAnonChild();
- fmp->Create();
- fmp->SetValue(SqlSource((*cmd)[0]));
- fmp->Complete();
+ mp->OnAnonChild([this](auto && fmp, auto &&) {
+ fmp->Create();
+ fmp->SetValue(SqlSource((*cmd)[0]));
+ fmp->Complete();
+ });
}
if (cmd->fetch()) {
throw TooManyRowsReturned();
@@ -60,10 +61,11 @@ namespace Slicer {
void
SqlSelectDeserializer::DeserializeSequence(ModelPartParam omp)
{
- auto mp = omp->GetAnonChild();
- while (cmd->fetch()) {
- DeserializeRow(mp);
- }
+ omp->OnAnonChild([this](auto && mp, auto &&) {
+ while (cmd->fetch()) {
+ DeserializeRow(mp);
+ }
+ });
}
void
@@ -85,29 +87,33 @@ namespace Slicer {
void
SqlSelectDeserializer::DeserializeRow(ModelPartParam mp)
{
- auto rmp = mp->GetAnonChild();
- if (rmp) {
+ mp->OnAnonChild([this](auto && rmp, auto &&) {
switch (rmp->GetType()) {
case Slicer::ModelPartType::Complex: {
+ auto apply = [this](auto && rcmp) {
+ rcmp->Create();
+ for (auto col = 0U; col < columnCount; col += 1) {
+ const DB::Column & c = (*cmd)[col];
+ if (!c.isNull()) {
+ rcmp->OnChild(
+ [&c](auto && fmp, auto &&) {
+ if (fmp) {
+ fmp->Create();
+ fmp->SetValue(SqlSource(c));
+ fmp->Complete();
+ }
+ },
+ c.name, nullptr, false);
+ }
+ }
+ rcmp->Complete();
+ };
if (typeIdColIdx) {
std::string subclass;
(*cmd)[*typeIdColIdx] >> subclass;
- rmp = rmp->GetSubclassModelPart(subclass);
- }
- rmp->Create();
- for (auto col = 0U; col < columnCount; col += 1) {
- const DB::Column & c = (*cmd)[col];
- if (!c.isNull()) {
- auto fmpr = rmp->GetChildRef(c.name, nullptr, false);
- if (fmpr) {
- auto fmp = fmpr.Child();
- fmp->Create();
- fmp->SetValue(SqlSource(c));
- fmp->Complete();
- }
- }
+ return rmp->OnSubclass(apply, subclass);
}
- rmp->Complete();
+ apply(rmp);
} break;
case Slicer::ModelPartType::Simple: {
rmp->Create();
@@ -120,6 +126,6 @@ namespace Slicer {
default:
throw UnsupportedModelType();
}
- }
+ });
}
}
diff --git a/slicer/db/sqlTablePatchSerializer.cpp b/slicer/db/sqlTablePatchSerializer.cpp
index da5b0b2..ec0e344 100644
--- a/slicer/db/sqlTablePatchSerializer.cpp
+++ b/slicer/db/sqlTablePatchSerializer.cpp
@@ -32,14 +32,15 @@ namespace Slicer {
SqlInsertSerializer ins(db, tablePatch.src);
ins.Serialize(mpr);
- auto mp = mpr->GetContainedModelPart();
- mp->OnEachChild([this](const auto & name, const auto &, const auto & h) {
- if (isPKey(h)) {
- tablePatch.pk.insert(name);
- }
- if (isBind(h)) {
- tablePatch.cols.insert(name);
- }
+ mpr->OnContained([this](auto && mp) {
+ mp->OnEachChild([this](const auto & name, const auto &, const auto & h) {
+ if (isPKey(h)) {
+ tablePatch.pk.insert(name);
+ }
+ if (isBind(h)) {
+ tablePatch.cols.insert(name);
+ }
+ });
});
db->patchTable(&tablePatch);
diff --git a/slicer/db/sqlUpdateSerializer.cpp b/slicer/db/sqlUpdateSerializer.cpp
index c054764..152c923 100644
--- a/slicer/db/sqlUpdateSerializer.cpp
+++ b/slicer/db/sqlUpdateSerializer.cpp
@@ -49,9 +49,10 @@ namespace Slicer {
void
SqlUpdateSerializer::SerializeSequence(ModelPartParam mp) const
{
- auto ins = createUpdate(mp->GetContainedModelPart());
- mp->OnEachChild([&ins](auto &&, auto && cmp, auto &&) {
- bindObjectAndExecute(cmp, ins.get());
+ mp->OnContained([this, mp](auto && cmp) {
+ mp->OnEachChild([upd = createUpdate(cmp)](auto &&, auto && chmp, auto &&) {
+ bindObjectAndExecute(chmp, upd.get());
+ });
});
}
diff --git a/slicer/json/serializer.cpp b/slicer/json/serializer.cpp
index 9bbd508..5b2725b 100644
--- a/slicer/json/serializer.cpp
+++ b/slicer/json/serializer.cpp
@@ -151,9 +151,9 @@ namespace Slicer {
class DocumentTreeIterate {
public:
static void
- visit(ModelPartPtr && mp, const json::Value & v)
+ visit(ModelPartParam mp, const json::Value & v)
{
- std::visit(DocumentTreeIterate {std::move(mp)}, v);
+ std::visit(DocumentTreeIterate {mp}, v);
}
template<typename SimpleT>
@@ -174,34 +174,47 @@ namespace Slicer {
void
operator()(const json::Object & o) const
{
+ auto apply = [&o](auto && objectModelPart) {
+ objectModelPart->Create();
+ if (objectModelPart->GetMetadata().flagSet(md_object)) {
+ for (const auto & element : o) {
+ objectModelPart->OnAnonChild([&element](auto && emp, auto &&) {
+ emp->Create();
+ emp->OnChild(
+ [&element](auto && key, auto &&) {
+ key->Create();
+ key->SetValue(JsonValueSource(element.first));
+ key->Complete();
+ },
+ keyName);
+ emp->OnChild(
+ [&element](auto && value, auto &&) {
+ visit(value, element.second);
+ },
+ valueName);
+ emp->Complete();
+ });
+ }
+ }
+ else {
+ for (const auto & element : o) {
+ objectModelPart->OnChild(
+ [&element](auto && emp, auto &&) {
+ visit(emp, element.second);
+ emp->Complete();
+ },
+ element.first);
+ }
+ objectModelPart->Complete();
+ }
+ };
if (auto typeIdName = modelPart->GetTypeIdProperty()) {
auto typeAttrItr = o.find(*typeIdName);
if (typeAttrItr != o.end() && std::holds_alternative<json::String>(typeAttrItr->second)) {
- modelPart = modelPart->GetSubclassModelPart(std::get<json::String>(typeAttrItr->second));
- }
- }
- modelPart->Create();
- if (modelPart->GetMetadata().flagSet(md_object)) {
- for (const auto & element : o) {
- auto emp = modelPart->GetAnonChild();
- emp->Create();
- auto key = emp->GetChild(keyName);
- key->Create();
- key->SetValue(JsonValueSource(element.first));
- key->Complete();
- visit(emp->GetChild(valueName), element.second);
- emp->Complete();
+ return modelPart->OnSubclass(apply, std::get<json::String>(typeAttrItr->second));
}
}
- else {
- for (const auto & element : o) {
- if (auto emp = modelPart->GetChild(element.first)) {
- visit(std::move(emp), element.second);
- emp->Complete();
- }
- }
- modelPart->Complete();
- }
+ apply(modelPart);
}
void
@@ -209,16 +222,15 @@ namespace Slicer {
{
modelPart->Create();
for (const auto & element : a) {
- if (auto emp = modelPart->GetAnonChild()) {
- emp->Create();
- visit(std::move(emp), element);
+ modelPart->OnAnonChild([&element](auto && emp, auto &&) {
+ visit(emp, element);
emp->Complete();
- }
+ });
}
modelPart->Complete();
}
- ModelPartPtr && modelPart;
+ ModelPartParam modelPart;
};
void ModelTreeIterateTo(const std::function<json::Value &()> &, ModelPartParam mp);
@@ -243,15 +255,23 @@ namespace Slicer {
if (!mp->HasValue()) {
return;
}
- ModelTreeIterateTo(
- [&d, mp]() -> json::Value & {
- json::Object::key_type k;
- json::Value kv;
- mp->GetChild(keyName)->GetValue(JsonValueTarget(kv));
- JsonValueSource(kv).set(k);
- return d[std::move(k)];
+ mp->OnChild(
+ [&d, mp](auto && cmp, auto &&) {
+ ModelTreeIterateTo(
+ [&d, mp]() -> json::Value & {
+ json::Object::key_type k;
+ json::Value kv;
+ mp->OnChild(
+ [&kv](auto && emp, auto &&) {
+ emp->GetValue(JsonValueTarget(kv));
+ },
+ keyName);
+ JsonValueSource(kv).set(k);
+ return d[std::move(k)];
+ },
+ cmp);
},
- mp->GetChild(valueName));
+ valueName);
}
void
@@ -291,8 +311,11 @@ namespace Slicer {
};
if (auto typeIdName = mp->GetTypeIdProperty()) {
if (auto typeId = mp->GetTypeId()) {
- oec(mp->GetSubclassModelPart(*typeId))->emplace(*typeIdName, *typeId);
- return;
+ return mp->OnSubclass(
+ [&oec, &typeIdName, &typeId](auto && lmp) {
+ oec(lmp)->emplace(*typeIdName, *typeId);
+ },
+ *typeId);
}
}
oec(mp);
@@ -331,7 +354,11 @@ namespace Slicer {
void
JsonStreamDeserializer::Deserialize(ModelPartForRootParam modelRoot)
{
- DocumentTreeIterate::visit(modelRoot->GetAnonChild(), json::parseValue(strm));
+ modelRoot->OnAnonChild(
+ [this](auto && mp, auto &&) {
+ DocumentTreeIterate::visit(mp, json::parseValue(strm));
+ },
+ {});
}
void
@@ -349,7 +376,11 @@ namespace Slicer {
JsonFileDeserializer::Deserialize(ModelPartForRootParam modelRoot)
{
std::ifstream inFile(path);
- DocumentTreeIterate::visit(modelRoot->GetAnonChild(), json::parseValue(inFile));
+ modelRoot->OnAnonChild(
+ [&inFile](auto && mp, auto &&) {
+ DocumentTreeIterate::visit(mp, json::parseValue(inFile));
+ },
+ {});
}
JsonValueDeserializer::JsonValueDeserializer(const json::Value & v) : value(v) { }
@@ -357,7 +388,11 @@ namespace Slicer {
void
JsonValueDeserializer::Deserialize(ModelPartForRootParam modelRoot)
{
- DocumentTreeIterate::visit(modelRoot->GetAnonChild(), value);
+ modelRoot->OnAnonChild(
+ [this](auto && mp, auto &&) {
+ DocumentTreeIterate::visit(mp, value);
+ },
+ {});
}
void
diff --git a/slicer/slicer/modelParts.cpp b/slicer/slicer/modelParts.cpp
index abe94d8..07b4095 100644
--- a/slicer/slicer/modelParts.cpp
+++ b/slicer/slicer/modelParts.cpp
@@ -11,10 +11,10 @@ namespace Slicer {
{
}
- ModelPartPtr
- ModelPart::GetSubclassModelPart(const std::string &)
+ void
+ ModelPart::OnSubclass(const ModelPartHandler &, const std::string &)
{
- throw std::logic_error {"GetSubclassModelPart not supported on this ModelPart"};
+ throw std::logic_error {"OnSubclass not supported on this ModelPart"};
}
TypeId
@@ -46,30 +46,33 @@ namespace Slicer {
return emptyMetadata;
}
- ModelPartPtr
- ModelPart::GetAnonChild(const HookFilter & flt)
+ bool
+ ModelPart::IsOptional() const
{
- auto ref = GetAnonChildRef(flt);
- return ref ? ref.Child() : ModelPartPtr(nullptr);
+ return false;
}
- ModelPartPtr
- ModelPart::GetChild(std::string_view memberName, const HookFilter & flt)
+ void
+ ModelPart::OnEachChild(const ChildHandler &)
{
- auto ref = GetChildRef(memberName, flt);
- return ref ? ref.Child() : ModelPartPtr(nullptr);
}
bool
- ModelPart::IsOptional() const
+ ModelPart::OnAnonChild(const SubPartHandler &, const HookFilter &)
{
return false;
}
- ModelPartPtr
- ModelPart::GetContainedModelPart()
+ bool
+ ModelPart::OnChild(const SubPartHandler &, const std::string_view, const HookFilter &, bool)
+ {
+ return false;
+ }
+
+ void
+ ModelPart::OnContained(const ModelPartHandler &)
{
- throw std::logic_error {"GetContainedModelPart not supported on this ModelPart"};
+ throw std::logic_error {"OnContained not supported on this ModelPart"};
}
bool
diff --git a/slicer/slicer/modelParts.h b/slicer/slicer/modelParts.h
index 1f1a50e..39149fd 100644
--- a/slicer/slicer/modelParts.h
+++ b/slicer/slicer/modelParts.h
@@ -83,10 +83,12 @@ namespace Slicer {
using ModelPartParam = any_ptr<ModelPart>;
using ModelPartForRootParam = any_ptr<ModelPartForRootBase>;
using TypeId = std::optional<std::string>;
+ using Metadata = MetaData<>;
using ChildHandler = std::function<void(const std::string &, ModelPartParam, const HookCommon *)>;
- using ClassRef = std::function<ModelPartPtr(void *)>;
+ using ModelPartHandler = std::function<void(ModelPartParam)>;
+ using SubPartHandler = std::function<void(ModelPartParam, const Metadata &)>;
+ using ClassRef = std::function<void(void *, const ModelPartHandler &)>;
using HookFilter = std::function<bool(const HookCommon *)>;
- using Metadata = MetaData<>;
constexpr Metadata emptyMetadata;
enum class ModelPartType {
@@ -103,21 +105,6 @@ namespace Slicer {
Value,
};
- class DLL_PUBLIC ChildRef {
- public:
- explicit ChildRef();
- explicit ChildRef(ModelPartPtr);
- explicit ChildRef(ModelPartPtr, const Metadata &);
-
- [[nodiscard]] ModelPartPtr Child() const;
- [[nodiscard]] const Metadata & ChildMetaData() const;
- explicit operator bool() const;
-
- private:
- ModelPartPtr mpp;
- const Metadata & mdr;
- };
-
class DLL_PUBLIC HookCommon {
public:
constexpr HookCommon(std::string_view n, std::string_view nl, const std::string * ns) :
@@ -156,14 +143,11 @@ namespace Slicer {
template<typename T> static ModelPartPtr CreateFor(Default<T> &&);
template<typename T> static ModelPartForRootPtr CreateRootFor(T & t);
- virtual void OnEachChild(const ChildHandler &) = 0;
- ModelPartPtr GetAnonChild(const HookFilter & = HookFilter());
- ModelPartPtr GetChild(std::string_view memberName, const HookFilter & = HookFilter());
- virtual ChildRef GetAnonChildRef(const HookFilter & = HookFilter()) = 0;
- virtual ChildRef GetChildRef(
- std::string_view memberName, const HookFilter & = HookFilter(), bool matchCase = true)
- = 0;
- virtual ModelPartPtr GetSubclassModelPart(const std::string &);
+ virtual void OnEachChild(const ChildHandler &);
+ virtual bool OnAnonChild(const SubPartHandler &, const HookFilter & = HookFilter());
+ virtual bool OnChild(const SubPartHandler &, std::string_view memberName, const HookFilter & = HookFilter(),
+ bool matchCase = true);
+ virtual void OnSubclass(const ModelPartHandler &, const std::string &);
virtual TypeId GetTypeId() const;
virtual std::optional<std::string> GetTypeIdProperty() const;
virtual ModelPartType GetType() const = 0;
@@ -174,7 +158,7 @@ namespace Slicer {
virtual bool HasValue() const = 0;
virtual const Metadata & GetMetadata() const;
virtual bool IsOptional() const;
- virtual ModelPartPtr GetContainedModelPart();
+ virtual void OnContained(const ModelPartHandler &);
};
template<typename T> class DLL_PUBLIC ModelPartModel {
@@ -189,14 +173,14 @@ namespace Slicer {
explicit ModelPartForRootBase(ModelPartPtr mp);
virtual const std::string & GetRootName() const = 0;
- ChildRef GetAnonChildRef(const HookFilter &) override;
- ChildRef GetChildRef(std::string_view name, const HookFilter &, bool matchCase = true) override;
+ bool OnAnonChild(const SubPartHandler &, const HookFilter &) override;
+ bool OnChild(const SubPartHandler &, std::string_view name, const HookFilter &, bool matchCase = true) override;
void OnEachChild(const ChildHandler & ch) override;
ModelPartType GetType() const override;
bool IsOptional() const override;
virtual void Write(::Ice::OutputStream &) const = 0;
virtual void Read(::Ice::InputStream &) = 0;
- ModelPartPtr GetContainedModelPart() override;
+ void OnContained(const ModelPartHandler &) override;
ModelPartPtr mp;
};
diff --git a/slicer/slicer/modelPartsTypes.cpp b/slicer/slicer/modelPartsTypes.cpp
index bd130bf..da38efe 100644
--- a/slicer/slicer/modelPartsTypes.cpp
+++ b/slicer/slicer/modelPartsTypes.cpp
@@ -110,20 +110,22 @@ namespace Slicer {
// ModelPartForRootBase
ModelPartForRootBase::ModelPartForRootBase(ModelPartPtr m) : mp(std::move(m)) { }
- ChildRef
- ModelPartForRootBase::GetAnonChildRef(const HookFilter &)
+ bool
+ ModelPartForRootBase::OnAnonChild(const SubPartHandler & h, const HookFilter &)
{
mp->Create();
- return ChildRef(mp);
+ h(mp, emptyMetadata);
+ return true;
}
- ChildRef
- ModelPartForRootBase::GetChildRef(std::string_view name, const HookFilter & hf, bool matchCase)
+ bool
+ ModelPartForRootBase::OnChild(
+ const SubPartHandler & h, std::string_view name, const HookFilter & hf, bool matchCase)
{
if (!optionalCaseEq(name, GetRootName(), matchCase)) {
throw IncorrectElementName(std::string {name});
}
- return GetAnonChildRef(hf);
+ return OnAnonChild(h, hf);
}
void
@@ -144,27 +146,10 @@ namespace Slicer {
return mp->IsOptional();
}
- ModelPartPtr
- ModelPartForRootBase::GetContainedModelPart()
- {
- return mp->GetContainedModelPart();
- }
-
void
- ModelPartForSimpleBase::OnEachChild(const ChildHandler &)
- {
- }
-
- ChildRef
- ModelPartForSimpleBase::GetAnonChildRef(const HookFilter &)
- {
- return ChildRef();
- }
-
- ChildRef
- ModelPartForSimpleBase::GetChildRef(std::string_view, const HookFilter &, bool)
+ ModelPartForRootBase::OnContained(const ModelPartHandler & h)
{
- return ChildRef();
+ return mp->OnContained(h);
}
bool
@@ -181,23 +166,6 @@ namespace Slicer {
const ModelPartType ModelPartForSimpleBase::type = ModelPartType::Simple;
- void
- ModelPartForConvertedBase::OnEachChild(const ChildHandler &)
- {
- }
-
- ChildRef
- ModelPartForConvertedBase::GetAnonChildRef(const HookFilter &)
- {
- return ChildRef();
- }
-
- ChildRef
- ModelPartForConvertedBase::GetChildRef(std::string_view, const HookFilter &, bool)
- {
- return ChildRef();
- }
-
bool
ModelPartForConvertedBase::HasValue() const
{
@@ -245,11 +213,11 @@ namespace Slicer {
}
}
- ModelPartPtr
- ModelPartForComplexBase::getSubclassModelPart(const std::string & name, void * m)
+ void
+ ModelPartForComplexBase::onSubclass(const std::string & name, void * m, const ModelPartHandler & h)
{
if (const auto ref = refs->find(ToModelTypeName(name)); ref != refs->end()) {
- return ref->second(m);
+ return ref->second(m, h);
}
throw UnknownType(name);
}
@@ -284,22 +252,23 @@ namespace Slicer {
}
}
- ChildRef
- ModelPartForOptionalBase::GetAnonChildRef(const HookFilter & flt)
+ bool
+ ModelPartForOptionalBase::OnAnonChild(const SubPartHandler & h, const HookFilter & flt)
{
if (this->hasModel()) {
- return modelPart->GetAnonChildRef(flt);
+ return modelPart->OnAnonChild(h, flt);
}
- return ChildRef();
+ return false;
}
- ChildRef
- ModelPartForOptionalBase::GetChildRef(std::string_view name, const HookFilter & flt, bool matchCase)
+ bool
+ ModelPartForOptionalBase::OnChild(
+ const SubPartHandler & h, std::string_view name, const HookFilter & flt, bool matchCase)
{
if (this->hasModel()) {
- return modelPart->GetChildRef(name, flt, matchCase);
+ return modelPart->OnChild(h, name, flt, matchCase);
}
- return ChildRef();
+ return false;
}
void
@@ -328,23 +297,6 @@ namespace Slicer {
return modelPart->GetMetadata();
}
- void
- ModelPartForEnumBase::OnEachChild(const ChildHandler &)
- {
- }
-
- ChildRef
- ModelPartForEnumBase::GetAnonChildRef(const HookFilter &)
- {
- return ChildRef();
- }
-
- ChildRef
- ModelPartForEnumBase::GetChildRef(std::string_view, const HookFilter &, bool)
- {
- return ChildRef();
- }
-
bool
ModelPartForEnumBase::HasValue() const
{
@@ -371,13 +323,14 @@ namespace Slicer {
return type;
}
- ChildRef
- ModelPartForSequenceBase::GetChildRef(std::string_view name, const HookFilter & flt, bool matchCase)
+ bool
+ ModelPartForSequenceBase::OnChild(
+ const SubPartHandler & h, std::string_view name, const HookFilter & flt, bool matchCase)
{
if (!name.empty() && !optionalCaseEq(name, GetElementName(), matchCase)) {
throw IncorrectElementName(std::string {name});
}
- return GetAnonChildRef(flt);
+ return OnAnonChild(h, flt);
}
const ModelPartType ModelPartForSequenceBase::type = ModelPartType::Sequence;
@@ -397,20 +350,6 @@ namespace Slicer {
const ModelPartType ModelPartForDictionaryBase::type = ModelPartType::Dictionary;
// Streams
- // NOLINTNEXTLINE(hicpp-no-array-decay)
- ChildRef
- ModelPartForStreamBase::GetAnonChildRef(const Slicer::HookFilter &)
- {
- throw InvalidStreamOperation(__FUNCTION__);
- }
-
- // NOLINTNEXTLINE(hicpp-no-array-decay)
- ChildRef
- ModelPartForStreamBase::GetChildRef(std::string_view, const Slicer::HookFilter &, bool)
- {
- throw InvalidStreamOperation(__FUNCTION__);
- }
-
ModelPartType
ModelPartForStreamBase::GetType() const
{
diff --git a/slicer/slicer/modelPartsTypes.h b/slicer/slicer/modelPartsTypes.h
index b6e7b3c..ab262f3 100644
--- a/slicer/slicer/modelPartsTypes.h
+++ b/slicer/slicer/modelPartsTypes.h
@@ -41,9 +41,6 @@ namespace Slicer {
class DLL_PUBLIC ModelPartForSimpleBase : public ModelPart {
public:
- void OnEachChild(const ChildHandler &) override;
- ChildRef GetAnonChildRef(const HookFilter &) override;
- ChildRef GetChildRef(std::string_view, const HookFilter &, bool matchCase = true) override;
bool HasValue() const override;
ModelPartType GetType() const override;
static const ModelPartType type;
@@ -62,9 +59,6 @@ namespace Slicer {
class DLL_PUBLIC ModelPartForConvertedBase : public ModelPart {
public:
- void OnEachChild(const ChildHandler &) override;
- ChildRef GetAnonChildRef(const HookFilter &) override;
- ChildRef GetChildRef(std::string_view, const HookFilter &, bool matchCase = true) override;
bool HasValue() const override;
ModelPartType GetType() const override;
static const ModelPartType type;
@@ -109,8 +103,9 @@ namespace Slicer {
public:
void OnEachChild(const ChildHandler & ch) override;
void Complete() override;
- ChildRef GetAnonChildRef(const HookFilter & flt) override;
- ChildRef GetChildRef(std::string_view name, const HookFilter & flt, bool matchCase = true) override;
+ bool OnAnonChild(const SubPartHandler &, const HookFilter & flt) override;
+ bool OnChild(
+ const SubPartHandler &, std::string_view name, const HookFilter & flt, bool matchCase = true) override;
void SetValue(ValueSource && s) override;
bool HasValue() const override;
bool IsOptional() const override;
@@ -142,7 +137,7 @@ namespace Slicer {
static const ModelPartType type;
protected:
- ModelPartPtr getSubclassModelPart(const std::string & name, void * m);
+ void onSubclass(const std::string & name, void * m, const ModelPartHandler &);
static void registerClass(const std::string & className, const std::string * typeName, const ClassRef &);
static void unregisterClass(const std::string & className, const std::string * typeName);
@@ -163,15 +158,16 @@ namespace Slicer {
void OnEachChild(const ChildHandler & ch) override;
- ChildRef GetAnonChildRef(const HookFilter & flt) override;
- ChildRef GetChildRef(std::string_view name, const HookFilter & flt, bool matchCase = true) override;
+ bool OnAnonChild(const SubPartHandler &, const HookFilter & flt) override;
+ bool OnChild(
+ const SubPartHandler &, std::string_view name, const HookFilter & flt, bool matchCase = true) override;
const Metadata & GetMetadata() const override;
virtual T * GetModel() = 0;
protected:
- template<typename R> ChildRef GetChildRefFromRange(const R & range, const HookFilter & flt);
+ template<typename R> bool OnChildFromRange(const SubPartHandler &, const R & range, const HookFilter & flt);
static const Hooks<T> & hooks();
};
@@ -187,7 +183,7 @@ namespace Slicer {
T * GetModel() override;
- ModelPartPtr GetSubclassModelPart(const std::string & name) override;
+ void OnSubclass(const ModelPartHandler &, const std::string & name) override;
[[nodiscard]] bool HasValue() const override;
@@ -199,7 +195,7 @@ namespace Slicer {
static const std::string * className;
static const std::string * typeName;
- static ModelPartPtr CreateModelPart(void *);
+ static void CreateModelPart(void *, const ModelPartHandler &);
private:
static void initClassName();
@@ -221,9 +217,6 @@ namespace Slicer {
class DLL_PUBLIC ModelPartForEnumBase : public ModelPart {
public:
- void OnEachChild(const ChildHandler &) override;
- ChildRef GetAnonChildRef(const HookFilter &) override;
- ChildRef GetChildRef(std::string_view, const HookFilter &, bool matchCase = true) override;
bool HasValue() const override;
ModelPartType GetType() const override;
static const ModelPartType type;
@@ -252,7 +245,7 @@ namespace Slicer {
public:
bool HasValue() const override;
ModelPartType GetType() const override;
- ChildRef GetChildRef(std::string_view, const HookFilter &, bool matchCase = true) override;
+ bool OnChild(const SubPartHandler &, std::string_view, const HookFilter &, bool matchCase = true) override;
virtual const std::string & GetElementName() const = 0;
static const ModelPartType type;
@@ -266,19 +259,19 @@ namespace Slicer {
void OnEachChild(const ChildHandler & ch) override;
- ChildRef GetAnonChildRef(const HookFilter &) override;
+ bool OnAnonChild(const SubPartHandler &, const HookFilter &) override;
const std::string & GetElementName() const override;
const Metadata & GetMetadata() const override;
- ModelPartPtr GetContainedModelPart() override;
+ void OnContained(const ModelPartHandler &) override;
static const Metadata metadata;
static const std::string elementName;
private:
- ModelPartPtr elementModelPart(typename T::value_type &) const;
+ // ModelPartPtr elementModelPart(typename T::value_type &) const;
};
template<typename T>
@@ -309,13 +302,13 @@ namespace Slicer {
void OnEachChild(const ChildHandler & ch) override;
- ChildRef GetAnonChildRef(const HookFilter &) override;
+ bool OnAnonChild(const SubPartHandler &, const HookFilter &) override;
- ChildRef GetChildRef(std::string_view name, const HookFilter &, bool matchCase = true) override;
+ bool OnChild(const SubPartHandler &, std::string_view name, const HookFilter &, bool matchCase = true) override;
const Metadata & GetMetadata() const override;
- ModelPartPtr GetContainedModelPart() override;
+ void OnContained(const ModelPartHandler &) override;
static const Metadata metadata;
static const std::string pairName;
@@ -337,10 +330,8 @@ namespace Slicer {
public:
ModelPartType GetType() const override;
bool HasValue() const override;
- ChildRef GetAnonChildRef(const HookFilter &) override;
- ChildRef GetChildRef(std::string_view, const HookFilter &, bool matchCase = true) override;
- ModelPartPtr GetContainedModelPart() override = 0;
+ void OnContained(const ModelPartHandler &) override = 0;
void OnEachChild(const ChildHandler & ch) override = 0;
};
@@ -348,7 +339,7 @@ namespace Slicer {
public:
using ModelPartModel<Stream<T>>::ModelPartModel;
- ModelPartPtr GetContainedModelPart() override;
+ void OnContained(const ModelPartHandler &) override;
void OnEachChild(const ChildHandler & ch) override;
};
diff --git a/slicer/slicer/modelPartsTypes.impl.h b/slicer/slicer/modelPartsTypes.impl.h
index 0924de6..9cdbe47 100644
--- a/slicer/slicer/modelPartsTypes.impl.h
+++ b/slicer/slicer/modelPartsTypes.impl.h
@@ -354,8 +354,8 @@ namespace Slicer {
template<typename T>
template<typename R>
- ChildRef
- ModelPartForComplex<T>::GetChildRefFromRange(const R & range, const HookFilter & flt)
+ bool
+ ModelPartForComplex<T>::OnChildFromRange(const SubPartHandler & ch, const R & range, const HookFilter & flt)
{
const auto itr = std::find_if(range.begin(), range.end(), [&flt](auto && h) {
return h->filter(flt);
@@ -363,29 +363,31 @@ namespace Slicer {
if (itr != range.end()) {
const auto & h = *itr;
auto model = GetModel();
- return ChildRef(h->Get(model), h->GetMetadata());
+ ch(h->Get(model), h->GetMetadata());
+ return true;
}
- return ChildRef();
+ return false;
}
template<typename T>
- ChildRef
- ModelPartForComplex<T>::GetAnonChildRef(const HookFilter & flt)
+ bool
+ ModelPartForComplex<T>::OnAnonChild(const SubPartHandler & ch, const HookFilter & flt)
{
- return GetChildRefFromRange(hooks(), flt);
+ return OnChildFromRange(ch, hooks(), flt);
}
template<typename T>
- ChildRef
- ModelPartForComplex<T>::GetChildRef(std::string_view name, const HookFilter & flt, bool matchCase)
+ bool
+ ModelPartForComplex<T>::OnChild(
+ const SubPartHandler & ch, std::string_view name, const HookFilter & flt, bool matchCase)
{
if (matchCase) {
- return GetChildRefFromRange(hooks().equal_range(name), flt);
+ return OnChildFromRange(ch, hooks().equal_range(name), flt);
}
else {
std::string i {name};
to_lower(i);
- return GetChildRefFromRange(hooks().equal_range_lower(i), flt);
+ return OnChildFromRange(ch, hooks().equal_range_lower(i), flt);
}
}
@@ -453,11 +455,11 @@ namespace Slicer {
}
template<typename T>
- ModelPartPtr
- ModelPartForClass<T>::GetSubclassModelPart(const std::string & name)
+ void
+ ModelPartForClass<T>::OnSubclass(const ModelPartHandler & h, const std::string & name)
{
BOOST_ASSERT(this->Model);
- return ModelPartForComplexBase::getSubclassModelPart(name, this->Model);
+ return ModelPartForComplexBase::onSubclass(name, this->Model, h);
}
template<typename T>
@@ -476,10 +478,10 @@ namespace Slicer {
}
template<typename T>
- ModelPartPtr
- ModelPartForClass<T>::CreateModelPart(void * p)
+ void
+ ModelPartForClass<T>::CreateModelPart(void * p, const ModelPartHandler & h)
{
- return ::Slicer::ModelPart::CreateFor(*static_cast<element_type *>(p));
+ return h(::Slicer::ModelPart::CreateFor(*static_cast<element_type *>(p)));
}
template<typename T>
@@ -598,16 +600,17 @@ namespace Slicer {
{
BOOST_ASSERT(this->Model);
for (auto & element : *this->Model) {
- ch(elementName, elementModelPart(element), NULL);
+ ch(elementName, ModelPart::CreateFor(element), NULL);
}
}
template<typename T>
- ChildRef
- ModelPartForSequence<T>::GetAnonChildRef(const HookFilter &)
+ bool
+ ModelPartForSequence<T>::OnAnonChild(const SubPartHandler & ch, const HookFilter &)
{
BOOST_ASSERT(this->Model);
- return ChildRef(ModelPart::CreateFor(this->Model->emplace_back()));
+ ch(ModelPart::CreateFor(this->Model->emplace_back()), emptyMetadata);
+ return true;
}
template<typename T>
@@ -625,17 +628,10 @@ namespace Slicer {
}
template<typename T>
- ModelPartPtr
- ModelPartForSequence<T>::elementModelPart(typename T::value_type & e) const
- {
- return ModelPart::CreateFor(e);
- }
-
- template<typename T>
- ModelPartPtr
- ModelPartForSequence<T>::GetContainedModelPart()
+ void
+ ModelPartForSequence<T>::OnContained(const ModelPartHandler & h)
{
- return ModelPart::CreateFor(Default<typename T::value_type> {});
+ return h(ModelPart::CreateFor(Default<typename T::value_type> {}));
}
// ModelPartForDictionaryElementInserter
@@ -664,22 +660,25 @@ namespace Slicer {
}
template<typename T>
- ChildRef
- ModelPartForDictionary<T>::GetAnonChildRef(const HookFilter &)
+ bool
+ ModelPartForDictionary<T>::OnAnonChild(const SubPartHandler & ch, const HookFilter &)
{
BOOST_ASSERT(this->Model);
- return ChildRef(std::make_shared<ModelPartForDictionaryElementInserter<T>>(this->Model));
+ ch(std::make_shared<ModelPartForDictionaryElementInserter<T>>(this->Model), emptyMetadata);
+ return true;
}
template<typename T>
- ChildRef
- ModelPartForDictionary<T>::GetChildRef(std::string_view name, const HookFilter &, bool matchCase)
+ bool
+ ModelPartForDictionary<T>::OnChild(
+ const SubPartHandler & ch, std::string_view name, const HookFilter &, bool matchCase)
{
BOOST_ASSERT(this->Model);
if (!optionalCaseEq(name, pairName, matchCase)) {
throw IncorrectElementName(std::string {name});
}
- return ChildRef(std::make_shared<ModelPartForDictionaryElementInserter<T>>(this->Model));
+ ch(std::make_shared<ModelPartForDictionaryElementInserter<T>>(this->Model), emptyMetadata);
+ return true;
}
template<typename T>
@@ -690,18 +689,18 @@ namespace Slicer {
}
template<typename T>
- ModelPartPtr
- ModelPartForDictionary<T>::GetContainedModelPart()
+ void
+ ModelPartForDictionary<T>::OnContained(const ModelPartHandler & h)
{
- return std::make_shared<ModelPartForStruct<typename T::value_type>>(nullptr);
+ return h(std::make_shared<ModelPartForStruct<typename T::value_type>>(nullptr));
}
// ModelPartForStream
template<typename T>
- ModelPartPtr
- ModelPartForStream<T>::GetContainedModelPart()
+ void
+ ModelPartForStream<T>::OnContained(const ModelPartHandler & h)
{
- return ModelPart::CreateFor(Default<T> {});
+ return h(ModelPart::CreateFor(Default<T> {}));
}
template<typename T>
diff --git a/slicer/slicer/slicer.cpp b/slicer/slicer/slicer.cpp
index 2eda740..ff9a948 100644
--- a/slicer/slicer/slicer.cpp
+++ b/slicer/slicer/slicer.cpp
@@ -5,29 +5,6 @@
#include <utility>
namespace Slicer {
- Slicer::ChildRef::ChildRef() : mpp(), mdr(emptyMetadata) { }
-
- Slicer::ChildRef::ChildRef(ModelPartPtr m) : mpp(std::move(m)), mdr(emptyMetadata) { }
-
- Slicer::ChildRef::ChildRef(ModelPartPtr mp, const Slicer::Metadata & md) : mpp(std::move(mp)), mdr(md) { }
-
- ModelPartPtr
- Slicer::ChildRef::Child() const
- {
- return mpp;
- }
-
- Slicer::ChildRef::operator bool() const
- {
- return !!mpp;
- }
-
- const Metadata &
- Slicer::ChildRef::ChildMetaData() const
- {
- return mdr;
- }
-
AdHocFormatter(InvalidEnumerationSymbolMsg, "Invalid enumeration symbol [%?] for type [%?]");
void
diff --git a/slicer/test/compilation.cpp b/slicer/test/compilation.cpp
index fbbbb5f..ba7c568 100644
--- a/slicer/test/compilation.cpp
+++ b/slicer/test/compilation.cpp
@@ -40,11 +40,15 @@ BOOST_TEST_DONT_PRINT_LOG_VALUE(Slicer::ModelPartType)
#define StackTypeTest(Var, Explicit, Expected) TypeTest(Var, Var(), Explicit, Expected)
+constexpr auto DontCall = [](auto &&...) {
+ BOOST_ERROR("Shouldn't be called");
+};
+
BOOST_AUTO_TEST_CASE(compile_auto_modelpart_type_class)
{
TypeTest(TestModule::BuiltInsPtr, std::make_shared<TestModule::BuiltIns>(), ModelPartForClass,
ModelPartType::Complex);
- BOOST_CHECK_THROW(mpp->GetContainedModelPart(), std::logic_error);
+ BOOST_CHECK_THROW(mpp->OnContained(DontCall), std::logic_error);
}
static void
@@ -53,7 +57,7 @@ hookHandler(std::vector<std::string> * names, const std::string & name, Slicer::
{
names->push_back(name);
BOOST_REQUIRE(mpp);
- BOOST_CHECK_THROW(mpp->GetContainedModelPart(), std::logic_error);
+ BOOST_CHECK_THROW(mpp->OnContained(DontCall), std::logic_error);
BOOST_REQUIRE(h);
BOOST_REQUIRE_EQUAL(h->name, name);
}
@@ -61,39 +65,42 @@ hookHandler(std::vector<std::string> * names, const std::string & name, Slicer::
BOOST_AUTO_TEST_CASE(compile_auto_modelpart_type_sequenceclasses)
{
StackTypeTest(TestModule::Classes, ModelPartForSequence, ModelPartType::Sequence);
- auto cmpp = mpp->GetContainedModelPart();
- BOOST_REQUIRE(cmpp);
- BOOST_REQUIRE_EQUAL(Slicer::ModelPartType::Complex, cmpp->GetType());
- std::vector<std::string> names;
- cmpp->OnEachChild([&](auto && PH1, auto && PH2, auto && PH3) {
- hookHandler(&names, PH1, PH2, PH3);
+ mpp->OnContained([](auto && cmpp) {
+ BOOST_REQUIRE(cmpp);
+ BOOST_REQUIRE_EQUAL(Slicer::ModelPartType::Complex, cmpp->GetType());
+ std::vector<std::string> names;
+ cmpp->OnEachChild([&](auto && PH1, auto && PH2, auto && PH3) {
+ hookHandler(&names, PH1, PH2, PH3);
+ });
+ BOOST_REQUIRE_EQUAL(2, names.size());
+ BOOST_REQUIRE_EQUAL("a", names.front());
+ BOOST_REQUIRE_EQUAL("b", names.back());
});
- BOOST_REQUIRE_EQUAL(2, names.size());
- BOOST_REQUIRE_EQUAL("a", names.front());
- BOOST_REQUIRE_EQUAL("b", names.back());
}
BOOST_AUTO_TEST_CASE(compile_auto_modelpart_type_sequencestructs)
{
StackTypeTest(TestModule::Structs, ModelPartForSequence, ModelPartType::Sequence);
- auto cmpp = mpp->GetContainedModelPart();
- BOOST_REQUIRE(cmpp);
- BOOST_REQUIRE_EQUAL(Slicer::ModelPartType::Complex, cmpp->GetType());
- std::vector<std::string> names;
- cmpp->OnEachChild([&](auto && PH1, auto && PH2, auto && PH3) {
- hookHandler(&names, PH1, PH2, PH3);
+ mpp->OnContained([](auto && cmpp) {
+ BOOST_REQUIRE(cmpp);
+ BOOST_REQUIRE_EQUAL(Slicer::ModelPartType::Complex, cmpp->GetType());
+ std::vector<std::string> names;
+ cmpp->OnEachChild([&](auto && PH1, auto && PH2, auto && PH3) {
+ hookHandler(&names, PH1, PH2, PH3);
+ });
+ BOOST_REQUIRE_EQUAL(2, names.size());
+ BOOST_REQUIRE_EQUAL("a", names.front());
+ BOOST_REQUIRE_EQUAL("b", names.back());
});
- BOOST_REQUIRE_EQUAL(2, names.size());
- BOOST_REQUIRE_EQUAL("a", names.front());
- BOOST_REQUIRE_EQUAL("b", names.back());
}
BOOST_AUTO_TEST_CASE(compile_auto_modelpart_type_mapclasses)
{
StackTypeTest(TestModule::ClassMap, ModelPartForDictionary, ModelPartType::Dictionary);
- auto cmpp = mpp->GetContainedModelPart();
- BOOST_REQUIRE(cmpp);
- BOOST_REQUIRE_EQUAL(Slicer::ModelPartType::Complex, cmpp->GetType());
+ mpp->OnContained([](auto && cmpp) {
+ BOOST_REQUIRE(cmpp);
+ BOOST_REQUIRE_EQUAL(Slicer::ModelPartType::Complex, cmpp->GetType());
+ });
}
BOOST_AUTO_TEST_CASE(compile_auto_modelpart_type_mapstructs)
@@ -104,61 +111,61 @@ BOOST_AUTO_TEST_CASE(compile_auto_modelpart_type_mapstructs)
BOOST_AUTO_TEST_CASE(compile_auto_modelpart_type_bi_string)
{
StackTypeTest(std::string, ModelPartForSimple, ModelPartType::Simple);
- BOOST_CHECK_THROW(mpp->GetContainedModelPart(), std::logic_error);
+ BOOST_CHECK_THROW(mpp->OnContained(DontCall), std::logic_error);
}
BOOST_AUTO_TEST_CASE(compile_auto_modelpart_type_bi_bool)
{
StackTypeTest(bool, ModelPartForSimple, ModelPartType::Simple);
- BOOST_CHECK_THROW(mpp->GetContainedModelPart(), std::logic_error);
+ BOOST_CHECK_THROW(mpp->OnContained(DontCall), std::logic_error);
}
BOOST_AUTO_TEST_CASE(compile_auto_modelpart_type_bi_float)
{
StackTypeTest(Ice::Float, ModelPartForSimple, ModelPartType::Simple);
- BOOST_CHECK_THROW(mpp->GetContainedModelPart(), std::logic_error);
+ BOOST_CHECK_THROW(mpp->OnContained(DontCall), std::logic_error);
}
BOOST_AUTO_TEST_CASE(compile_auto_modelpart_type_bi_double)
{
StackTypeTest(Ice::Double, ModelPartForSimple, ModelPartType::Simple);
- BOOST_CHECK_THROW(mpp->GetContainedModelPart(), std::logic_error);
+ BOOST_CHECK_THROW(mpp->OnContained(DontCall), std::logic_error);
}
BOOST_AUTO_TEST_CASE(compile_auto_modelpart_type_bi_byte)
{
StackTypeTest(Ice::Byte, ModelPartForSimple, ModelPartType::Simple);
- BOOST_CHECK_THROW(mpp->GetContainedModelPart(), std::logic_error);
+ BOOST_CHECK_THROW(mpp->OnContained(DontCall), std::logic_error);
}
BOOST_AUTO_TEST_CASE(compile_auto_modelpart_type_bi_short)
{
StackTypeTest(Ice::Short, ModelPartForSimple, ModelPartType::Simple);
- BOOST_CHECK_THROW(mpp->GetContainedModelPart(), std::logic_error);
+ BOOST_CHECK_THROW(mpp->OnContained(DontCall), std::logic_error);
}
BOOST_AUTO_TEST_CASE(compile_auto_modelpart_type_bi_int)
{
StackTypeTest(Ice::Int, ModelPartForSimple, ModelPartType::Simple);
- BOOST_CHECK_THROW(mpp->GetContainedModelPart(), std::logic_error);
+ BOOST_CHECK_THROW(mpp->OnContained(DontCall), std::logic_error);
}
BOOST_AUTO_TEST_CASE(compile_auto_modelpart_type_bi_long)
{
StackTypeTest(Ice::Long, ModelPartForSimple, ModelPartType::Simple);
- BOOST_CHECK_THROW(mpp->GetContainedModelPart(), std::logic_error);
+ BOOST_CHECK_THROW(mpp->OnContained(DontCall), std::logic_error);
}
BOOST_AUTO_TEST_CASE(compile_auto_modelpart_type_struct)
{
StackTypeTest(TestModule::StructType, ModelPartForStruct, ModelPartType::Complex);
- BOOST_CHECK_THROW(mpp->GetContainedModelPart(), std::logic_error);
+ BOOST_CHECK_THROW(mpp->OnContained(DontCall), std::logic_error);
}
BOOST_AUTO_TEST_CASE(compile_auto_modelpart_type_enum)
{
StackTypeTest(TestModule::SomeNumbers, ModelPartForEnum, ModelPartType::Simple);
- BOOST_CHECK_THROW(mpp->GetContainedModelPart(), std::logic_error);
+ BOOST_CHECK_THROW(mpp->OnContained(DontCall), std::logic_error);
}
BOOST_AUTO_TEST_CASE(normalClassTypeId)
diff --git a/slicer/xml/serializer.cpp b/slicer/xml/serializer.cpp
index 5eab4be..8e351b6 100644
--- a/slicer/xml/serializer.cpp
+++ b/slicer/xml/serializer.cpp
@@ -221,7 +221,7 @@ namespace Slicer {
};
void DocumentTreeIterate(const xmlpp::Node * node, ModelPartParam mp);
- void DocumentTreeIterateElement(const xmlpp::Element * element, ModelPartParam mp, const ChildRef & c);
+ void DocumentTreeIterateElement(const xmlpp::Element * element, ModelPartParam mp, const Metadata & md);
void DocumentTreeIterate(const xmlpp::Document * doc, ModelPartParam mp);
void DocumentTreeIterateDictAttrs(const xmlpp::Element::const_AttributeList & attrs, ModelPartParam dict);
void DocumentTreeIterateDictElements(const xmlpp::Element * parent, ModelPartParam dict);
@@ -229,18 +229,23 @@ namespace Slicer {
void
DocumentTreeIterateDictAttrs(const xmlpp::Element::const_AttributeList & attrs, ModelPartParam dict)
{
- using AttrMember = Glib::ustring (xmlpp::Attribute::*)() const;
for (const auto & attr : attrs) {
- auto emp = dict->GetAnonChild();
- emp->Create();
- const auto setChild = [&emp, &attr](const auto & childName, AttrMember attrMember) {
- auto child = emp->GetChild(childName);
- child->SetValue(XmlValueSource((attr->*attrMember)()));
- child->Complete();
- };
- setChild(keyName, &xmlpp::Attribute::get_name);
- setChild(valueName, &xmlpp::Attribute::get_value);
- emp->Complete();
+ dict->OnAnonChild([&attr](auto && emp, auto &&) {
+ emp->Create();
+ emp->OnChild(
+ [&attr](auto && child, auto &&) {
+ child->SetValue(XmlValueSource(attr->get_name()));
+ child->Complete();
+ },
+ keyName);
+ emp->OnChild(
+ [&attr](auto && value, auto &&) {
+ value->SetValue(XmlValueSource(attr->get_value()));
+ value->Complete();
+ },
+ valueName);
+ emp->Complete();
+ });
}
}
@@ -250,31 +255,38 @@ namespace Slicer {
auto node = element->get_first_child();
while (node) {
if (auto childElement = dynamic_cast<const xmlpp::Element *>(node)) {
- auto emp = dict->GetAnonChild();
- emp->Create();
- auto key = emp->GetChild(keyName);
- auto value = emp->GetChildRef(valueName);
- key->SetValue(XmlValueSource(childElement->get_name()));
- key->Complete();
- DocumentTreeIterateElement(childElement, value.Child(), value);
- emp->Complete();
+ dict->OnAnonChild([childElement](auto && emp, auto &&) {
+ emp->Create();
+ emp->OnChild(
+ [childElement](auto && child, auto &&) {
+ child->SetValue(XmlValueSource(childElement->get_name()));
+ child->Complete();
+ },
+ keyName);
+ emp->OnChild(
+ [childElement](auto && value, auto && md) {
+ DocumentTreeIterateElement(childElement, value, md);
+ },
+ valueName);
+ emp->Complete();
+ });
}
node = node->get_next_sibling();
}
}
void
- DocumentTreeIterateElement(const xmlpp::Element * element, ModelPartParam smp, const ChildRef & smpr)
+ DocumentTreeIterateElement(const xmlpp::Element * element, ModelPartParam smp, const Metadata & md)
{
- auto oec = [&smpr, element](const auto & lmp) {
+ auto oec = [&md, element](const auto & lmp) {
lmp->Create();
- if (smpr.ChildMetaData().flagSet(md_attributes)) {
+ if (md.flagSet(md_attributes)) {
auto attrs(element->get_attributes());
if (!attrs.empty()) {
DocumentTreeIterateDictAttrs(attrs, lmp);
}
}
- else if (smpr.ChildMetaData().flagSet(md_elements)) {
+ else if (md.flagSet(md_elements)) {
DocumentTreeIterateDictElements(element, lmp);
}
else {
@@ -294,8 +306,7 @@ namespace Slicer {
};
if (auto typeIdPropName = smp->GetTypeIdProperty()) {
if (auto typeAttr = element->get_attribute(*typeIdPropName)) {
- oec(smp->GetSubclassModelPart(typeAttr->get_value()));
- return;
+ return smp->OnSubclass(oec, typeAttr->get_value());
}
}
oec(smp);
@@ -306,40 +317,45 @@ namespace Slicer {
{
while (node) {
if (auto element = dynamic_cast<const xmlpp::Element *>(node)) {
- auto smpr = mp->GetChildRef(element->get_name().raw(), [](const auto & h) {
- return h->GetMetadata().flagNotSet(md_attribute);
- });
- if (smpr) {
- auto smp = smpr.Child();
- if (smpr.ChildMetaData().flagSet(md_bare)) {
- smp = smp->GetAnonChild();
- }
- if (smp) {
- DocumentTreeIterateElement(element, smp, smpr);
- }
- }
+ mp->OnChild(
+ [element](auto && smp, auto && md) {
+ if (md.flagSet(md_bare)) {
+ smp->OnAnonChild([element](auto && bmp, auto && bmd) {
+ DocumentTreeIterateElement(element, bmp, bmd);
+ });
+ return;
+ }
+ DocumentTreeIterateElement(element, smp, md);
+ },
+ element->get_name().raw(),
+ [](const auto & h) {
+ return h->GetMetadata().flagNotSet(md_attribute);
+ });
}
else if (auto attribute = dynamic_cast<const xmlpp::Attribute *>(node)) {
- auto smp = mp->GetChild(attribute->get_name().raw(), [](const auto & h) {
- return h->GetMetadata().flagSet(md_attribute);
- });
- if (smp) {
- smp->Create();
- smp->SetValue(XmlValueSource(attribute));
- smp->Complete();
- }
+ mp->OnChild(
+ [attribute](auto && smp, auto &&) {
+ smp->Create();
+ smp->SetValue(XmlValueSource(attribute));
+ smp->Complete();
+ },
+ attribute->get_name().raw(),
+ [](const auto & h) {
+ return h->GetMetadata().flagSet(md_attribute);
+ });
}
else if (auto content = dynamic_cast<const xmlpp::ContentNode *>(node)) {
- ModelPartPtr smp;
+ bool bare = false;
if (!content->is_white_space()) {
- smp = mp->GetAnonChild([](const auto & h) {
- return h->GetMetadata().flagSet(md_text);
- });
- }
- if (smp) {
- smp->SetValue(XmlValueSource(content));
+ bare = (mp->OnAnonChild(
+ [content](auto && smp, auto &&) {
+ smp->SetValue(XmlValueSource(content));
+ },
+ [](const auto & h) {
+ return h->GetMetadata().flagSet(md_text);
+ }));
}
- else {
+ if (!bare) {
mp->SetValue(XmlValueSource(content));
}
}
@@ -397,9 +413,17 @@ namespace Slicer {
{
dict->OnEachChild([element](const auto &, const auto & mp, const auto &) {
if (mp->HasValue()) {
- mp->GetChild(keyName)->GetValue(XmlValueTarget([&mp, element](const auto & name) {
- mp->GetChild(valueName)->GetValue(XmlValueTarget(element, name));
- }));
+ mp->OnChild(
+ [mp, element](auto && key, auto &&) {
+ key->GetValue(XmlValueTarget([mp, element](const auto & name) {
+ mp->OnChild(
+ [element, &name](auto && value, auto &&) {
+ value->GetValue(XmlValueTarget(element, name));
+ },
+ valueName);
+ }));
+ },
+ keyName);
}
});
}
@@ -409,12 +433,20 @@ namespace Slicer {
{
dict->OnEachChild([element](const auto &, const auto & mp, const auto &) {
if (mp->HasValue()) {
- mp->GetChild(keyName)->GetValue(XmlValueTarget([&mp, element](const auto & name) {
- CurrentElementCreator cec([&element, &name]() {
- return element->add_child_element(name);
- });
- ModelTreeProcessElement(cec, mp->GetChild(valueName), defaultElementCreator);
- }));
+ mp->OnChild(
+ [mp, element](auto && key, auto &&) {
+ key->GetValue(XmlValueTarget([mp, element](const auto & name) {
+ CurrentElementCreator cec([&element, &name]() {
+ return element->add_child_element(name);
+ });
+ mp->OnChild(
+ [&cec](auto && value, auto &&) {
+ ModelTreeProcessElement(cec, value, defaultElementCreator);
+ },
+ valueName);
+ }));
+ },
+ keyName);
}
});
}
@@ -434,8 +466,11 @@ namespace Slicer {
};
if (auto typeIdPropName = mp->GetTypeIdProperty()) {
if (auto typeId = mp->GetTypeId()) {
- oec(mp->GetSubclassModelPart(*typeId))->set_attribute(*typeIdPropName, *typeId);
- return;
+ return mp->OnSubclass(
+ [oec, &typeIdPropName, &typeId](auto && smp) {
+ oec(smp)->set_attribute(*typeIdPropName, *typeId);
+ },
+ *typeId);
}
}
oec(mp);