0.6.0
C++ to UML diagram generator based on Clang
Loading...
Searching...
No Matches
display_adapters.h
Go to the documentation of this file.
1/**
2 * @file src/common/generators/display_adapters.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
21#include "util/util.h"
22
23#include <string>
24
26
27namespace detail {
28
29template <typename U>
30auto has_name_impl(int) -> decltype(std::declval<U>().name(), std::true_type{});
31
32template <typename> std::false_type has_name_impl(...);
33
34template <typename U> struct has_name : decltype(has_name_impl<U>(0)) { };
35
36template <typename U>
37auto has_type_impl(int) -> decltype(std::declval<U>().type(), std::true_type{});
38
39template <typename> std::false_type has_type_impl(...);
40
41template <typename U> struct has_type : decltype(has_type_impl<U>(0)) { };
42
43template <typename U>
45 int) -> decltype(std::declval<U>().full_name(std::declval<bool>()),
46 std::true_type{});
47template <typename> std::false_type has_full_name_impl(...);
48
49template <typename U>
50struct has_full_name : decltype(has_full_name_impl<U>(0)) { };
51
52template <typename U>
54 int) -> decltype(std::declval<U>().name_no_ns(), std::true_type{});
55template <typename> std::false_type has_name_no_ns_impl(...);
56
57template <typename U>
58struct has_name_no_ns : decltype(has_name_no_ns_impl<U>(0)) { };
59
60template <typename U>
62 int) -> decltype(std::declval<U>().full_name_no_ns(), std::true_type{});
63template <typename> std::false_type has_full_name_no_ns_impl(...);
64
65template <typename U>
66struct has_full_name_no_ns : decltype(has_full_name_no_ns_impl<U>(0)) { };
67
68} // namespace detail
69
70template <typename T> class display_name_adapter {
71public:
72 explicit display_name_adapter(const T &e)
73 : element_{e}
74 {
75 }
76
78 {
79 with_packages_ = true;
80 return *this;
81 }
82
83 template <typename U = T>
84 std::enable_if_t<detail::has_name<U>::value, std::string> name() const
85 {
86 return adapt(element_.name());
87 }
88
89 template <typename U = T>
90 std::enable_if_t<detail::has_type<U>::value, std::string> type() const
91 {
92 return adapt(element_.type());
93 }
94
95 template <typename U = T>
96 std::enable_if_t<detail::has_full_name<U>::value, std::string> full_name(
97 bool relative) const
98 {
99 return adapt(element_.full_name(relative));
100 }
101
102 template <typename U = T>
103 std::enable_if_t<detail::has_name_no_ns<U>::value, std::string>
105 {
106 return adapt(element_.name_no_ns());
107 }
108
109 template <typename U = T>
110 std::enable_if_t<detail::has_full_name_no_ns<U>::value, std::string>
112 {
113 return adapt(element_.full_name_no_ns());
114 }
115
116protected:
117 std::string adapt(std::string n) const
118 {
119 util::replace_all(n, "##", "::");
120
121 if constexpr (std::is_base_of<common::model::element, T>::value) {
122 if (!with_packages_) {
123 if (needs_root_prefix(element_))
124 return fmt::format("::{}", n);
125 }
126 else {
127 if (element_.get_namespace().is_empty() &&
128 needs_root_prefix(element_))
129 return fmt::format("::{}", n);
130 }
131 }
132
133 return n;
134 }
135
136private:
137 mutable bool with_packages_{false};
138 const T &element_;
139};
140
141} // namespace clanguml::common::generators