From be68a27ca0b7c68bd75173355c0fdade893a1ace Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Mon, 18 Apr 2022 14:10:22 +0200 Subject: [PATCH] Refactored tree relationship filter --- src/common/model/diagram_filter.h | 80 +++++++++++++------------------ src/util/util.h | 6 +++ 2 files changed, 38 insertions(+), 48 deletions(-) diff --git a/src/common/model/diagram_filter.h b/src/common/model/diagram_filter.h index 94c13042..3ed8ffbc 100644 --- a/src/common/model/diagram_filter.h +++ b/src/common/model/diagram_filter.h @@ -169,60 +169,44 @@ private: matching_elements_.emplace(template_ref.value()); } - // Iterate over the templates set, until no new template instantiations - // or specializations are found - bool found_new_template{true}; + auto match_tree_rel = [&, this](const auto &from, const auto &to) { + bool added_new_element{false}; - auto reverse_relationship_match = [&found_new_template, this]( - const relationship &rel, - const auto &el) { - if (rel.type() == relationship_) { - for (const auto &already_matching : matching_elements_) { - if (rel.destination() == - already_matching->full_name(false)) { - auto inserted = matching_elements_.insert(el); - if (inserted.second) - found_new_template = true; - } - } - } - }; - - if (!forward_) - while (found_new_template) { - found_new_template = false; - // For each element of type ElementT in the diagram - for (const auto &el : detail::view(cd)) { - // Check if any of its relationships of type relationship_ - // points to an element already in the matching_elements_ - // 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(cd)) { - if (rel.destination() == el->full_name(false)) { - auto inserted = - matching_elements_.insert(el); - if (inserted.second) - found_new_template = true; - } + for (const auto &from_el : from) { + // Check if any of its relationships of type relationship_ + // points to an element already in the matching_elements_ + // set + for (const auto &rel : from_el->relationships()) { + if (rel.type() == relationship_) { + for (const auto &to_el : to) { + if (rel.destination() == to_el->full_name(false)) { + const auto &to_add = forward_ ? to_el : from_el; + if (matching_elements_.insert(to_add).second) + added_new_element = true; } } } + } } + return added_new_element; + }; + + bool keep_looking{true}; + while (keep_looking) { + keep_looking = false; + if (forward_) { + if (match_tree_rel( + matching_elements_, detail::view(cd))) + keep_looking = true; + } + else { + if (match_tree_rel( + detail::view(cd), matching_elements_)) + keep_looking = true; + } + } + initialized_ = true; } diff --git a/src/util/util.h b/src/util/util.h index ed59bf8e..90c8052b 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -218,5 +218,11 @@ bool contains(const T &container, const E &element) } } +template void for_each(const T &collection, F &&func) +{ + std::for_each(std::begin(collection), std::end(collection), + std::forward(func)); +} + } // namespace util } // namespace clanguml \ No newline at end of file