0.6.0
C++ to UML diagram generator based on Clang
Loading...
Searching...
No Matches
element_view.h
Go to the documentation of this file.
1/**
2 * @file src/common/model/element_view.h
3 *
4 * Copyright (c) 2021-2025 Bartek Kryza <bkryza@gmail.com>
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18#pragma once
19
20#include "common/types.h"
21
22#include <set>
23
25
27
28/**
29 * Provides type based views over elements in a diagram.
30 *
31 * @tparam T Type of diagram element
32 */
33template <typename T> class element_view {
34public:
35 /**
36 * @brief Add reference to diagram element
37 *
38 * @param element Reference to diagram element of specific type
39 */
40 void add(std::reference_wrapper<T> element)
41 {
42 elements_.emplace_back(std::move(element));
43 }
44
45 /**
46 * @brief Get collection of reference to diagram elements
47 *
48 * @return
49 */
50 const reference_vector<T> &view() const { return elements_; }
51
52 /**
53 * @brief Get collection of reference to diagram elements
54 *
55 * @return
56 */
58
59 /**
60 * @brief Get typed diagram element by id
61 * @param id Global id of a diagram element
62 *
63 * @return
64 */
66 {
67 for (const auto &e : elements_) {
68 if (e.get().id() == id) {
69 return {e};
70 }
71 }
72
73 return {};
74 }
75
76 /**
77 * @brief Check whether the element view is empty
78 *
79 * @return True, if the view does not contain any elements
80 */
81 bool is_empty() const { return elements_.empty(); }
82
83 void remove(const std::set<eid_t> &element_ids)
84 {
85 elements_.erase(std::remove_if(elements_.begin(), elements_.end(),
86 [&element_ids](auto &&e) {
87 return element_ids.count(e.get().id()) > 0;
88 }),
89 elements_.end());
90 }
91
92 template <typename F> void for_each(F &&f) const
93 {
94 for (const auto &e : elements_) {
95 f(e.get());
96 }
97 }
98
99private:
101};
102
103template <typename... Ts> struct element_views : public element_view<Ts>... {
104 template <typename F> void for_all_elements(F &&f)
105 {
106 (f(element_view<Ts>::view()), ...);
107 }
108
109 template <typename F> void for_all_elements(F &&f) const
110 {
111 (f(element_view<Ts>::view()), ...);
112 }
113
114 template <typename T> const element_view<T> &view() const
115 {
116 return dynamic_cast<const element_view<T> &>(*this);
117 }
118
119 /**
120 * @brief Calls `f` function on `e` if it can be dynamically casted to
121 * any type in the element_views
122 * @tparam T Element type
123 * @tparam F Function to call on e
124 * @param e Pointer to element
125 * @param f Function to call with `e` dynamically casted to one of types
126 */
127 template <typename T, typename F> void dynamic_apply(T *e, F &&f) const
128 {
129 if (e == nullptr)
130 return;
131
132 (
133 [&] {
134 if (auto *ptr = dynamic_cast<Ts *>(e); ptr) {
135 f(ptr);
136 }
137 }(),
138 ...);
139 }
140};
141} // namespace clanguml::common::model