summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-02-11 17:55:04 +0100
committerBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-02-11 17:55:04 +0100
commit7daed2f8431e89e2bd041a54bc1bef8c45329092 (patch)
tree0e252862dcb2b1e24eaf8886020d597dd1233cb1
parent2f75ac166594b6bc2ea30901669304eca23174ec (diff)
improved pathto
-rw-r--r--src/core/model/Domain.cpp30
-rw-r--r--src/core/model/Domain.hpp3
-rw-r--r--test/core/model/DomainTest.cpp7
3 files changed, 23 insertions, 17 deletions
diff --git a/src/core/model/Domain.cpp b/src/core/model/Domain.cpp
index 3fb525f..228348d 100644
--- a/src/core/model/Domain.cpp
+++ b/src/core/model/Domain.cpp
@@ -207,16 +207,15 @@ bool Descriptor::doValidate(Logger &logger) const
return valid & continueValidationCheckDuplicates(fds, logger);
}
-std::vector<Rooted<Node>> Descriptor::pathTo(
- Handle<StructuredClass> target) const
+NodeVector<Node> Descriptor::pathTo(Handle<StructuredClass> target) const
{
- std::vector<Rooted<Node>> path;
- continuePath(target, path);
- return path;
+ NodeVector<Node> path;
+ continuePath(target, path, true);
+ return std::move(path);
}
bool Descriptor::continuePath(Handle<StructuredClass> target,
- std::vector<Rooted<Node>> &currentPath) const
+ NodeVector<Node> &currentPath, bool start) const
{
// check if we are at the target already
if (this == target) {
@@ -225,27 +224,34 @@ bool Descriptor::continuePath(Handle<StructuredClass> target,
// a variable to determine if we already found a solution
bool found = false;
// the currently optimal path.
- std::vector<Rooted<Node>> optimum;
+ NodeVector<Node> optimum;
// use recursive depth-first search from the top to reach the given child
// get the list of effective FieldDescriptors.
NodeVector<FieldDescriptor> fields = getFieldDescriptors();
+ Rooted<Node> thisHandle{const_cast<Descriptor *>(this)};
+
for (auto &fd : fields) {
for (auto &c : fd->getChildren()) {
// check if a child is the target node.
if (c == target) {
// if we have made the connection, stop the search.
+ if (!start) {
+ currentPath.push_back(thisHandle);
+ }
currentPath.push_back(fd);
return true;
}
// look for transparent intermediate nodes.
if (c->isTransparent()) {
// copy the path.
- std::vector<Rooted<Node>> cPath = currentPath;
+ NodeVector<Node> cPath = currentPath;
+ if (!start) {
+ cPath.push_back(thisHandle);
+ }
cPath.push_back(fd);
- cPath.push_back(c);
// recursion.
- if (c->continuePath(target, cPath) &&
+ if (c->continuePath(target, cPath, false) &&
(!found || optimum.size() > cPath.size())) {
// look if this path is better than the current optimum.
optimum = std::move(cPath);
@@ -260,8 +266,8 @@ bool Descriptor::continuePath(Handle<StructuredClass> target,
// if this is a StructuredClass we also can call the subclasses.
for (auto &c : tis->getSubclasses()) {
// copy the path.
- std::vector<Rooted<Node>> cPath = currentPath;
- if (c->continuePath(target, cPath) &&
+ NodeVector<Node> cPath = currentPath;
+ if (c->continuePath(target, cPath, false) &&
(!found || optimum.size() > cPath.size())) {
// look if this path is better than the current optimum.
optimum = std::move(cPath);
diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp
index 43661c2..57e5602 100644
--- a/src/core/model/Domain.hpp
+++ b/src/core/model/Domain.hpp
@@ -589,8 +589,7 @@ public:
* no such path can be constructed.
*
*/
- std::vector<Rooted<Node>> pathTo(
- Handle<StructuredClass> childDescriptor) const;
+ NodeVector<Node> pathTo(Handle<StructuredClass> childDescriptor) const;
};
/*
* TODO: We should discuss Cardinalities one more time. Is it smart to define
diff --git a/test/core/model/DomainTest.cpp b/test/core/model/DomainTest.cpp
index 79b62f0..2e20c3b 100644
--- a/test/core/model/DomainTest.cpp
+++ b/test/core/model/DomainTest.cpp
@@ -101,7 +101,7 @@ TEST(Descriptor, pathTo)
Rooted<StructuredClass> book = getClass("book", domain);
Rooted<StructuredClass> section = getClass("section", domain);
// get the path in between.
- std::vector<Rooted<Node>> path = book->pathTo(section);
+ NodeVector<Node> path = book->pathTo(section);
ASSERT_EQ(1U, path.size());
ASSERT_TRUE(path[0]->isa(&RttiTypes::FieldDescriptor));
@@ -202,18 +202,19 @@ TEST(Descriptor, pathToAdvanced)
E_field->addChild(target);
ASSERT_TRUE(domain->validate(logger));
+
#ifdef MANAGER_GRAPHVIZ_EXPORT
// dump the manager state
mgr.exportGraphviz("nastyDomain.dot");
#endif
// and now we should be able to find the shortest path as suggested
- std::vector<Rooted<Node>> path = start->pathTo(target);
+ NodeVector<Node> path = start->pathTo(target);
ASSERT_EQ(3U, path.size());
ASSERT_TRUE(path[0]->isa(&RttiTypes::FieldDescriptor));
ASSERT_EQ("second", path[0]->getName());
ASSERT_TRUE(path[1]->isa(&RttiTypes::StructuredClass));
- ASSERT_EQ("B", path[1]->getName());
+ ASSERT_EQ("C", path[1]->getName());
ASSERT_TRUE(path[2]->isa(&RttiTypes::FieldDescriptor));
ASSERT_EQ("", path[2]->getName());
}