summaryrefslogtreecommitdiff
path: root/src/core/model
diff options
context:
space:
mode:
authorBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-02-15 20:16:04 +0100
committerBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-02-15 20:16:04 +0100
commit67f25b93b847b43a62a4148e626481c3f6d0cd9b (patch)
tree1346a333d0712080a59ca88a1f31c21b188b2157 /src/core/model
parentc0db7f8fda037b2bfeb3f47605b9cb52205dffc8 (diff)
added getChildrenWithSubclasses and thus made pathTo and collect more compact.
Diffstat (limited to 'src/core/model')
-rw-r--r--src/core/model/Domain.cpp68
-rw-r--r--src/core/model/Domain.hpp11
2 files changed, 35 insertions, 44 deletions
diff --git a/src/core/model/Domain.cpp b/src/core/model/Domain.cpp
index 698d49d..ae20068 100644
--- a/src/core/model/Domain.cpp
+++ b/src/core/model/Domain.cpp
@@ -81,7 +81,7 @@ static NodeVector<Node> pathTo(const Node *start, Logger &logger,
const FieldDescriptor *field =
static_cast<const FieldDescriptor *>(start);
// initially put every child and its subclasses to the queue.
- for (auto c : field->getChildren()) {
+ for (auto c : field->getChildrenWithSubclasses()) {
// if we have found the target directly, return without search.
if (c == target) {
success = true;
@@ -90,16 +90,6 @@ static NodeVector<Node> pathTo(const Node *start, Logger &logger,
if (c->isTransparent()) {
states.push(std::make_shared<PathState>(nullptr, c.get()));
}
- for (auto sub : c->getSubclasses()) {
- if (sub == target) {
- success = true;
- return shortest;
- }
- if (sub->isTransparent()) {
- states.push(
- std::make_shared<PathState>(nullptr, sub.get()));
- }
- }
}
}
// set of visited nodes.
@@ -140,7 +130,7 @@ static NodeVector<Node> pathTo(const Node *start, Logger &logger,
const FieldDescriptor *field =
static_cast<const FieldDescriptor *>(current->node);
// and we proceed by visiting all permitted children.
- for (auto c : field->getChildren()) {
+ for (auto c : field->getChildrenWithSubclasses()) {
// if we found our target, break off the search in this branch.
if (c == target) {
fin = true;
@@ -150,17 +140,6 @@ static NodeVector<Node> pathTo(const Node *start, Logger &logger,
if (c->isTransparent()) {
states.push(std::make_shared<PathState>(current, c.get()));
}
- // ... or their transparent subclasses.
- for (auto sub : c->getSubclasses()) {
- if (sub == target) {
- fin = true;
- continue;
- }
- if (sub->isTransparent()) {
- states.push(
- std::make_shared<PathState>(current, sub.get()));
- }
- }
}
}
// check if we are finished.
@@ -224,29 +203,11 @@ static NodeVector<Node> collect(const Node *start, F match)
q.push(fd);
}
}
-
- /*
- * Furthermore we have to consider that all subclasses of this
- * StructuredClass are allowed in place of this StructuredClass as
- * well, so we continue the search for them as well.
- */
-
- NodeVector<StructuredClass> subs = strct->getSubclasses();
- for (auto sub : subs) {
- // note matches.
- if (match(sub)) {
- res.push_back(sub);
- }
- // We only continue our search via transparent classes.
- if (sub->isTransparent()) {
- q.push(sub);
- }
- }
} else {
// otherwise this is a FieldDescriptor.
Rooted<FieldDescriptor> field = n.cast<FieldDescriptor>();
// and we proceed by visiting all permitted children.
- for (auto c : field->getChildren()) {
+ for (auto c : field->getChildrenWithSubclasses()) {
// note matches.
if (match(c)) {
res.push_back(c);
@@ -350,7 +311,7 @@ bool FieldDescriptor::doValidate(Logger &logger) const
* there are duplicates.
*/
std::set<std::string> names;
- for (Handle<StructuredClass> c : children) {
+ for (Handle<StructuredClass> c : getChildrenWithSubclasses()) {
if (!names.insert(c->getName()).second) {
logger.error(std::string("Field \"") + getName() +
"\" had multiple children with the name \"" +
@@ -363,6 +324,25 @@ bool FieldDescriptor::doValidate(Logger &logger) const
return valid;
}
+static void gatherSubclasses(NodeVector<StructuredClass> &res,
+ Handle<StructuredClass> strct)
+{
+ for (auto sub : strct->getSubclasses()) {
+ res.push_back(sub);
+ gatherSubclasses(res, sub);
+ }
+}
+
+NodeVector<StructuredClass> FieldDescriptor::getChildrenWithSubclasses() const
+{
+ NodeVector<StructuredClass> res;
+ for (auto c : children) {
+ res.push_back(c);
+ gatherSubclasses(res, c);
+ }
+ return res;
+}
+
bool FieldDescriptor::removeChild(Handle<StructuredClass> c)
{
auto it = children.find(c);
@@ -642,7 +622,7 @@ void Descriptor::copyFieldDescriptor(Handle<FieldDescriptor> fd, Logger &logger)
copy = Rooted<FieldDescriptor>{
new FieldDescriptor(getManager(), this, fd->getFieldType(),
fd->getName(), fd->isOptional())};
- for (auto &c : fd->getChildren()) {
+ for (auto c : fd->getChildren()) {
copy->addChild(c);
}
}
diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp
index 3f41ecf..081435a 100644
--- a/src/core/model/Domain.hpp
+++ b/src/core/model/Domain.hpp
@@ -275,6 +275,17 @@ public:
const NodeVector<StructuredClass> &getChildren() const { return children; }
/**
+ * Returns all StructuredClasses whose instances are allowed as children in
+ * the Structure Tree of instances of this field including subclasses of
+ * children, which are allowed directly.
+ *
+ * @return all StructuredClasses whose instances are allowed as children in
+ * the Structure Tree of instances of this field including subclasses of
+ * children, which are allowed directly.
+ */
+ NodeVector<StructuredClass> getChildrenWithSubclasses() const;
+
+ /**
* Adds a StructuredClass whose instances shall be allowed as children in
* the StructureTree of instances of this field.
*/