Refactored template builder with try_as methods for different types
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -80,11 +80,6 @@ public:
|
||||
const clang::TemplateArgument &arg, size_t argument_index,
|
||||
std::vector<template_parameter> &argument);
|
||||
|
||||
void process_tag_argument(model::class_ &template_instantiation,
|
||||
const clang::TemplateDecl *template_decl,
|
||||
const clang::QualType type,
|
||||
common::model::template_parameter &argument);
|
||||
|
||||
template_parameter process_expression_argument(
|
||||
const clang::TemplateArgument &arg);
|
||||
|
||||
@@ -100,30 +95,73 @@ public:
|
||||
std::vector<template_parameter> process_pack_argument(
|
||||
std::optional<clanguml::class_diagram::model::class_ *> &parent,
|
||||
const clang::NamedDecl *cls, class_ &template_instantiation,
|
||||
const clang::TemplateDecl *template_decl,
|
||||
const clang::TemplateDecl *base_template_decl,
|
||||
const clang::TemplateArgument &arg, size_t argument_index,
|
||||
std::vector<template_parameter> &argument);
|
||||
|
||||
template_parameter process_type_argument(
|
||||
std::optional<clanguml::class_diagram::model::class_ *> &parent,
|
||||
const clang::NamedDecl *cls, const clang::TemplateDecl *template_decl,
|
||||
const clang::TemplateArgument &arg,
|
||||
model::class_ &template_instantiation, size_t argument_index);
|
||||
const clang::NamedDecl *cls,
|
||||
const clang::TemplateDecl *base_template_decl,
|
||||
// const clang::TemplateArgument &arg,
|
||||
clang::QualType type, model::class_ &template_instantiation,
|
||||
size_t argument_index);
|
||||
|
||||
common::model::template_parameter process_template_argument(
|
||||
const clang::TemplateArgument &arg);
|
||||
|
||||
void process_unexposed_template_specialization_parameters(
|
||||
const std::string &type_name, template_parameter &tp, class_ &c);
|
||||
common::model::template_parameter process_template_expansion(
|
||||
const clang::TemplateArgument &arg);
|
||||
|
||||
std::optional<template_parameter> try_as_function_prototype(
|
||||
std::optional<clanguml::class_diagram::model::class_ *> &parent,
|
||||
const clang::NamedDecl *cls, const clang::TemplateDecl *template_decl,
|
||||
clang::QualType &type, class_ &template_instantiation,
|
||||
size_t argument_index);
|
||||
|
||||
std::optional<template_parameter> try_as_array(
|
||||
std::optional<clanguml::class_diagram::model::class_ *> &parent,
|
||||
const clang::NamedDecl *cls, const clang::TemplateDecl *template_decl,
|
||||
clang::QualType &type, class_ &template_instantiation,
|
||||
size_t argument_index);
|
||||
|
||||
std::optional<template_parameter> try_as_template_specialization_type(
|
||||
std::optional<clanguml::class_diagram::model::class_ *> &parent,
|
||||
const clang::NamedDecl *cls, const clang::TemplateDecl *template_decl,
|
||||
clang::QualType &type, class_ &template_instantiation,
|
||||
size_t argument_index);
|
||||
|
||||
std::optional<template_parameter> try_as_template_parm_type(
|
||||
const clang::NamedDecl *cls, const clang::TemplateDecl *template_decl,
|
||||
clang::QualType &type);
|
||||
|
||||
std::optional<template_parameter> try_as_lamda(const clang::NamedDecl *cls,
|
||||
const clang::TemplateDecl *template_decl, clang::QualType &type);
|
||||
|
||||
std::optional<template_parameter> try_as_record_type(
|
||||
std::optional<clanguml::class_diagram::model::class_ *> &parent,
|
||||
const clang::NamedDecl *cls, const clang::TemplateDecl *template_decl,
|
||||
clang::QualType &type, class_ &template_instantiation,
|
||||
size_t argument_index);
|
||||
|
||||
std::optional<template_parameter> try_as_enum_type(
|
||||
std::optional<clanguml::class_diagram::model::class_ *> &parent,
|
||||
const clang::NamedDecl *cls, const clang::TemplateDecl *template_decl,
|
||||
clang::QualType &type, class_ &template_instantiation);
|
||||
|
||||
std::optional<template_parameter> try_as_member_pointer(
|
||||
std::optional<clanguml::class_diagram::model::class_ *> &parent,
|
||||
const clang::NamedDecl *cls, const clang::TemplateDecl *template_decl,
|
||||
clang::QualType &type, class_ &template_instantiation,
|
||||
size_t argument_index);
|
||||
|
||||
clang::QualType consume_context(
|
||||
clang::QualType type, template_parameter &tp) const;
|
||||
|
||||
bool find_relationships_in_unexposed_template_params(
|
||||
const template_parameter &ct,
|
||||
class_diagram::visitor::found_relationships_t &relationships);
|
||||
|
||||
std::optional<template_parameter>
|
||||
get_template_argument_from_type_parameter_string(
|
||||
const clang::Decl *decl, std::string type_name) const;
|
||||
|
||||
common::visitor::ast_id_mapper &id_mapper();
|
||||
|
||||
clang::SourceManager &source_manager() const;
|
||||
|
||||
@@ -306,7 +306,8 @@ template <> id_t to_id(const std::string &full_name)
|
||||
return static_cast<id_t>(std::hash<std::string>{}(full_name) >> 3U);
|
||||
}
|
||||
|
||||
id_t to_id(const clang::QualType &type, const clang::ASTContext &ctx) {
|
||||
id_t to_id(const clang::QualType &type, const clang::ASTContext &ctx)
|
||||
{
|
||||
return to_id(common::to_string(type, ctx));
|
||||
}
|
||||
|
||||
@@ -520,6 +521,22 @@ bool is_type_token(const std::string &t)
|
||||
(is_identifier(t) && !is_qualifier(t) && !is_bracket(t));
|
||||
}
|
||||
|
||||
clang::QualType dereference(clang::QualType type)
|
||||
{
|
||||
auto res = type;
|
||||
|
||||
while (true) {
|
||||
if (res->isReferenceType())
|
||||
res = res.getNonReferenceType();
|
||||
else if (res->isPointerType())
|
||||
res = res->getPointeeType();
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<std::string> tokenize_unexposed_template_parameter(
|
||||
const std::string &t)
|
||||
{
|
||||
@@ -537,7 +554,8 @@ std::vector<std::string> tokenize_unexposed_template_parameter(
|
||||
std::string tok;
|
||||
|
||||
for (const char c : word) {
|
||||
if (c == '(' || c == ')' || c == '[' || c == ']' || c == '<' || c == '>') {
|
||||
if (c == '(' || c == ')' || c == '[' || c == ']' || c == '<' ||
|
||||
c == '>') {
|
||||
if (!tok.empty())
|
||||
result.push_back(tok);
|
||||
result.push_back(std::string{c});
|
||||
|
||||
@@ -184,4 +184,6 @@ bool is_qualified_identifier(const std::string &t);
|
||||
|
||||
bool is_type_token(const std::string &t);
|
||||
|
||||
clang::QualType dereference(clang::QualType type);
|
||||
|
||||
} // namespace clanguml::common
|
||||
|
||||
@@ -69,8 +69,9 @@ void template_parameter::set_name(const std::string &name)
|
||||
{
|
||||
assert(kind_ != template_parameter_kind_t::argument);
|
||||
|
||||
if (name.empty())
|
||||
if (name.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (util::ends_with(name, std::string{"..."})) {
|
||||
name_ = name.substr(0, name.size() - 3);
|
||||
@@ -113,10 +114,11 @@ int template_parameter::calculate_specialization_match(
|
||||
{
|
||||
int res{0};
|
||||
|
||||
// If the potential base template has a qualifier, the current template
|
||||
// must match it
|
||||
if (!base_template_parameter.qualifiers().empty() &&
|
||||
(qualifiers() != base_template_parameter.qualifiers()))
|
||||
// If the potential base template has a deduction context (e.g. const&),
|
||||
// the specialization must have the same and possibly more
|
||||
if (!base_template_parameter.deduced_context().empty() &&
|
||||
!util::starts_with(
|
||||
deduced_context(), base_template_parameter.deduced_context()))
|
||||
return 0;
|
||||
|
||||
if (is_template_parameter() &&
|
||||
@@ -126,7 +128,7 @@ int template_parameter::calculate_specialization_match(
|
||||
is_variadic() == is_variadic() &&
|
||||
is_function_template() ==
|
||||
base_template_parameter.is_function_template() &&
|
||||
is_method_template() == base_template_parameter.is_method_template()) {
|
||||
is_member_pointer() == base_template_parameter.is_member_pointer()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -137,7 +139,6 @@ int template_parameter::calculate_specialization_match(
|
||||
maybe_template_parameter_type.has_value() &&
|
||||
!base_template_parameter.is_template_parameter() &&
|
||||
!is_template_parameter()) {
|
||||
|
||||
if (maybe_base_template_parameter_type.value() !=
|
||||
maybe_template_parameter_type.value())
|
||||
return 0;
|
||||
@@ -145,11 +146,20 @@ int template_parameter::calculate_specialization_match(
|
||||
res++;
|
||||
}
|
||||
|
||||
if (base_template_parameter.is_array() && !is_array())
|
||||
return 0;
|
||||
|
||||
if (base_template_parameter.is_array() && is_array())
|
||||
res++;
|
||||
|
||||
if (base_template_parameter.is_function_template() &&
|
||||
!is_function_template())
|
||||
return 0;
|
||||
|
||||
if (base_template_parameter.is_method_template() && !is_method_template())
|
||||
if (base_template_parameter.is_member_pointer() && !is_member_pointer())
|
||||
return 0;
|
||||
|
||||
if (base_template_parameter.is_data_pointer() && !is_data_pointer())
|
||||
return 0;
|
||||
|
||||
if (!base_template_parameter.template_params().empty() &&
|
||||
@@ -214,31 +224,22 @@ bool operator!=(const template_parameter &l, const template_parameter &r)
|
||||
return !(l == r);
|
||||
}
|
||||
|
||||
std::string template_parameter::qualifiers_str() const
|
||||
std::string template_parameter::deduced_context_str() const
|
||||
{
|
||||
std::string res;
|
||||
if (qualifiers_.count(cvqualifier::kConst) == 1)
|
||||
res += "const";
|
||||
std::vector<std::string> deduced_contexts;
|
||||
|
||||
if (is_rvalue_reference())
|
||||
res += "&&";
|
||||
else if (is_lvalue_reference())
|
||||
res += "&";
|
||||
for (const auto &c : deduced_context()) {
|
||||
deduced_contexts.push_back(c.to_string());
|
||||
}
|
||||
|
||||
if (is_pointer())
|
||||
res += "*";
|
||||
|
||||
if(res.empty())
|
||||
return res;
|
||||
|
||||
return " " + res;
|
||||
return fmt::format("{}", fmt::join(deduced_contexts, " "));
|
||||
}
|
||||
|
||||
std::string template_parameter::to_string(
|
||||
const clanguml::common::model::namespace_ &using_namespace, bool relative,
|
||||
bool skip_qualifiers) const
|
||||
{
|
||||
if(is_elipssis())
|
||||
if (is_elipssis())
|
||||
return "...";
|
||||
|
||||
using clanguml::common::model::namespace_;
|
||||
@@ -258,35 +259,41 @@ std::string template_parameter::to_string(
|
||||
"{}({})", return_type, fmt::join(function_args, ","));
|
||||
}
|
||||
|
||||
if (is_method_template()) {
|
||||
assert(template_params().size() > 1);
|
||||
if (is_data_pointer()) {
|
||||
assert(template_params().size() == 2);
|
||||
|
||||
std::string unqualified;
|
||||
if (template_params().size() == 2) {
|
||||
unqualified = fmt::format("{} {}::*",
|
||||
template_params().at(0).to_string(using_namespace, relative),
|
||||
template_params().at(1).to_string(using_namespace, relative));
|
||||
}
|
||||
else {
|
||||
auto it = template_params().begin();
|
||||
auto return_type = it->to_string(using_namespace, relative);
|
||||
it++;
|
||||
auto class_type = it->to_string(using_namespace, relative);
|
||||
it++;
|
||||
std::vector<std::string> args;
|
||||
|
||||
for (; it != template_params().end(); it++) {
|
||||
args.push_back(it->to_string(using_namespace, relative));
|
||||
}
|
||||
|
||||
unqualified = fmt::format("{} ({}::*)({})", return_type, class_type,
|
||||
fmt::join(args, ","));
|
||||
}
|
||||
std::string unqualified = fmt::format("{} {}::*",
|
||||
template_params().at(0).to_string(using_namespace, relative),
|
||||
template_params().at(1).to_string(using_namespace, relative));
|
||||
|
||||
if (skip_qualifiers)
|
||||
return unqualified;
|
||||
else
|
||||
return unqualified + qualifiers_str();
|
||||
else {
|
||||
return util::join(" ", unqualified, deduced_context_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (is_member_pointer()) {
|
||||
assert(template_params().size() > 1);
|
||||
|
||||
auto it = template_params().begin();
|
||||
auto return_type = it->to_string(using_namespace, relative);
|
||||
it++;
|
||||
auto class_type = it->to_string(using_namespace, relative);
|
||||
it++;
|
||||
std::vector<std::string> args;
|
||||
|
||||
for (; it != template_params().end(); it++) {
|
||||
args.push_back(it->to_string(using_namespace, relative));
|
||||
}
|
||||
|
||||
std::string unqualified = fmt::format(
|
||||
"{} ({}::*)({})", return_type, class_type, fmt::join(args, ","));
|
||||
if (skip_qualifiers)
|
||||
return unqualified;
|
||||
else {
|
||||
return util::join(" ", unqualified, deduced_context_str());
|
||||
}
|
||||
}
|
||||
|
||||
std::string res;
|
||||
@@ -339,7 +346,7 @@ std::string template_parameter::to_string(
|
||||
}
|
||||
|
||||
if (!skip_qualifiers)
|
||||
res += qualifiers_str();
|
||||
res = util::join(" ", res, deduced_context_str());
|
||||
|
||||
const auto &maybe_default_value = default_value();
|
||||
if (maybe_default_value) {
|
||||
@@ -362,8 +369,9 @@ bool template_parameter::find_nested_relationships(
|
||||
// If this type argument should be included in the relationship
|
||||
// just add it and skip recursion (e.g. this is a user defined type)
|
||||
const auto maybe_type = type();
|
||||
|
||||
if (maybe_type && should_include(maybe_type.value())) {
|
||||
if (is_pointer() || is_lvalue_reference() || is_rvalue_reference())
|
||||
if (is_association())
|
||||
hint = common::model::relationship_t::kAssociation;
|
||||
|
||||
const auto maybe_id = id();
|
||||
@@ -383,9 +391,7 @@ bool template_parameter::find_nested_relationships(
|
||||
|
||||
if (maybe_id && maybe_arg_type && should_include(*maybe_arg_type)) {
|
||||
|
||||
if (template_argument.is_pointer() ||
|
||||
template_argument.is_lvalue_reference() ||
|
||||
template_argument.is_rvalue_reference())
|
||||
if (template_argument.is_association())
|
||||
hint = common::model::relationship_t::kAssociation;
|
||||
|
||||
nested_relationships.emplace_back(maybe_id.value(), hint);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "common/model/enums.h"
|
||||
#include "common/model/namespace.h"
|
||||
|
||||
#include <deque>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
@@ -31,10 +32,49 @@ enum class template_parameter_kind_t {
|
||||
template_type,
|
||||
template_template_type,
|
||||
non_type_template,
|
||||
argument, // a.k.a. type parameter specialization
|
||||
argument,
|
||||
concept_constraint
|
||||
};
|
||||
|
||||
// TODO: rename to include the pointer and reference
|
||||
enum class cvqualifier { kConst, kVolatile };
|
||||
|
||||
enum class rpqualifier { kLValueReference, kRValueReference, kPointer, kNone };
|
||||
|
||||
struct context {
|
||||
bool is_const;
|
||||
bool is_volatile;
|
||||
rpqualifier pr{rpqualifier::kNone};
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
std::vector<std::string> cv_qualifiers;
|
||||
if (is_const)
|
||||
cv_qualifiers.push_back("const");
|
||||
if (is_volatile)
|
||||
cv_qualifiers.push_back("volatile");
|
||||
|
||||
auto res = fmt::format("{}", fmt::join(cv_qualifiers, " "));
|
||||
|
||||
if (pr == rpqualifier::kPointer)
|
||||
res += "*";
|
||||
else if (pr == rpqualifier::kLValueReference)
|
||||
res += "&";
|
||||
else if (pr == rpqualifier::kRValueReference)
|
||||
res += "&&";
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool operator==(const context &rhs) const
|
||||
{
|
||||
return is_const == rhs.is_const && is_volatile == rhs.is_volatile &&
|
||||
pr == rhs.pr;
|
||||
}
|
||||
|
||||
bool operator!=(const context &rhs) const { return !(rhs == *this); }
|
||||
};
|
||||
|
||||
std::string to_string(template_parameter_kind_t k);
|
||||
|
||||
/// @brief Represents template parameter, template arguments or concept
|
||||
@@ -45,13 +85,6 @@ std::string to_string(template_parameter_kind_t k);
|
||||
/// nested templates
|
||||
class template_parameter {
|
||||
public:
|
||||
enum class cvqualifier {
|
||||
kConst,
|
||||
kVolatile,
|
||||
kLValueReference,
|
||||
kRValueReference
|
||||
};
|
||||
|
||||
static template_parameter make_template_type(const std::string &name,
|
||||
const std::optional<std::string> &default_value = {},
|
||||
bool is_variadic = false)
|
||||
@@ -167,6 +200,15 @@ public:
|
||||
|
||||
void clear_params() { template_params_.clear(); }
|
||||
|
||||
bool is_association() const
|
||||
{
|
||||
return std::any_of(deduced_context().begin(), deduced_context().end(),
|
||||
[](const auto &c) {
|
||||
return c.pr == rpqualifier::kPointer ||
|
||||
c.pr == rpqualifier::kLValueReference;
|
||||
});
|
||||
}
|
||||
|
||||
bool find_nested_relationships(
|
||||
std::vector<std::pair<int64_t, common::model::relationship_t>>
|
||||
&nested_relationships,
|
||||
@@ -186,33 +228,29 @@ public:
|
||||
|
||||
void set_unexposed(bool unexposed) { is_unexposed_ = unexposed; }
|
||||
|
||||
void set_function_template(bool ft) { is_function_template_ = ft; }
|
||||
|
||||
void is_function_template(bool ft) { is_function_template_ = ft; }
|
||||
bool is_function_template() const { return is_function_template_; }
|
||||
|
||||
void set_method_template(bool mt) { is_method_template_ = mt; }
|
||||
void is_member_pointer(bool m) { is_member_pointer_ = m; }
|
||||
bool is_member_pointer() const { return is_member_pointer_; }
|
||||
|
||||
bool is_method_template() const { return is_method_template_; }
|
||||
void is_data_pointer(bool m) { is_data_pointer_ = m; }
|
||||
bool is_data_pointer() const { return is_data_pointer_; }
|
||||
|
||||
void set_qualifier(const cvqualifier q) { qualifiers_.emplace(q); }
|
||||
void is_array(bool a) { is_array_ = a; }
|
||||
bool is_array() const { return is_array_; }
|
||||
|
||||
const std::set<cvqualifier> &qualifiers() const { return qualifiers_; }
|
||||
|
||||
void is_pointer(bool p) { is_pointer_ = p; }
|
||||
bool is_pointer() const { return is_pointer_; }
|
||||
|
||||
void is_lvalue_reference(bool p) { is_lvalue_reference_ = p; }
|
||||
bool is_lvalue_reference() const { return is_lvalue_reference_; }
|
||||
|
||||
void is_rvalue_reference(bool p) { is_rvalue_reference_ = p; }
|
||||
bool is_rvalue_reference() const { return is_rvalue_reference_; }
|
||||
void push_context(const context q) { context_.push_front(q); }
|
||||
const std::deque<context> &deduced_context() const { return context_; }
|
||||
void deduced_context(const std::deque<context> &c) { context_ = c; }
|
||||
|
||||
void is_elipssis(bool e) { is_elipssis_ = e; }
|
||||
bool is_elipssis() const { return is_elipssis_; }
|
||||
|
||||
private:
|
||||
template_parameter() = default;
|
||||
|
||||
std::string qualifiers_str() const;
|
||||
std::string deduced_context_str() const;
|
||||
|
||||
template_parameter_kind_t kind_{template_parameter_kind_t::template_type};
|
||||
|
||||
@@ -239,15 +277,16 @@ private:
|
||||
/// Whether the template parameter is variadic
|
||||
bool is_variadic_{false};
|
||||
|
||||
bool is_pointer_{false};
|
||||
bool is_lvalue_reference_{false};
|
||||
bool is_rvalue_reference_{false};
|
||||
|
||||
bool is_function_template_{false};
|
||||
|
||||
bool is_method_template_{false};
|
||||
bool is_data_pointer_{false};
|
||||
|
||||
std::set<cvqualifier> qualifiers_;
|
||||
bool is_member_pointer_{false};
|
||||
|
||||
bool is_array_{false};
|
||||
|
||||
/// Stores the template parameter/argument deduction context e.g. const&
|
||||
std::deque<context> context_;
|
||||
|
||||
/// Stores optional fully qualified name of constraint for this template
|
||||
/// parameter
|
||||
|
||||
@@ -92,9 +92,26 @@ std::string get_git_toplevel_dir();
|
||||
std::vector<std::string> split(
|
||||
std::string str, std::string_view delimiter, bool skip_empty = true);
|
||||
|
||||
template <typename T, typename F> void erase_if(std::vector<T> &v, F &&f)
|
||||
{
|
||||
v.erase(std::remove_if(v.begin(), v.end(), std::forward<F>(f)), v.end());
|
||||
}
|
||||
|
||||
std::string join(
|
||||
const std::vector<std::string> &toks, std::string_view delimiter);
|
||||
|
||||
template <typename... Args>
|
||||
std::string join(std::string_view delimiter, Args... args)
|
||||
{
|
||||
std::vector<std::string> coll{args...};
|
||||
|
||||
erase_if(coll, [](const auto &s) {
|
||||
return s.find_first_not_of(" \t") == std::string::npos;
|
||||
});
|
||||
|
||||
return fmt::format("{}", fmt::join(coll, delimiter));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Abbreviate string to max_length, and replace last 3 characters
|
||||
* with ellipsis.
|
||||
|
||||
@@ -40,7 +40,6 @@ set(TEST_CASES
|
||||
test_config
|
||||
test_cli_handler
|
||||
test_filters
|
||||
test_template_parser
|
||||
test_thread_pool_executor)
|
||||
|
||||
foreach(TEST_NAME ${TEST_CASES})
|
||||
|
||||
@@ -59,9 +59,9 @@ TEST_CASE("t00051", "[test-case][class]")
|
||||
REQUIRE_THAT(puml, (IsMethod<Public>("ff", "void")));
|
||||
|
||||
REQUIRE_THAT(puml,
|
||||
IsClassTemplate("B",
|
||||
"(lambda at ../../tests/t00051/t00051.cc:43:18)"));
|
||||
//,(lambda at ../../tests/t00051/t00051.cc:43:27)"));
|
||||
IsClassTemplate(
|
||||
"B", "(lambda at ../../tests/t00051/t00051.cc:43:18)"));
|
||||
//,(lambda at ../../tests/t00051/t00051.cc:43:27)"));
|
||||
|
||||
REQUIRE_THAT(puml,
|
||||
IsInstantiation(_A("B<F,FF=F>"),
|
||||
|
||||
@@ -17,7 +17,7 @@ template <typename U> struct A<std::map<std::string, U> &> {
|
||||
template <>
|
||||
struct A<std::map<std::string, std::map<std::string, std::string>> &> { };
|
||||
|
||||
template <typename U> struct A<U ***> {
|
||||
template <typename U> struct A<U **const *> {
|
||||
U ***u;
|
||||
};
|
||||
|
||||
@@ -71,6 +71,14 @@ template <int N> struct A<char[N]> {
|
||||
template <> struct A<char[1000]> {
|
||||
std::vector<char> n;
|
||||
};
|
||||
|
||||
//
|
||||
// template <typename T> struct eval;
|
||||
//
|
||||
// template <template <typename, typename...> class TT, typename T1,
|
||||
// typename... Rest>
|
||||
// struct eval<TT<T1, Rest...>> { };
|
||||
//
|
||||
// eval<A<int>> eA;
|
||||
// eval<std::map<int, float>> eB;
|
||||
}
|
||||
}
|
||||
@@ -36,17 +36,17 @@ TEST_CASE("t00062", "[test-case][class]")
|
||||
REQUIRE_THAT(puml, EndsWith("@enduml\n"));
|
||||
|
||||
// Check if all classes exist
|
||||
REQUIRE_THAT(puml, IsClassTemplate("A", "TTTT"));
|
||||
REQUIRE_THAT(puml, IsClassTemplate("A", "T"));
|
||||
REQUIRE_THAT(puml, IsClassTemplate("A", "U &"));
|
||||
REQUIRE_THAT(puml, IsClassTemplate("A", "U &&"));
|
||||
REQUIRE_THAT(puml, IsClassTemplate("A", "U const&"));
|
||||
REQUIRE_THAT(puml, IsClassTemplate("A", "M C::*"));
|
||||
REQUIRE_THAT(puml, IsClassTemplate("A", "M C::*&&"));
|
||||
REQUIRE_THAT(puml, IsClassTemplate("A", "M C::* &&"));
|
||||
REQUIRE_THAT(puml, IsClassTemplate("A", "M (C::*)(Arg)"));
|
||||
REQUIRE_THAT(puml, IsClassTemplate("A", "int (C::*)(bool)"));
|
||||
REQUIRE_THAT(puml, IsClassTemplate("A", "M (C::*)(Arg)&&"));
|
||||
REQUIRE_THAT(puml, IsClassTemplate("A", "M (C::*)(Arg) &&"));
|
||||
REQUIRE_THAT(puml, IsClassTemplate("A", "M (C::*)(Arg1,Arg2,Arg3)"));
|
||||
REQUIRE_THAT(puml, IsClassTemplate("A", "float (C::*)(int)&&"));
|
||||
REQUIRE_THAT(puml, IsClassTemplate("A", "float (C::*)(int) &&"));
|
||||
|
||||
REQUIRE_THAT(puml, IsClassTemplate("A", "char[N]"));
|
||||
REQUIRE_THAT(puml, IsClassTemplate("A", "char[1000]"));
|
||||
|
||||
@@ -211,13 +211,13 @@ TEST_CASE(
|
||||
|
||||
{
|
||||
auto tp1 = template_parameter::make_template_type({});
|
||||
tp1.set_function_template(true);
|
||||
tp1.is_function_template(true);
|
||||
tp1.add_template_param(template_parameter::make_template_type("Ret"));
|
||||
tp1.add_template_param(template_parameter::make_template_type("Arg1"));
|
||||
tp1.add_template_param(template_parameter::make_template_type("Arg2"));
|
||||
|
||||
auto tp2 = template_parameter::make_argument({});
|
||||
tp2.set_function_template(true);
|
||||
tp2.is_function_template(true);
|
||||
tp2.add_template_param(template_parameter::make_argument("char"));
|
||||
tp2.add_template_param(template_parameter::make_argument("int"));
|
||||
tp2.add_template_param(template_parameter::make_argument("double"));
|
||||
@@ -227,13 +227,13 @@ TEST_CASE(
|
||||
|
||||
{
|
||||
auto tp1 = template_parameter::make_template_type({});
|
||||
tp1.set_function_template(true);
|
||||
tp1.is_function_template(true);
|
||||
tp1.add_template_param(template_parameter::make_template_type("Ret"));
|
||||
tp1.add_template_param(template_parameter::make_template_type("Arg1"));
|
||||
tp1.add_template_param(template_parameter::make_template_type("Arg2"));
|
||||
|
||||
auto tp2 = template_parameter::make_argument({});
|
||||
tp2.set_function_template(false);
|
||||
tp2.is_function_template(false);
|
||||
tp2.add_template_param(template_parameter::make_argument("char"));
|
||||
tp2.add_template_param(template_parameter::make_argument("int"));
|
||||
tp2.add_template_param(template_parameter::make_argument("double"));
|
||||
@@ -243,13 +243,13 @@ TEST_CASE(
|
||||
|
||||
{
|
||||
auto tp1 = template_parameter::make_template_type({});
|
||||
tp1.set_function_template(true);
|
||||
tp1.is_function_template(true);
|
||||
tp1.add_template_param(template_parameter::make_template_type("Ret"));
|
||||
tp1.add_template_param(
|
||||
template_parameter::make_template_type("Args", {}, true));
|
||||
|
||||
auto tp2 = template_parameter::make_argument({});
|
||||
tp2.set_function_template(true);
|
||||
tp2.is_function_template(true);
|
||||
tp2.add_template_param(template_parameter::make_argument("char"));
|
||||
tp2.add_template_param(template_parameter::make_argument("int"));
|
||||
tp2.add_template_param(template_parameter::make_argument("double"));
|
||||
@@ -262,7 +262,7 @@ TEST_CASE(
|
||||
auto sh1 =
|
||||
template_parameter::make_argument("ns1::ns2::signal_handler");
|
||||
auto sh1_t1 = template_parameter::make_template_type({});
|
||||
sh1_t1.set_function_template(true);
|
||||
sh1_t1.is_function_template(true);
|
||||
sh1_t1.add_template_param(
|
||||
template_parameter::make_template_type("Ret"));
|
||||
sh1_t1.add_template_param(
|
||||
@@ -276,7 +276,7 @@ TEST_CASE(
|
||||
auto sh2 =
|
||||
template_parameter::make_argument("ns1::ns2::signal_handler");
|
||||
auto sh2_a1 = template_parameter::make_argument({});
|
||||
sh2_a1.set_function_template(true);
|
||||
sh2_a1.is_function_template(true);
|
||||
sh2_a1.add_template_param(template_parameter::make_argument("void"));
|
||||
sh2_a1.add_template_param(template_parameter::make_argument("int"));
|
||||
auto sh2_a2 = template_parameter::make_argument("bool");
|
||||
@@ -289,13 +289,13 @@ TEST_CASE(
|
||||
|
||||
{
|
||||
auto tp1 = template_parameter::make_template_type({});
|
||||
tp1.set_method_template(true);
|
||||
tp1.is_function_template(true);
|
||||
tp1.add_template_param(template_parameter::make_template_type("Ret"));
|
||||
tp1.add_template_param(template_parameter::make_template_type("C"));
|
||||
tp1.add_template_param(template_parameter::make_template_type("Arg0"));
|
||||
|
||||
auto tp2 = template_parameter::make_template_type({});
|
||||
tp2.set_method_template(true);
|
||||
tp2.is_function_template(true);
|
||||
tp2.add_template_param(template_parameter::make_argument("char"));
|
||||
tp2.add_template_param(template_parameter::make_template_type("C"));
|
||||
tp2.add_template_param(template_parameter::make_argument("double"));
|
||||
@@ -305,13 +305,13 @@ TEST_CASE(
|
||||
|
||||
{
|
||||
auto tp1 = template_parameter::make_template_type({});
|
||||
tp1.set_method_template(true);
|
||||
tp1.is_function_template(true);
|
||||
tp1.add_template_param(template_parameter::make_template_type("Ret"));
|
||||
tp1.add_template_param(template_parameter::make_template_type("C"));
|
||||
tp1.add_template_param(template_parameter::make_template_type("Arg0"));
|
||||
|
||||
auto tp2 = template_parameter::make_template_type({});
|
||||
tp2.set_method_template(true);
|
||||
tp2.is_function_template(true);
|
||||
tp2.add_template_param(template_parameter::make_argument("char"));
|
||||
tp2.add_template_param(template_parameter::make_template_type("C"));
|
||||
tp2.add_template_param(template_parameter::make_argument("double"));
|
||||
|
||||
Reference in New Issue
Block a user