0.5.4
C++ to UML diagram generator based on Clang
Loading...
Searching...
No Matches
template_parameter.h
Go to the documentation of this file.
1/**
2 * @file src/common/model/template_parameter.h
3 *
4 * Copyright (c) 2021-2024 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/model/enums.h"
22#include "common/types.h"
23
24#include <deque>
25#include <optional>
26#include <set>
27#include <string>
28#include <vector>
29
31
33
34/**
35 * Type of template parameter or argument.
36 */
38 template_type, /*!< Template type, e.g. <typename T> */
39 template_template_type, /*!< Template template type, e.g. <typename <> T> */
40 non_type_template, /*!< Non type template parameter, e.g. <int N> */
41 argument, /*!< Template argument, e.g. <int> */
42 concept_constraint /*!< Concept constraint, e.g. <std::integral T> */
43};
44
46
47/**
48 * Enum representing type of reference or pointer type qualifier
49 */
50enum class rpqualifier {
51 kLValueReference, /*!< l-value reference (e.g. &) */
52 kRValueReference, /*!< r-value reference (e.g. &&) */
53 kPointer, /*!< pointer (e.g *) */
54 kNone /*!< No qualifier */
55};
56
57/**
58 * This struct manages a single level of template deduced context, e.g.
59 * & or const*
60 */
61struct context {
62 bool is_const{false};
63 bool is_volatile{false};
64 bool is_ref_const{false};
65 bool is_ref_volatile{false};
67
68 std::string to_string() const;
69
70 bool operator==(const context &rhs) const;
71 bool operator!=(const context &rhs) const;
72};
73
74/**
75 * @brief Represents template parameter, template arguments or concept
76 * constraints
77 *
78 * This class can represent both template parameter and template arguments,
79 * including variadic parameters and instantiations with
80 * nested templates
81 */
83public:
84 /**
85 * @brief Build template type parameter
86 *
87 * @param name Name of template parameter (e.g. T)
88 * @param default_value Default value of the parameter if any
89 * @param is_variadic Whether the template parameter is variadic
90 * @return template_parameter instance
91 */
92 static template_parameter make_template_type(const std::string &name,
93 const std::optional<std::string> &default_value = {},
94 bool is_variadic = false);
95
96 /**
97 * @brief Build template template parameter type
98 *
99 * @param name Name of template template parameter
100 * @param default_value Default value of the parameter if any
101 * @param is_variadic Whether the template parameter is variadic
102 * @return template_parameter instance
103 */
105 const std::string &name,
106 const std::optional<std::string> &default_value = {},
107 bool is_variadic = false);
108
109 /**
110 * @brief Build non-type template parameter
111 * @param type Type of non-type parameter (e.g. int)
112 * @param name Name of parameter
113 * @param default_value Default value of the parameter if any
114 * @param is_variadic Whether the template parameter is variadic
115 * @return template_parameter instance
116 */
117 static template_parameter make_non_type_template(const std::string &type,
118 const std::optional<std::string> &name,
119 const std::optional<std::string> &default_value = {},
120 bool is_variadic = false);
121
122 /**
123 * @brief Build template argument
124 *
125 * @param type Type of template argument
126 * @param default_value Default value of the parameter if any
127 * @return template_parameter instance
128 */
129 static template_parameter make_argument(const std::string &type,
130 const std::optional<std::string> &default_value = {});
131
132 /**
133 * @brief Build template argument with unexposed type
134 *
135 * This method is used to build template argument from an unexposed string,
136 * i.e. when Clang just returns a string for the template argument type
137 * instead of actual type AST.
138 *
139 * @param type String representation of the type
140 * @param default_value Default value of the parameter if any
141 * @return template_parameter instance
142 */
143 static template_parameter make_unexposed_argument(const std::string &type,
144 const std::optional<std::string> &default_value = {});
145
146 /**
147 * Set the type of template argument
148 *
149 * @param type Name of the type
150 */
151 void set_type(const std::string &type);
152
153 /**
154 * Get the type of template parameter if any
155 *
156 * @return Optional name of type
157 */
158 std::optional<std::string> type() const;
159
160 /**
161 * Set unique id for the template parameter or argument
162 *
163 * @param id Id of parameter
164 */
165 void set_id(const eid_t &id) { id_ = id; }
166
167 /**
168 * Get id of the template parameter
169 *
170 * @return Id of the template parameter
171 */
172 const std::optional<eid_t> &id() const { return id_; }
173
174 /**
175 * Set the name of the template parameter
176 *
177 * @param name Name of template parameter
178 */
179 void set_name(const std::string &name);
180
181 /**
182 * Get the name of template parameter, if any
183 *
184 * @return Name of template parameter
185 */
186 std::optional<std::string> name() const;
187
188 /**
189 * Set default value for template parameter
190 *
191 * @param value Default value
192 */
193 void set_default_value(const std::string &value);
194
195 /**
196 * Get the template parameters default value if any
197 *
198 * @return Default value
199 */
200 const std::optional<std::string> &default_value() const;
201
202 /**
203 * Set template parameters variadic status.
204 *
205 * @param is_variadic True, if template parameter is variadic
206 */
207 void is_variadic(bool is_variadic) noexcept;
208
209 /**
210 * Check whether template parameter is variadic
211 *
212 * @return True, if template parameter is variadic
213 */
214 bool is_variadic() const noexcept;
215
216 /**
217 * @brief Calculate the match between this and other parameter
218 *
219 * This method calculates to what degree *this matches the
220 * `base_template_parameter` as it's less specific specialization.
221 *
222 * The higher the value, the more likely it is that *this is a
223 * specialization of `base_template_parameter`.
224 *
225 * @todo This is not scientific - there probably is more strict way to
226 * calculate this...
227 *
228 * @see calculate_template_params_specialization_match()
229 *
230 * @param base_template_parameter
231 * @return Specialization match value
232 */
234 const template_parameter &base_template_parameter) const;
235
236 /**
237 * Whether this is a template parameter.
238 *
239 * @return True, if *this is a template parameter
240 */
241 bool is_template_parameter() const;
242
243 /**
244 * Set, whether this is a template parameter.
245 *
246 * @param is_template_parameter Template parameter status
247 */
249
250 /**
251 * Whether this is a template template parameter.
252 *
253 * @return True, if *this is a template template parameter
254 */
256
257 /**
258 * Set, whether this is a template template parameter.
259 *
260 * @param is_template_parameter Template template parameter status
261 */
263
264 bool is_unexposed() const;
265 void set_unexposed(bool unexposed);
266
267 /**
268 * Set, whether this is a function template parameter.
269 *
270 * @param ft Function template parameter status
271 */
272 void is_function_template(bool ft);
273
274 /**
275 * Whether this is a function template parameter.
276 *
277 * @return True, if *this is a function template parameter
278 */
279 bool is_function_template() const;
280
281 /**
282 * Set, whether this is a member pointer template parameter.
283 *
284 * @param m Member pointer template parameter status
285 */
286 void is_member_pointer(bool m);
287
288 /**
289 * Whether this is a member pointer parameter.
290 *
291 * @return True if this is member pointer parameter.
292 */
293 bool is_member_pointer() const;
294
295 /**
296 * Set, whether this is a data template parameter.
297 *
298 * @param m Data pointer parameter status
299 */
300 void is_data_pointer(bool m);
301
302 /**
303 * Whether this is a data pointer parameter.
304 *
305 * @return True, if this is a data pointer parameter.
306 */
307 bool is_data_pointer() const;
308
309 /**
310 * Set, whether this is an array template parameter.
311 *
312 * @param m Array parameter status
313 */
314 void is_array(bool a);
315
316 /**
317 * Whether this is an array template parameter.
318 *
319 * @return True, if this is an array template parameter.
320 */
321 bool is_array() const;
322
323 /**
324 * Add a nested template parameter.
325 *
326 * @param ct Template parameter r-value.
327 */
329
330 /**
331 * Add a nested template parameter.
332 *
333 * @param ct Template parameter l-value.
334 */
336
337 /**
338 * Get the reference to all nested template parameters.
339 *
340 * @return
341 */
342 const std::vector<template_parameter> &template_params() const;
343
344 /**
345 * Erase all nested template parameters.
346 */
347 void clear_params() { template_params_.clear(); }
348
349 /**
350 * Does the template parameters deduced context contain any references
351 * or pointers?
352 *
353 * @return True if any of the deduced context is a reference or pointer.
354 */
355 bool is_association() const;
356
357 /**
358 * Is this template argument or parameter a specialization of some more
359 * generic template.
360 *
361 * @return True, if this is specialization of some more generic template
362 * parameter.
363 */
364 bool is_specialization() const;
365
366 /**
367 * @brief Whether this is the same type of specialization as other.
368 *
369 * This method is used for instance to check if 2 template parameters
370 * are function templates.
371 *
372 * @param other Another template parameter or argument
373 * @return True, if both template parameters are the same type of
374 * specialzations.
375 */
376 bool is_same_specialization(const template_parameter &other) const;
377
378 /**
379 * @brief Find all relationships in this and its nested templates
380 *
381 * @param nested_relationships Output to store found relationships
382 * @param hint Provide hint for the found relationships
383 * @param should_include Functor to determine whether nested template
384 * parameter or argument should be considered
385 * @return
386 */
388 std::vector<std::pair<eid_t, common::model::relationship_t>>
389 &nested_relationships,
391 const std::function<bool(const std::string &full_name)> &should_include)
392 const;
393
394 /**
395 * Set the concept constraint for this template parameter
396 *
397 * @param constraint
398 */
399 void set_concept_constraint(std::string constraint);
400
401 /**
402 * Get the name of the concept constraint for this parameter, if any
403 *
404 * @return Optional concept constraint name
405 */
406 const std::optional<std::string> &concept_constraint() const;
407
408 /**
409 * Get the kind of the template parameter or argument
410 * @return Template parameter kind
411 */
413
414 /**
415 * Set the kind of the template parameter or argument.
416 *
417 * @param kind Kind of the template parameter
418 */
420
421 /**
422 * @brief Append a deduced context to the template parameter.
423 *
424 * @param q Deduced context
425 */
426 void push_context(const context &q);
427
428 /**
429 * Get the entire deduce context of the template parameter
430 *
431 * @return Deduced context of this template parameter
432 */
433 const std::deque<context> &deduced_context() const;
434
435 /**
436 * Set the deduced context for the template parameter
437 *
438 * @param c Deduced context.
439 */
440 void deduced_context(std::deque<context> c);
441
442 /**
443 * Set, whether the parameter is an ellipsis (...)
444 *
445 * @param e True, if parameter is an ellipsis
446 */
447 void is_ellipsis(bool e);
448
449 /**
450 * Check whether the parameter is an ellipsis
451 *
452 * @return True if the parameter is an ellipsis
453 */
454 bool is_ellipsis() const;
455
456 /**
457 * @brief Render the template_parameter into string
458 *
459 * This method renders the template parameter along with any of its
460 * nested template parameters
461 * @param using_namespace
462 * @param relative
463 * @param skip_qualifiers
464 * @return
465 */
466 std::string to_string(
467 const clanguml::common::model::namespace_ &using_namespace,
468 bool relative, bool skip_qualifiers = false) const;
469
470private:
471 /**
472 * This class should be only constructed using builder methods.
473 */
475
476 std::string deduced_context_str() const;
477
479
480 /*! Represents the type of non-type template parameters e.g. 'int' or type
481 * of template arguments
482 */
483 std::optional<std::string> type_;
484
485 /*! The name of the parameter (e.g. 'T' or 'N') */
486 std::optional<std::string> name_;
487
488 /*! Default value of the template parameter */
489 std::optional<std::string> default_value_;
490
491 /*! Whether the template parameter is a regular template parameter. When
492 * false, it is a non-type template parameter
493 */
495
496 /*! Whether the template parameter is a template template parameter.
497 * Can only be true when is_template_parameter_ is true
498 */
500
501 /*! Whether template argument is ellipsis (...) */
502 bool is_ellipsis_{false};
503
504 /*! Whether the template parameter is variadic */
505 bool is_variadic_{false};
506
507 /*! Whether the template is a function template (e.g. R(T)) */
509
510 /*! Whether the template */
511 bool is_data_pointer_{false};
512
513 /*! Whether the template is a member pointer (e.g. R(C::*)(int)) */
515
516 /*! Is template argument an array */
517 bool is_array_{false};
518
519 /*! Stores the template parameter/argument deduction context e.g. const& */
520 std::deque<context> context_;
521
522 /*! Stores optional fully qualified name of constraint for this template
523 * parameter
524 */
525 std::optional<std::string> concept_constraint_;
526
527 /*! Nested template parameters. If this is a function template, the first
528 * element is the return type
529 */
530 std::vector<template_parameter> template_params_;
531
532 std::optional<eid_t> id_;
533
534 bool is_unexposed_{false};
535};
536
537/**
538 * @brief Calculate the match between 2 template parameter lists
539 *
540 * The higher the value, the more likely it is that *this is a
541 * specialization of `base_template_parameter`.
542 *
543 * @todo This is not scientific - there probably is more strict way to
544 * calculate this...
545 *
546 * @param base_template_parameter
547 * @return Specialization match value
548 */
550 const std::vector<template_parameter> &specialization,
551 const std::vector<template_parameter> &base_template);
552
553} // namespace clanguml::common::model