@@ -139,13 +139,15 @@ static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch(
139
139
SmallVectorImpl<DeducedTemplateArgument> &Deduced, unsigned TDF,
140
140
bool PartialOrdering = false , bool DeducedFromArrayBound = false );
141
141
142
+ enum class PackFold { ParameterToArgument, ArgumentToParameter };
142
143
static TemplateDeductionResult
143
144
DeduceTemplateArguments (Sema &S, TemplateParameterList *TemplateParams,
144
145
ArrayRef<TemplateArgument> Ps,
145
146
ArrayRef<TemplateArgument> As,
146
147
TemplateDeductionInfo &Info,
147
148
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
148
- bool NumberOfArgumentsMustMatch);
149
+ bool NumberOfArgumentsMustMatch,
150
+ PackFold PackFold = PackFold::ParameterToArgument);
149
151
150
152
static void MarkUsedTemplateParameters (ASTContext &Ctx,
151
153
const TemplateArgument &TemplateArg,
@@ -2550,7 +2552,9 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
2550
2552
ArrayRef<TemplateArgument> As,
2551
2553
TemplateDeductionInfo &Info,
2552
2554
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
2553
- bool NumberOfArgumentsMustMatch) {
2555
+ bool NumberOfArgumentsMustMatch, PackFold PackFold) {
2556
+ if (PackFold == PackFold::ArgumentToParameter)
2557
+ std::swap (Ps, As);
2554
2558
// C++0x [temp.deduct.type]p9:
2555
2559
// If the template argument list of P contains a pack expansion that is not
2556
2560
// the last template argument, the entire template argument list is a
@@ -2581,8 +2585,11 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
2581
2585
return TemplateDeductionResult::MiscellaneousDeductionFailure;
2582
2586
2583
2587
// Perform deduction for this Pi/Ai pair.
2584
- if (auto Result = DeduceTemplateArguments (S, TemplateParams, P,
2585
- As[ArgIdx], Info, Deduced);
2588
+ TemplateArgument Pi = P, Ai = As[ArgIdx];
2589
+ if (PackFold == PackFold::ArgumentToParameter)
2590
+ std::swap (Pi, Ai);
2591
+ if (auto Result =
2592
+ DeduceTemplateArguments (S, TemplateParams, Pi, Ai, Info, Deduced);
2586
2593
Result != TemplateDeductionResult::Success)
2587
2594
return Result;
2588
2595
@@ -2609,9 +2616,12 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
2609
2616
for (; hasTemplateArgumentForDeduction (As, ArgIdx) &&
2610
2617
PackScope.hasNextElement ();
2611
2618
++ArgIdx) {
2619
+ TemplateArgument Pi = Pattern, Ai = As[ArgIdx];
2620
+ if (PackFold == PackFold::ArgumentToParameter)
2621
+ std::swap (Pi, Ai);
2612
2622
// Deduce template arguments from the pattern.
2613
- if (auto Result = DeduceTemplateArguments (S, TemplateParams, Pattern,
2614
- As[ArgIdx] , Info, Deduced);
2623
+ if (auto Result =
2624
+ DeduceTemplateArguments (S, TemplateParams, Pi, Ai , Info, Deduced);
2615
2625
Result != TemplateDeductionResult::Success)
2616
2626
return Result;
2617
2627
@@ -6299,7 +6309,8 @@ bool Sema::isMoreSpecializedThanPrimary(
6299
6309
}
6300
6310
6301
6311
bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs (
6302
- TemplateParameterList *P, TemplateDecl *AArg, SourceLocation Loc) {
6312
+ TemplateParameterList *P, TemplateDecl *AArg, SourceLocation Loc,
6313
+ bool IsDeduced) {
6303
6314
// C++1z [temp.arg.template]p4: (DR 150)
6304
6315
// A template template-parameter P is at least as specialized as a
6305
6316
// template template-argument A if, given the following rewrite to two
@@ -6309,11 +6320,10 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs(
6309
6320
// equivalent partial ordering by performing deduction directly on
6310
6321
// the template parameter lists of the template template parameters.
6311
6322
//
6312
- // Given an invented class template X with the template parameter list of
6313
- // A (including default arguments):
6314
- TemplateName X = Context.getCanonicalTemplateName (TemplateName (AArg));
6315
6323
TemplateParameterList *A = AArg->getTemplateParameters ();
6316
6324
6325
+ // Given an invented class template X with the template parameter list of
6326
+ // A (including default arguments):
6317
6327
// - Each function template has a single function parameter whose type is
6318
6328
// a specialization of X with template arguments corresponding to the
6319
6329
// template parameters from the respective function template
@@ -6356,14 +6366,43 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs(
6356
6366
return false ;
6357
6367
}
6358
6368
6359
- QualType AType = Context.getCanonicalTemplateSpecializationType (X, AArgs);
6360
- QualType PType = Context.getCanonicalTemplateSpecializationType (X, PArgs);
6369
+ // Determine whether P1 is at least as specialized as P2.
6370
+ TemplateDeductionInfo Info (Loc, A->getDepth ());
6371
+ SmallVector<DeducedTemplateArgument, 4 > Deduced;
6372
+ Deduced.resize (A->size ());
6361
6373
6362
6374
// ... the function template corresponding to P is at least as specialized
6363
6375
// as the function template corresponding to A according to the partial
6364
6376
// ordering rules for function templates.
6365
- TemplateDeductionInfo Info (Loc, A->getDepth ());
6366
- return isAtLeastAsSpecializedAs (*this , PType, AType, AArg, Info);
6377
+
6378
+ // Provisional resolution for CWG2398: Regarding temp.arg.template]p4, when
6379
+ // applying the partial ordering rules for function templates on
6380
+ // the rewritten template template parameters:
6381
+ // - In a deduced context, the matching of packs versus fixed-size needs to
6382
+ // be inverted between Ps and As. On non-deduced context, matching needs to
6383
+ // happen both ways, according to [temp.arg.template]p3, but this is
6384
+ // currently implemented as a special case elsewhere.
6385
+ if (::DeduceTemplateArguments (*this , A, AArgs, PArgs, Info, Deduced,
6386
+ /* NumberOfArgumentsMustMatch=*/ false ,
6387
+ IsDeduced ? PackFold::ArgumentToParameter
6388
+ : PackFold::ParameterToArgument) !=
6389
+ TemplateDeductionResult::Success)
6390
+ return false ;
6391
+
6392
+ SmallVector<TemplateArgument, 4 > DeducedArgs (Deduced.begin (), Deduced.end ());
6393
+ Sema::InstantiatingTemplate Inst (*this , Info.getLocation (), AArg, DeducedArgs,
6394
+ Info);
6395
+ if (Inst.isInvalid ())
6396
+ return false ;
6397
+
6398
+ bool AtLeastAsSpecialized;
6399
+ runWithSufficientStackSpace (Info.getLocation (), [&] {
6400
+ AtLeastAsSpecialized =
6401
+ ::FinishTemplateArgumentDeduction (
6402
+ *this , AArg, /* IsPartialOrdering=*/ true , PArgs, Deduced, Info) ==
6403
+ TemplateDeductionResult::Success;
6404
+ });
6405
+ return AtLeastAsSpecialized;
6367
6406
}
6368
6407
6369
6408
namespace {
0 commit comments