Fixed handling of qualifiers in template parameter deduced contexts
This commit is contained in:
@@ -498,8 +498,14 @@ clang::QualType template_builder::consume_context(
|
|||||||
bool try_again{false};
|
bool try_again{false};
|
||||||
common::model::context ctx;
|
common::model::context ctx;
|
||||||
|
|
||||||
ctx.is_const = type.isConstQualified();
|
if (type->isPointerType() || type->isReferenceType()) {
|
||||||
ctx.is_volatile = type.isVolatileQualified();
|
if (type.isConstQualified() || type.isVolatileQualified()) {
|
||||||
|
ctx.is_ref_const = type.isConstQualified();
|
||||||
|
ctx.is_ref_volatile = type.isVolatileQualified();
|
||||||
|
|
||||||
|
try_again = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (type->isLValueReferenceType()) {
|
if (type->isLValueReferenceType()) {
|
||||||
ctx.pr = common::model::rpqualifier::kLValueReference;
|
ctx.pr = common::model::rpqualifier::kLValueReference;
|
||||||
@@ -509,24 +515,51 @@ clang::QualType template_builder::consume_context(
|
|||||||
ctx.pr = common::model::rpqualifier::kRValueReference;
|
ctx.pr = common::model::rpqualifier::kRValueReference;
|
||||||
try_again = true;
|
try_again = true;
|
||||||
}
|
}
|
||||||
|
else if (type->isMemberFunctionPointerType()) {
|
||||||
|
const auto ref_qualifier = type->getPointeeType()
|
||||||
|
->getAs<clang::FunctionProtoType>()
|
||||||
|
->getRefQualifier();
|
||||||
|
|
||||||
|
if (ref_qualifier == clang::RefQualifierKind::RQ_RValue) {
|
||||||
|
ctx.pr = common::model::rpqualifier::kRValueReference;
|
||||||
|
try_again = true;
|
||||||
|
}
|
||||||
|
else if (ref_qualifier == clang::RefQualifierKind::RQ_LValue) {
|
||||||
|
ctx.pr = common::model::rpqualifier::kLValueReference;
|
||||||
|
try_again = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (type->isPointerType()) {
|
else if (type->isPointerType()) {
|
||||||
ctx.pr = common::model::rpqualifier::kPointer;
|
ctx.pr = common::model::rpqualifier::kPointer;
|
||||||
try_again = true;
|
try_again = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type.isConstQualified() || type.isVolatileQualified()) {
|
|
||||||
ctx.is_const = type.isConstQualified();
|
|
||||||
ctx.is_volatile = type.isVolatileQualified();
|
|
||||||
|
|
||||||
try_again = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (try_again) {
|
if (try_again) {
|
||||||
type = type.getNonReferenceType().getUnqualifiedType();
|
if (type->isPointerType()) {
|
||||||
if (type->isPointerType())
|
if (type->getPointeeType().isConstQualified())
|
||||||
type = type->getPointeeType();
|
ctx.is_const = true;
|
||||||
|
if (type->getPointeeType().isVolatileQualified())
|
||||||
|
ctx.is_volatile = true;
|
||||||
|
|
||||||
|
type = type->getPointeeType().getUnqualifiedType();
|
||||||
|
}
|
||||||
|
else if (type->isReferenceType()) {
|
||||||
|
if (type.getNonReferenceType().isConstQualified())
|
||||||
|
ctx.is_const = true;
|
||||||
|
if (type.getNonReferenceType().isVolatileQualified())
|
||||||
|
ctx.is_volatile = true;
|
||||||
|
|
||||||
|
type = type.getNonReferenceType().getUnqualifiedType();
|
||||||
|
}
|
||||||
|
else if (type.isConstQualified() || type.isVolatileQualified()) {
|
||||||
|
ctx.is_const = type.isConstQualified();
|
||||||
|
ctx.is_volatile = type.isVolatileQualified();
|
||||||
|
}
|
||||||
|
|
||||||
tp.push_context(std::move(ctx));
|
tp.push_context(std::move(ctx));
|
||||||
|
|
||||||
|
if (type->isMemberFunctionPointerType())
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return type;
|
return type;
|
||||||
@@ -571,7 +604,7 @@ template_parameter template_builder::process_type_argument(
|
|||||||
if (argument)
|
if (argument)
|
||||||
return *argument;
|
return *argument;
|
||||||
|
|
||||||
argument = try_as_lamda(cls, template_decl, type);
|
argument = try_as_lambda(cls, template_decl, type);
|
||||||
|
|
||||||
if (argument)
|
if (argument)
|
||||||
return *argument;
|
return *argument;
|
||||||
@@ -998,7 +1031,7 @@ std::optional<template_parameter> template_builder::try_as_template_parm_type(
|
|||||||
return argument;
|
return argument;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<template_parameter> template_builder::try_as_lamda(
|
std::optional<template_parameter> template_builder::try_as_lambda(
|
||||||
const clang::NamedDecl *cls, const clang::TemplateDecl *template_decl,
|
const clang::NamedDecl *cls, const clang::TemplateDecl *template_decl,
|
||||||
clang::QualType &type)
|
clang::QualType &type)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ public:
|
|||||||
const clang::NamedDecl *cls, const clang::TemplateDecl *template_decl,
|
const clang::NamedDecl *cls, const clang::TemplateDecl *template_decl,
|
||||||
clang::QualType &type);
|
clang::QualType &type);
|
||||||
|
|
||||||
std::optional<template_parameter> try_as_lamda(const clang::NamedDecl *cls,
|
std::optional<template_parameter> try_as_lambda(const clang::NamedDecl *cls,
|
||||||
const clang::TemplateDecl *template_decl, clang::QualType &type);
|
const clang::TemplateDecl *template_decl, clang::QualType &type);
|
||||||
|
|
||||||
std::optional<template_parameter> try_as_record_type(
|
std::optional<template_parameter> try_as_record_type(
|
||||||
|
|||||||
@@ -23,6 +23,41 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace clanguml::common::model {
|
namespace clanguml::common::model {
|
||||||
|
|
||||||
|
std::string context::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 += "&&";
|
||||||
|
|
||||||
|
if (is_ref_const)
|
||||||
|
res += " const";
|
||||||
|
if (is_ref_volatile)
|
||||||
|
res += " volatile";
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool context::operator==(const context &rhs) const
|
||||||
|
{
|
||||||
|
return is_const == rhs.is_const && is_volatile == rhs.is_volatile &&
|
||||||
|
is_ref_const == rhs.is_ref_const &&
|
||||||
|
is_ref_volatile == rhs.is_ref_volatile && pr == rhs.pr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool context::operator!=(const context &rhs) const { return !(rhs == *this); }
|
||||||
|
|
||||||
std::string to_string(template_parameter_kind_t k)
|
std::string to_string(template_parameter_kind_t k)
|
||||||
{
|
{
|
||||||
switch (k) {
|
switch (k) {
|
||||||
@@ -42,6 +77,67 @@ std::string to_string(template_parameter_kind_t k)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template_parameter template_parameter::make_template_type(
|
||||||
|
const std::string &name, const std::optional<std::string> &default_value,
|
||||||
|
bool is_variadic)
|
||||||
|
{
|
||||||
|
template_parameter p;
|
||||||
|
p.set_kind(template_parameter_kind_t::template_type);
|
||||||
|
p.set_name(name);
|
||||||
|
p.is_variadic(is_variadic);
|
||||||
|
p.is_template_parameter(true);
|
||||||
|
if (default_value)
|
||||||
|
p.set_default_value(default_value.value());
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
template_parameter template_parameter::make_template_template_type(
|
||||||
|
const std::string &name, const std::optional<std::string> &default_value,
|
||||||
|
bool is_variadic)
|
||||||
|
{
|
||||||
|
template_parameter p;
|
||||||
|
p.set_kind(template_parameter_kind_t::template_template_type);
|
||||||
|
p.set_name(name + "<>");
|
||||||
|
if (default_value)
|
||||||
|
p.set_default_value(default_value.value());
|
||||||
|
p.is_variadic(is_variadic);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
template_parameter template_parameter::make_non_type_template(
|
||||||
|
const std::string &type, const std::optional<std::string> &name,
|
||||||
|
const std::optional<std::string> &default_value, bool is_variadic)
|
||||||
|
{
|
||||||
|
template_parameter p;
|
||||||
|
p.set_kind(template_parameter_kind_t::non_type_template);
|
||||||
|
p.set_type(type);
|
||||||
|
if (name)
|
||||||
|
p.set_name(name.value());
|
||||||
|
if (default_value)
|
||||||
|
p.set_default_value(default_value.value());
|
||||||
|
p.is_variadic(is_variadic);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
template_parameter template_parameter::make_argument(
|
||||||
|
const std::string &type, const std::optional<std::string> &default_value)
|
||||||
|
{
|
||||||
|
template_parameter p;
|
||||||
|
p.set_kind(template_parameter_kind_t::argument);
|
||||||
|
p.set_type(type);
|
||||||
|
if (default_value)
|
||||||
|
p.set_default_value(default_value.value());
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
template_parameter template_parameter::make_unexposed_argument(
|
||||||
|
const std::string &type, const std::optional<std::string> &default_value)
|
||||||
|
{
|
||||||
|
template_parameter p = make_argument(type, default_value);
|
||||||
|
p.set_unexposed(true);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
void template_parameter::set_type(const std::string &type)
|
void template_parameter::set_type(const std::string &type)
|
||||||
{
|
{
|
||||||
assert(kind_ != template_parameter_kind_t::template_type);
|
assert(kind_ != template_parameter_kind_t::template_type);
|
||||||
@@ -410,6 +506,27 @@ bool template_parameter::find_nested_relationships(
|
|||||||
return added_aggregation_relationship;
|
return added_aggregation_relationship;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool template_parameter::is_template_parameter() const
|
||||||
|
{
|
||||||
|
return is_template_parameter_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void template_parameter::is_template_parameter(bool is_template_parameter)
|
||||||
|
{
|
||||||
|
is_template_parameter_ = is_template_parameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool template_parameter::is_template_template_parameter() const
|
||||||
|
{
|
||||||
|
return is_template_template_parameter_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void template_parameter::is_template_template_parameter(
|
||||||
|
bool is_template_template_parameter)
|
||||||
|
{
|
||||||
|
is_template_template_parameter_ = is_template_template_parameter;
|
||||||
|
}
|
||||||
|
|
||||||
void template_parameter::set_concept_constraint(std::string constraint)
|
void template_parameter::set_concept_constraint(std::string constraint)
|
||||||
{
|
{
|
||||||
concept_constraint_ = std::move(constraint);
|
concept_constraint_ = std::move(constraint);
|
||||||
@@ -420,6 +537,66 @@ const std::optional<std::string> &template_parameter::concept_constraint() const
|
|||||||
return concept_constraint_;
|
return concept_constraint_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool template_parameter::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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
template_parameter_kind_t template_parameter::kind() const { return kind_; }
|
||||||
|
|
||||||
|
void template_parameter::set_kind(template_parameter_kind_t kind)
|
||||||
|
{
|
||||||
|
kind_ = kind;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool template_parameter::is_unexposed() const { return is_unexposed_; }
|
||||||
|
|
||||||
|
void template_parameter::set_unexposed(bool unexposed)
|
||||||
|
{
|
||||||
|
is_unexposed_ = unexposed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void template_parameter::is_function_template(bool ft)
|
||||||
|
{
|
||||||
|
is_function_template_ = ft;
|
||||||
|
}
|
||||||
|
bool template_parameter::is_function_template() const
|
||||||
|
{
|
||||||
|
return is_function_template_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void template_parameter::is_member_pointer(bool m) { is_member_pointer_ = m; }
|
||||||
|
bool template_parameter::is_member_pointer() const
|
||||||
|
{
|
||||||
|
return is_member_pointer_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void template_parameter::is_data_pointer(bool m) { is_data_pointer_ = m; }
|
||||||
|
bool template_parameter::is_data_pointer() const { return is_data_pointer_; }
|
||||||
|
|
||||||
|
void template_parameter::is_array(bool a) { is_array_ = a; }
|
||||||
|
bool template_parameter::is_array() const { return is_array_; }
|
||||||
|
|
||||||
|
void template_parameter::push_context(const context q)
|
||||||
|
{
|
||||||
|
context_.push_front(q);
|
||||||
|
}
|
||||||
|
const std::deque<context> &template_parameter::deduced_context() const
|
||||||
|
{
|
||||||
|
return context_;
|
||||||
|
}
|
||||||
|
void template_parameter::deduced_context(const std::deque<context> &c)
|
||||||
|
{
|
||||||
|
context_ = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void template_parameter::is_elipssis(bool e) { is_elipssis_ = e; }
|
||||||
|
bool template_parameter::is_elipssis() const { return is_elipssis_; }
|
||||||
|
|
||||||
int calculate_template_params_specialization_match(
|
int calculate_template_params_specialization_match(
|
||||||
const std::vector<template_parameter> &specialization_params,
|
const std::vector<template_parameter> &specialization_params,
|
||||||
const std::vector<template_parameter> &template_params)
|
const std::vector<template_parameter> &template_params)
|
||||||
|
|||||||
@@ -35,118 +35,56 @@ enum class template_parameter_kind_t {
|
|||||||
argument,
|
argument,
|
||||||
concept_constraint
|
concept_constraint
|
||||||
};
|
};
|
||||||
|
std::string to_string(template_parameter_kind_t k);
|
||||||
// TODO: rename to include the pointer and reference
|
|
||||||
enum class cvqualifier { kConst, kVolatile };
|
|
||||||
|
|
||||||
enum class rpqualifier { kLValueReference, kRValueReference, kPointer, kNone };
|
enum class rpqualifier { kLValueReference, kRValueReference, kPointer, kNone };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This struct manages a single level of template deduced context, e.g.
|
||||||
|
* & or const*
|
||||||
|
*/
|
||||||
struct context {
|
struct context {
|
||||||
bool is_const;
|
bool is_const{false};
|
||||||
bool is_volatile;
|
bool is_volatile{false};
|
||||||
|
bool is_ref_const{false};
|
||||||
|
bool is_ref_volatile{false};
|
||||||
rpqualifier pr{rpqualifier::kNone};
|
rpqualifier pr{rpqualifier::kNone};
|
||||||
|
|
||||||
std::string to_string() const
|
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, " "));
|
bool operator==(const context &rhs) const;
|
||||||
|
bool operator!=(const context &rhs) const;
|
||||||
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
|
||||||
/// @brief Represents template parameter, template arguments or concept
|
* constraints
|
||||||
/// constraints
|
*
|
||||||
///
|
* This class can represent both template parameter and template arguments,
|
||||||
/// This class can represent both template parameter and template arguments,
|
* including variadic parameters and instantiations with
|
||||||
/// including variadic parameters and instantiations with
|
* nested templates
|
||||||
/// nested templates
|
*/
|
||||||
class template_parameter {
|
class template_parameter {
|
||||||
public:
|
public:
|
||||||
static template_parameter make_template_type(const std::string &name,
|
static template_parameter make_template_type(const std::string &name,
|
||||||
const std::optional<std::string> &default_value = {},
|
const std::optional<std::string> &default_value = {},
|
||||||
bool is_variadic = false)
|
bool is_variadic = false);
|
||||||
{
|
|
||||||
template_parameter p;
|
|
||||||
p.set_kind(template_parameter_kind_t::template_type);
|
|
||||||
p.set_name(name);
|
|
||||||
p.is_variadic(is_variadic);
|
|
||||||
p.is_template_parameter(true);
|
|
||||||
if (default_value)
|
|
||||||
p.set_default_value(default_value.value());
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static template_parameter make_template_template_type(
|
static template_parameter make_template_template_type(
|
||||||
const std::string &name,
|
const std::string &name,
|
||||||
const std::optional<std::string> &default_value = {},
|
const std::optional<std::string> &default_value = {},
|
||||||
bool is_variadic = false)
|
bool is_variadic = false);
|
||||||
{
|
|
||||||
template_parameter p;
|
|
||||||
p.set_kind(template_parameter_kind_t::template_template_type);
|
|
||||||
p.set_name(name + "<>");
|
|
||||||
if (default_value)
|
|
||||||
p.set_default_value(default_value.value());
|
|
||||||
p.is_variadic(is_variadic);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static template_parameter make_non_type_template(const std::string &type,
|
static template_parameter make_non_type_template(const std::string &type,
|
||||||
const std::optional<std::string> &name,
|
const std::optional<std::string> &name,
|
||||||
const std::optional<std::string> &default_value = {},
|
const std::optional<std::string> &default_value = {},
|
||||||
bool is_variadic = false)
|
bool is_variadic = false);
|
||||||
{
|
|
||||||
template_parameter p;
|
|
||||||
p.set_kind(template_parameter_kind_t::non_type_template);
|
|
||||||
p.set_type(type);
|
|
||||||
if (name)
|
|
||||||
p.set_name(name.value());
|
|
||||||
if (default_value)
|
|
||||||
p.set_default_value(default_value.value());
|
|
||||||
p.is_variadic(is_variadic);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static template_parameter make_argument(const std::string &type,
|
static template_parameter make_argument(const std::string &type,
|
||||||
const std::optional<std::string> &default_value = {})
|
const std::optional<std::string> &default_value = {});
|
||||||
{
|
|
||||||
template_parameter p;
|
|
||||||
p.set_kind(template_parameter_kind_t::argument);
|
|
||||||
p.set_type(type);
|
|
||||||
if (default_value)
|
|
||||||
p.set_default_value(default_value.value());
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static template_parameter make_unexposed_argument(const std::string &type,
|
static template_parameter make_unexposed_argument(const std::string &type,
|
||||||
const std::optional<std::string> &default_value = {})
|
const std::optional<std::string> &default_value = {});
|
||||||
{
|
|
||||||
template_parameter p = make_argument(type, default_value);
|
|
||||||
p.set_unexposed(true);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_type(const std::string &type);
|
void set_type(const std::string &type);
|
||||||
std::optional<std::string> type() const;
|
std::optional<std::string> type() const;
|
||||||
@@ -171,22 +109,13 @@ public:
|
|||||||
friend bool operator!=(
|
friend bool operator!=(
|
||||||
const template_parameter &l, const template_parameter &r);
|
const template_parameter &l, const template_parameter &r);
|
||||||
|
|
||||||
bool is_template_parameter() const { return is_template_parameter_; }
|
bool is_template_parameter() const;
|
||||||
|
|
||||||
void is_template_parameter(bool is_template_parameter)
|
void is_template_parameter(bool is_template_parameter);
|
||||||
{
|
|
||||||
is_template_parameter_ = is_template_parameter;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_template_template_parameter() const
|
bool is_template_template_parameter() const;
|
||||||
{
|
|
||||||
return is_template_template_parameter_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void is_template_template_parameter(bool is_template_template_parameter)
|
void is_template_template_parameter(bool is_template_template_parameter);
|
||||||
{
|
|
||||||
is_template_template_parameter_ = is_template_template_parameter;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string to_string(
|
std::string to_string(
|
||||||
const clanguml::common::model::namespace_ &using_namespace,
|
const clanguml::common::model::namespace_ &using_namespace,
|
||||||
@@ -200,14 +129,7 @@ public:
|
|||||||
|
|
||||||
void clear_params() { template_params_.clear(); }
|
void clear_params() { template_params_.clear(); }
|
||||||
|
|
||||||
bool is_association() const
|
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(
|
bool find_nested_relationships(
|
||||||
std::vector<std::pair<int64_t, common::model::relationship_t>>
|
std::vector<std::pair<int64_t, common::model::relationship_t>>
|
||||||
@@ -220,32 +142,32 @@ public:
|
|||||||
|
|
||||||
const std::optional<std::string> &concept_constraint() const;
|
const std::optional<std::string> &concept_constraint() const;
|
||||||
|
|
||||||
template_parameter_kind_t kind() const { return kind_; }
|
template_parameter_kind_t kind() const;
|
||||||
|
|
||||||
void set_kind(template_parameter_kind_t kind) { kind_ = kind; }
|
void set_kind(template_parameter_kind_t kind);
|
||||||
|
|
||||||
bool is_unexposed() const { return is_unexposed_; }
|
bool is_unexposed() const;
|
||||||
|
|
||||||
void set_unexposed(bool unexposed) { is_unexposed_ = unexposed; }
|
void set_unexposed(bool unexposed);
|
||||||
|
|
||||||
void is_function_template(bool ft) { is_function_template_ = ft; }
|
void is_function_template(bool ft);
|
||||||
bool is_function_template() const { return is_function_template_; }
|
bool is_function_template() const;
|
||||||
|
|
||||||
void is_member_pointer(bool m) { is_member_pointer_ = m; }
|
void is_member_pointer(bool m);
|
||||||
bool is_member_pointer() const { return is_member_pointer_; }
|
bool is_member_pointer() const;
|
||||||
|
|
||||||
void is_data_pointer(bool m) { is_data_pointer_ = m; }
|
void is_data_pointer(bool m);
|
||||||
bool is_data_pointer() const { return is_data_pointer_; }
|
bool is_data_pointer() const;
|
||||||
|
|
||||||
void is_array(bool a) { is_array_ = a; }
|
void is_array(bool a);
|
||||||
bool is_array() const { return is_array_; }
|
bool is_array() const;
|
||||||
|
|
||||||
void push_context(const context q) { context_.push_front(q); }
|
void push_context(const context q);
|
||||||
const std::deque<context> &deduced_context() const { return context_; }
|
const std::deque<context> &deduced_context() const;
|
||||||
void deduced_context(const std::deque<context> &c) { context_ = c; }
|
void deduced_context(const std::deque<context> &c);
|
||||||
|
|
||||||
void is_elipssis(bool e) { is_elipssis_ = e; }
|
void is_elipssis(bool e);
|
||||||
bool is_elipssis() const { return is_elipssis_; }
|
bool is_elipssis() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template_parameter() = default;
|
template_parameter() = default;
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ template <typename U> struct A<U **const *> {
|
|||||||
U ***u;
|
U ***u;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename U> struct A<U const *const volatile> {
|
||||||
|
U ***u;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename U> struct A<U &&> {
|
template <typename U> struct A<U &&> {
|
||||||
U &&u;
|
U &&u;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user