0.5.4
C++ to UML diagram generator based on Clang
Loading...
Searching...
No Matches
Public Member Functions | Private Member Functions | Private Attributes | List of all members
clanguml::common::model::context_filter Struct Reference

Detailed Description

Match diagram elements which are in within a 'radius' distance relationship to any of the elements specified in context.

Definition at line 570 of file diagram_filter.h.

#include <diagram_filter.h>

Public Member Functions

 context_filter (filter_t type, std::vector< config::context_config > context)
 
 ~context_filter () override=default
 
tvl::value_t match (const diagram &d, const element &r) const override
 
- Public Member Functions inherited from clanguml::common::model::filter_visitor
 filter_visitor (filter_t type)
 
virtual ~filter_visitor ()=default
 
virtual tvl::value_t match (const diagram &d, const common::model::element &e) const
 
virtual tvl::value_t match (const diagram &d, const common::model::relationship &r) const
 
virtual tvl::value_t match (const diagram &d, const common::model::relationship_t &r) const
 
virtual tvl::value_t match (const diagram &d, const common::model::access_t &a) const
 
virtual tvl::value_t match (const diagram &d, const common::model::namespace_ &ns) const
 
virtual tvl::value_t match (const diagram &d, const common::model::source_file &f) const
 
virtual tvl::value_t match (const diagram &d, const common::model::source_location &f) const
 
virtual tvl::value_t match (const diagram &d, const class_diagram::model::class_method &m) const
 
virtual tvl::value_t match (const diagram &d, const class_diagram::model::class_member &m) const
 
virtual tvl::value_t match (const diagram &d, const sequence_diagram::model::participant &p) const
 
bool is_inclusive () const
 
bool is_exclusive () const
 
filter_t type () const
 
filter_mode_t mode () const
 
void set_mode (filter_mode_t mode)
 

Private Member Functions

void initialize (const diagram &d) const
 
void initialize_effective_context (const diagram &d, unsigned idx) const
 
bool is_inward (relationship_t r) const
 
bool is_outward (relationship_t r) const
 
template<typename ElementT >
void find_elements_in_direct_relationship (const diagram &d, const config::context_config &context_cfg, std::set< eid_t > &effective_context, std::set< eid_t > &current_iteration_context) const
 
bool should_include (const config::context_config &context_cfg, relationship_t r) const
 
void find_elements_inheritance_relationship (const diagram &d, const config::context_config &context_cfg, std::set< eid_t > &effective_context, std::set< eid_t > &current_iteration_context) const
 
void find_elements_base_classes (const diagram &d, std::set< eid_t > &effective_context, std::set< eid_t > &current_iteration_context, const class_diagram::model::diagram &cd, const std::reference_wrapper< class_diagram::model::class_ > &c) const
 
void find_elements_sub_classes (std::set< eid_t > &effective_context, std::set< eid_t > &current_iteration_context, const class_diagram::model::diagram &cd, const std::reference_wrapper< class_diagram::model::class_ > &c) const
 

Private Attributes

std::vector< config::context_configcontext_
 
std::vector< std::set< eid_t > > effective_contexts_
 
bool initialized_ {false}
 

Constructor & Destructor Documentation

◆ context_filter()

clanguml::common::model::context_filter::context_filter ( filter_t  type,
std::vector< config::context_config context 
)

Definition at line 757 of file diagram_filter.cc.

760 , context_{std::move(context)}
761{
762}

◆ ~context_filter()

clanguml::common::model::context_filter::~context_filter ( )
overridedefault

Member Function Documentation

◆ find_elements_base_classes()

void clanguml::common::model::context_filter::find_elements_base_classes ( const diagram d,
std::set< eid_t > &  effective_context,
std::set< eid_t > &  current_iteration_context,
const class_diagram::model::diagram cd,
const std::reference_wrapper< class_diagram::model::class_ > &  c 
) const
private

Definition at line 890 of file diagram_filter.cc.

895{
896 for (const class_diagram::model::class_parent &p : c.get().parents()) {
897 for (const auto &ec : effective_context) {
898 const auto &maybe_parent =
899 cd.find<class_diagram::model::class_>(ec);
900 if (!maybe_parent)
901 continue;
902
903 if (d.should_include(relationship_t::kExtension) &&
904 maybe_parent.value().full_name(false) == p.name())
905 current_iteration_context.emplace(c.get().id());
906 }
907 }
908}

◆ find_elements_in_direct_relationship()

template<typename ElementT >
void clanguml::common::model::context_filter::find_elements_in_direct_relationship ( const diagram d,
const config::context_config context_cfg,
std::set< eid_t > &  effective_context,
std::set< eid_t > &  current_iteration_context 
) const
inlineprivate

Definition at line 587 of file diagram_filter.h.

591 {
592 static_assert(std::is_same_v<ElementT, class_diagram::model::class_> ||
593 std::is_same_v<ElementT, class_diagram::model::enum_> ||
594 std::is_same_v<ElementT, class_diagram::model::concept_>,
595 "ElementT must be either class_ or enum_ or concept_");
596
597 const auto &cd = dynamic_cast<const class_diagram::model::diagram &>(d);
598
599 for (const auto &el : cd.elements<ElementT>()) {
600 // First search all elements of type ElementT in the diagram
601 // which have a relationship to any of the effective_context
602 // elements
603 for (const relationship &rel : el.get().relationships()) {
604 if (!should_include(context_cfg, rel.type()) ||
605 !d.should_include(rel.type())) {
606 continue;
607 }
608 // At the moment aggregation and composition are added in the
609 // model in reverse direction, so we don't consider them here
610 if (context_cfg.direction ==
612 (rel.type() == relationship_t::kAggregation ||
613 rel.type() == relationship_t::kComposition)) {
614 continue;
615 }
616 if (context_cfg.direction ==
618 (rel.type() != relationship_t::kAggregation &&
619 rel.type() != relationship_t::kComposition)) {
620 continue;
621 }
622 for (const auto &element_id : effective_context) {
623 if (rel.destination() == element_id)
624 current_iteration_context.emplace(el.get().id());
625 }
626 }
627
628 // Now search current effective_context elements and add any
629 // elements of any type in the diagram which have a relationship
630 // to that element
631 for (const auto element_id : effective_context) {
632 const auto &maybe_element = cd.get(element_id);
633
634 if (!maybe_element)
635 continue;
636
637 for (const relationship &rel :
638 maybe_element.value().relationships()) {
639 if (!should_include(context_cfg, rel.type()) ||
640 !d.should_include(rel.type())) {
641 continue;
642 }
643
644 if ((context_cfg.direction ==
646 (rel.type() != relationship_t::kAggregation &&
647 rel.type() != relationship_t::kComposition)) {
648 continue;
649 }
650 if (context_cfg.direction ==
652 (rel.type() == relationship_t::kAggregation ||
653 rel.type() == relationship_t::kComposition)) {
654 continue;
655 }
656
657 if (rel.destination() == el.get().id())
658 current_iteration_context.emplace(el.get().id());
659 }
660 }
661 }
662 }

◆ find_elements_inheritance_relationship()

void clanguml::common::model::context_filter::find_elements_inheritance_relationship ( const diagram d,
const config::context_config context_cfg,
std::set< eid_t > &  effective_context,
std::set< eid_t > &  current_iteration_context 
) const
private

Definition at line 844 of file diagram_filter.cc.

848{
849 const auto &cd = dynamic_cast<const class_diagram::model::diagram &>(d);
850
851 if (!should_include(context_cfg, relationship_t::kExtension)) {
852 return;
853 }
854
855 for (const auto &c : cd.classes()) {
856 // Check if any of the elements parents are already in the
857 // effective context...
858 if (context_cfg.direction != config::context_direction_t::outward)
860 d, effective_context, current_iteration_context, cd, c);
861
862 // .. or vice-versa
863 if (context_cfg.direction != config::context_direction_t::inward)
865 effective_context, current_iteration_context, cd, c);
866 }
867}

◆ find_elements_sub_classes()

void clanguml::common::model::context_filter::find_elements_sub_classes ( std::set< eid_t > &  effective_context,
std::set< eid_t > &  current_iteration_context,
const class_diagram::model::diagram cd,
const std::reference_wrapper< class_diagram::model::class_ > &  c 
) const
private

Definition at line 869 of file diagram_filter.cc.

874{
875 for (const auto &ec : effective_context) {
876 const auto &maybe_child = cd.find<class_diagram::model::class_>(ec);
877
878 // The element might not exist because it might have been
879 // something other than a class
880 if (!maybe_child)
881 continue;
882
883 for (const auto &p : maybe_child.value().parents()) {
884 if (p.name() == c.get().full_name(false)) {
885 current_iteration_context.emplace(c.get().id());
886 }
887 }
888 }
889}

◆ initialize()

void clanguml::common::model::context_filter::initialize ( const diagram d) const
private

Definition at line 910 of file diagram_filter.cc.

911{
912 if (initialized_)
913 return;
914
915 initialized_ = true;
916
917 // Prepare effective_contexts_
918 for (auto i = 0U; i < context_.size(); i++) {
919 effective_contexts_.push_back({}); // NOLINT
921 }
922}

◆ initialize_effective_context()

void clanguml::common::model::context_filter::initialize_effective_context ( const diagram d,
unsigned  idx 
) const
private

Definition at line 764 of file diagram_filter.cc.

766{
767 bool effective_context_extended{true};
768
769 auto &effective_context = effective_contexts_[idx];
770
771 // First add to effective context all elements matching context_ patterns
772 const auto &context_cfg = context_.at(idx);
773 const auto &context_matches =
774 dynamic_cast<const class_diagram::model::diagram &>(d)
775 .find<class_diagram::model::class_>(context_cfg.pattern);
776
777 for (const auto &maybe_match : context_matches) {
778 if (maybe_match)
779 effective_context.emplace(maybe_match.value().id());
780 }
781
782 const auto &context_enum_matches =
783 dynamic_cast<const class_diagram::model::diagram &>(d)
784 .find<class_diagram::model::enum_>(context_cfg.pattern);
785
786 for (const auto &maybe_match : context_enum_matches) {
787 if (maybe_match)
788 effective_context.emplace(maybe_match.value().id());
789 }
790
791 const auto &context_concept_matches =
792 dynamic_cast<const class_diagram::model::diagram &>(d)
793 .find<class_diagram::model::concept_>(context_cfg.pattern);
794
795 for (const auto &maybe_match : context_concept_matches) {
796 if (maybe_match)
797 effective_context.emplace(maybe_match.value().id());
798 }
799
800 // Now repeat radius times - extend the effective context with elements
801 // matching in direct relationship to what is in context
802 auto radius_counter = context_cfg.radius;
803 std::set<eid_t> current_iteration_context;
804
805 while (radius_counter > 0 && effective_context_extended) {
806 // If at any iteration the effective context was not extended - we
807 // don't to need to continue
808 radius_counter--;
809 effective_context_extended = false;
810 current_iteration_context.clear();
811
812 // For each class in the model
813 find_elements_in_direct_relationship<class_diagram::model::class_>(
814 d, context_cfg, effective_context, current_iteration_context);
815
817 d, context_cfg, effective_context, current_iteration_context);
818
819 // For each concept in the model
820 find_elements_in_direct_relationship<class_diagram::model::concept_>(
821 d, context_cfg, effective_context, current_iteration_context);
822
823 // For each enum in the model
824 find_elements_in_direct_relationship<class_diagram::model::enum_>(
825 d, context_cfg, effective_context, current_iteration_context);
826
827 for (auto id : current_iteration_context) {
828 if (effective_context.count(id) == 0) {
829 // Found new element to add to context
830 effective_context.emplace(id);
831 effective_context_extended = true;
832 }
833 }
834 }
835}

◆ is_inward()

bool clanguml::common::model::context_filter::is_inward ( relationship_t  r) const
private

Definition at line 948 of file diagram_filter.cc.

949{
951}

◆ is_outward()

bool clanguml::common::model::context_filter::is_outward ( relationship_t  r) const
private

Definition at line 953 of file diagram_filter.cc.

954{
956}

◆ match()

tvl::value_t clanguml::common::model::context_filter::match ( const diagram d,
const element r 
) const
overridevirtual

Reimplemented from clanguml::common::model::filter_visitor.

Definition at line 924 of file diagram_filter.cc.

925{
926 if (d.type() != diagram_t::kClass)
927 return {};
928
929 // Running this filter makes sense only after the entire diagram is
930 // generated - i.e. during diagram generation
931 if (!d.complete())
932 return {};
933
934 initialize(d);
935
936 if (std::all_of(effective_contexts_.begin(), effective_contexts_.end(),
937 [](const auto &ec) { return ec.empty(); }))
938 return {};
939
940 for (const auto &ec : effective_contexts_) {
941 if (ec.count(e.id()) > 0)
942 return true;
943 }
944
945 return false;
946}

◆ should_include()

bool clanguml::common::model::context_filter::should_include ( const config::context_config context_cfg,
relationship_t  r 
) const
private

Definition at line 837 of file diagram_filter.cc.

839{
840 return context_cfg.relationships.empty() ||
841 util::contains(context_cfg.relationships, r);
842}

Member Data Documentation

◆ context_

std::vector<config::context_config> clanguml::common::model::context_filter::context_
private

Definition at line 683 of file diagram_filter.h.

◆ effective_contexts_

std::vector<std::set<eid_t> > clanguml::common::model::context_filter::effective_contexts_
mutableprivate

Represents all elements which should belong to the diagram based on this filter. It is populated by the initialize() method.

Definition at line 689 of file diagram_filter.h.

◆ initialized_

bool clanguml::common::model::context_filter::initialized_ {false}
mutableprivate

Flag to mark whether the filter context has been computed

Definition at line 692 of file diagram_filter.h.


The documentation for this struct was generated from the following files: