Fixed matching template instantiation to templates with variadic params in the middle

This commit is contained in:
Bartek Kryza
2023-04-05 00:44:27 +02:00
parent 425a13ec5b
commit 2b951fe170
2 changed files with 50 additions and 6 deletions

View File

@@ -114,9 +114,13 @@ int template_parameter::calculate_specialization_match(
int res{0}; int res{0};
if (ct.type().has_value() && type().has_value() && if (ct.type().has_value() && type().has_value() &&
!ct.is_template_parameter() && !is_template_parameter() && !ct.is_template_parameter() && !is_template_parameter()) {
ct.type().value() != type().value())
if (ct.type().value() != type().value())
return 0; return 0;
else
res++;
}
if (ct.is_function_template() && !is_function_template()) if (ct.is_function_template() && !is_function_template())
return 0; return 0;
@@ -143,15 +147,41 @@ int template_parameter::calculate_specialization_match(
res += match; res += match;
// Add 1 point for argument match // Add 1 point if the current specialization param is an argument
// as it's a more specific match than 2 template params
if (!specialization_params.at(arg_index).is_template_parameter()) if (!specialization_params.at(arg_index).is_template_parameter())
res++; res++;
arg_index++; arg_index++;
} }
if (arg_index == specialization_params.size()) if (arg_index == specialization_params.size()) {
// Check also backwards to make sure that trailing non-variadic
// params match after a variadic parameter
template_index = template_params.size() - 1;
arg_index = specialization_params.size() - 1;
while (true) {
auto match = specialization_params.at(arg_index)
.calculate_specialization_match(
template_params.at(template_index));
if (match == 0) {
return 0;
}
if (arg_index == 0 || template_index == 0)
break;
arg_index--;
if (!template_params.at(template_index).is_variadic())
template_index--;
else
break;
}
return res; return res;
}
else else
return 0; return 0;
} }
@@ -160,7 +190,7 @@ int template_parameter::calculate_specialization_match(
!is_template_parameter()) !is_template_parameter())
return 1; return 1;
return 0; return res;
} }
void template_parameter::add_template_param(template_parameter &&ct) void template_parameter::add_template_param(template_parameter &&ct)

View File

@@ -125,6 +125,20 @@ TEST_CASE(
CHECK(tp2.calculate_specialization_match(tp1)); CHECK(tp2.calculate_specialization_match(tp1));
} }
{
auto tp1 = template_parameter::make_argument("tuple");
tp1.add_template_param(
template_parameter::make_template_type("Args", {}, true));
tp1.add_template_param(template_parameter::make_argument("int"));
auto tp2 = template_parameter::make_argument("tuple");
tp2.add_template_param(template_parameter::make_argument("char"));
tp2.add_template_param(template_parameter::make_argument("double"));
tp2.add_template_param(template_parameter::make_argument("int"));
CHECK(tp2.calculate_specialization_match(tp1));
}
{ {
auto tp1 = template_parameter::make_argument("tuple"); auto tp1 = template_parameter::make_argument("tuple");
tp1.add_template_param( tp1.add_template_param(