Refactored tree relationship filter

This commit is contained in:
Bartek Kryza
2022-04-18 14:10:22 +02:00
parent 4ff563354f
commit be68a27ca0
2 changed files with 38 additions and 48 deletions

View File

@@ -169,57 +169,41 @@ private:
matching_elements_.emplace(template_ref.value()); matching_elements_.emplace(template_ref.value());
} }
// Iterate over the templates set, until no new template instantiations auto match_tree_rel = [&, this](const auto &from, const auto &to) {
// or specializations are found bool added_new_element{false};
bool found_new_template{true};
auto reverse_relationship_match = [&found_new_template, this]( for (const auto &from_el : from) {
const relationship &rel, // Check if any of its relationships of type relationship_
const auto &el) { // points to an element already in the matching_elements_
// set
for (const auto &rel : from_el->relationships()) {
if (rel.type() == relationship_) { if (rel.type() == relationship_) {
for (const auto &already_matching : matching_elements_) { for (const auto &to_el : to) {
if (rel.destination() == if (rel.destination() == to_el->full_name(false)) {
already_matching->full_name(false)) { const auto &to_add = forward_ ? to_el : from_el;
auto inserted = matching_elements_.insert(el); if (matching_elements_.insert(to_add).second)
if (inserted.second) added_new_element = true;
found_new_template = true;
} }
} }
} }
}
}
return added_new_element;
}; };
if (!forward_) bool keep_looking{true};
while (found_new_template) { while (keep_looking) {
found_new_template = false; keep_looking = false;
// For each element of type ElementT in the diagram if (forward_) {
for (const auto &el : detail::view<ElementT>(cd)) { if (match_tree_rel(
// Check if any of its relationships of type relationship_ matching_elements_, detail::view<ElementT>(cd)))
// points to an element already in the matching_elements_ keep_looking = true;
// set
for (const auto &rel : el->relationships()) {
reverse_relationship_match(rel, el);
}
}
}
else
while (found_new_template) {
found_new_template = false;
// For each of the already matched elements
for (const auto &already_matching : matching_elements_)
// Check if any of its relationships of type relationship_
// points to an element already in the matching_elements_
// set
for (const auto &rel : already_matching->relationships()) {
if (rel.type() == relationship_) {
for (const auto &el : detail::view<ElementT>(cd)) {
if (rel.destination() == el->full_name(false)) {
auto inserted =
matching_elements_.insert(el);
if (inserted.second)
found_new_template = true;
}
}
} }
else {
if (match_tree_rel(
detail::view<ElementT>(cd), matching_elements_))
keep_looking = true;
} }
} }

View File

@@ -218,5 +218,11 @@ bool contains(const T &container, const E &element)
} }
} }
template <typename T, typename F> void for_each(const T &collection, F &&func)
{
std::for_each(std::begin(collection), std::end(collection),
std::forward<decltype(func)>(func));
}
} // namespace util } // namespace util
} // namespace clanguml } // namespace clanguml