diff options
author | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-02-11 17:55:04 +0100 |
---|---|---|
committer | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-02-11 17:55:04 +0100 |
commit | 7daed2f8431e89e2bd041a54bc1bef8c45329092 (patch) | |
tree | 0e252862dcb2b1e24eaf8886020d597dd1233cb1 | |
parent | 2f75ac166594b6bc2ea30901669304eca23174ec (diff) |
improved pathto
-rw-r--r-- | src/core/model/Domain.cpp | 30 | ||||
-rw-r--r-- | src/core/model/Domain.hpp | 3 | ||||
-rw-r--r-- | test/core/model/DomainTest.cpp | 7 |
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>> ¤tPath) const + NodeVector<Node> ¤tPath, 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()); } |