Extremely scary template patch to fix Luigi's partial specialization argument handling bug.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@4398 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Dave Beazley 2003-02-26 17:44:28 +00:00
commit dd74b7ea59
2 changed files with 68 additions and 1 deletions

View file

@ -1879,6 +1879,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
ParmList *temparms;
if (specialized) temparms = CopyParmList($7);
else temparms = CopyParmList(tparms);
/* Create typedef's and arguments */
p = $7;
tp = temparms;
@ -2548,10 +2549,69 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_para
List *tlist;
String *targs = SwigType_templateargs(tname);
tlist = SwigType_parmlist(targs);
/* Printf(stdout,"targs = '%s'\n", targs); */
/* Printf(stdout,"targs = '%s' %s\n", targs, tlist); */
if (!Getattr($$,"sym:weak")) {
Setattr($$,"sym:typename","1");
}
if (Len(tlist) != ParmList_len(Getattr(tempn,"templateparms"))) {
Swig_error(Getfile($$),Getline($$),"Inconsistent argument count in template partial specialization. %d %d\n", Len(tlist), ParmList_len(Getattr(tempn,"templateparms")));
} else {
/* This code builds the argument list for the partial template
specialization. This is a little hairy, but the idea is as
follows:
$3 contains a list of arguments supplied for the template.
For example template<class T>.
tlist is a list of the specialization arguments--which may be
different. For example class<int,T>.
tp is a copy of the arguments in the original template definition.
The patching algorithm walks through the list of supplied
arguments ($3), finds the position in the specialization arguments
(tlist), and then patches the name in the argument list of the
original template.
*/
{
String *pn;
Parm *p, *p1;
int i, nargs;
Parm *tp = CopyParmList(Getattr(tempn,"templateparms"));
nargs = Len(tlist);
p = $3;
while (p) {
for (i = 0; i < nargs; i++){
pn = Getattr(p,"name");
if (Strcmp(pn,Getitem(tlist,i)) == 0) {
int j;
Parm *p1 = tp;
for (j = 0; j < i; j++) {
p1 = nextSibling(p1);
}
Setattr(p1,"name",pn);
Setattr(p1,"partialarg","1");
}
}
p = nextSibling(p);
}
p1 = tp;
i = 0;
while (p1) {
if (!Getattr(p1,"partialarg")) {
Delattr(p1,"name");
Setattr(p1,"type", Getitem(tlist,i));
}
i++;
p1 = nextSibling(p1);
}
Setattr($$,"templateparms",tp);
}
#if 0
/* Patch the parameter list */
if (tempn) {
Parm *p,*p1;
@ -2560,7 +2620,9 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_para
p1 = tp;
while (p && p1) {
String *pn = Getattr(p,"name");
Printf(stdout,"pn = '%s'\n", pn);
if (pn) Setattr(p1,"name",pn);
else Delattr(p1,"name");
pn = Getattr(p,"type");
if (pn) Setattr(p1,"type",pn);
p = nextSibling(p);
@ -2570,6 +2632,7 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_para
} else {
Setattr($$,"templateparms",$3);
}
#endif
Delattr($$,"specialization");
Setattr($$,"partialspecialization","1");
/* Create a specialized name for matching */
@ -2621,6 +2684,7 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_para
Setattr($$,"partialargs",ffname);
Swig_symbol_cadd(ffname,$$);
}
}
Delete(tlist);
Delete(targs);
} else {