mirror of https://github.com/swig/swig
%implicitconv is improved for overloaded functions.
Like in C++, the methods with the actual types are considered before trying implicit conversions.
This commit is contained in:
parent
1cc735df5e
commit
b58dabced9
|
@ -5,6 +5,26 @@ See the RELEASENOTES file for a summary of changes in each release.
|
|||
Version 2.0.11 (in progress)
|
||||
============================
|
||||
|
||||
2013-08-28: wsfulton
|
||||
[Python] %implicitconv is improved for overloaded functions. Like in C++, the methods
|
||||
with the actual types are considered before trying implicit conversions. Example:
|
||||
|
||||
%implicitconv A;
|
||||
struct A {
|
||||
A(int i);
|
||||
};
|
||||
class CCC {
|
||||
public:
|
||||
int xx(int i) { return 11; }
|
||||
int xx(const A& i) { return 22; }
|
||||
};
|
||||
|
||||
The following python code:
|
||||
|
||||
CCC().xx(-1)
|
||||
|
||||
will now return 11 instead of 22 - the implicit conversion is not done.
|
||||
|
||||
2013-08-23: olly
|
||||
[Python] Fix clang++ warning in generated wrapper code.
|
||||
|
||||
|
|
|
@ -84,3 +84,33 @@
|
|||
int get_AA_val(AA a) { return a.ii; }
|
||||
int get_AA_ref(const AA& a) { return a.ii; }
|
||||
}
|
||||
|
||||
|
||||
/****************** Overloading priority *********************/
|
||||
|
||||
%inline %{
|
||||
class BBB {
|
||||
public:
|
||||
BBB(const B &) {}
|
||||
};
|
||||
|
||||
class CCC {
|
||||
public:
|
||||
CCC(const BBB &) : checkvalue(0) {}
|
||||
int xx(int i) { return 11; }
|
||||
int xx(const A& i) { return 22; }
|
||||
int yy(int i, int j) { return 111; }
|
||||
int yy(const A& i, const A& j) { return 222; }
|
||||
int checkvalue;
|
||||
};
|
||||
%}
|
||||
|
||||
// CCC(const BBB &) was being called instead of this constructor (independent of being added via %extend)
|
||||
%extend CCC {
|
||||
CCC(const B& b) {
|
||||
CCC* ccc = new CCC(b);
|
||||
ccc->checkvalue = 10;
|
||||
return ccc;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -114,3 +114,12 @@ try:
|
|||
raise RuntimeError
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
|
||||
### overloading priority test ###
|
||||
|
||||
ccc = CCC(B())
|
||||
check(ccc.checkvalue, 10)
|
||||
check(ccc.xx(123), 11)
|
||||
check(ccc.yy(123, 123), 111)
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ struct Overloaded {
|
|||
int argc; /* Argument count */
|
||||
ParmList *parms; /* Parameters used for overload check */
|
||||
int error; /* Ambiguity error */
|
||||
bool implicitconv_function; /* For ordering implicitconv functions*/
|
||||
};
|
||||
|
||||
static int fast_dispatch_mode = 0;
|
||||
|
@ -40,6 +41,32 @@ void Wrapper_cast_dispatch_mode_set(int flag) {
|
|||
cast_dispatch_mode = flag;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* mark_implicitconv_function()
|
||||
*
|
||||
* Mark function if it contains an implicitconv type in the parameter list
|
||||
* ----------------------------------------------------------------------------- */
|
||||
static void mark_implicitconv_function(Overloaded& onode) {
|
||||
Parm *parms = onode.parms;
|
||||
if (parms) {
|
||||
bool is_implicitconv_function = false;
|
||||
Parm *p = parms;
|
||||
while (p) {
|
||||
if (checkAttribute(p, "tmap:in:numinputs", "0")) {
|
||||
p = Getattr(p, "tmap:in:next");
|
||||
continue;
|
||||
}
|
||||
if (GetFlag(p, "implicitconv")) {
|
||||
is_implicitconv_function = true;
|
||||
break;
|
||||
}
|
||||
p = nextSibling(p);
|
||||
}
|
||||
if (is_implicitconv_function)
|
||||
onode.implicitconv_function = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_overload_rank()
|
||||
*
|
||||
|
@ -85,6 +112,9 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
|
|||
nodes[nnodes].parms = Getattr(c, "wrap:parms");
|
||||
nodes[nnodes].argc = emit_num_required(nodes[nnodes].parms);
|
||||
nodes[nnodes].error = 0;
|
||||
nodes[nnodes].implicitconv_function = false;
|
||||
|
||||
mark_implicitconv_function(nodes[nnodes]);
|
||||
nnodes++;
|
||||
}
|
||||
c = Getattr(c, "sym:nextSibling");
|
||||
|
@ -287,12 +317,30 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
|
|||
List *result = NewList();
|
||||
{
|
||||
int i;
|
||||
int argc_changed_index = -1;
|
||||
for (i = 0; i < nnodes; i++) {
|
||||
if (nodes[i].error)
|
||||
Setattr(nodes[i].n, "overload:ignore", "1");
|
||||
Append(result, nodes[i].n);
|
||||
// Printf(stdout,"[ %d ] %s\n", i, ParmList_errorstr(nodes[i].parms));
|
||||
// Swig_print_node(nodes[i].n);
|
||||
// Printf(stdout,"[ %d ] %d %s\n", i, nodes[i].implicitconv_function, ParmList_errorstr(nodes[i].parms));
|
||||
// Swig_print_node(nodes[i].n);
|
||||
if (i == nnodes-1 || nodes[i].argc != nodes[i+1].argc) {
|
||||
if (argc_changed_index+2 < nnodes && (nodes[argc_changed_index+1].argc == nodes[argc_changed_index+2].argc)) {
|
||||
// Add additional implicitconv functions in same order as already ranked.
|
||||
// Consider overloaded functions by argument count... only add additional implicitconv functions if
|
||||
// the number of functions with the same arg count > 1, ie, only if overloaded by same argument count.
|
||||
int j;
|
||||
for (j = argc_changed_index + 1; j <= i; j++) {
|
||||
if (nodes[j].implicitconv_function) {
|
||||
SetFlag(nodes[j].n, "implicitconvtypecheckoff");
|
||||
Append(result, nodes[j].n);
|
||||
// Printf(stdout,"[ %d ] %d + %s\n", j, nodes[j].implicitconv_function, ParmList_errorstr(nodes[j].parms));
|
||||
// Swig_print_node(nodes[j].n);
|
||||
}
|
||||
}
|
||||
}
|
||||
argc_changed_index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -302,20 +350,22 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
|
|||
// * print_typecheck()
|
||||
// * ----------------------------------------------------------------------------- */
|
||||
|
||||
static bool print_typecheck(String *f, int j, Parm *pj) {
|
||||
static bool print_typecheck(String *f, int j, Parm *pj, bool implicitconvtypecheckoff) {
|
||||
char tmp[256];
|
||||
sprintf(tmp, Char(argv_template_string), j);
|
||||
String *tm = Getattr(pj, "tmap:typecheck");
|
||||
if (tm) {
|
||||
tm = Copy(tm);
|
||||
Replaceid(tm, Getattr(pj, "lname"), "_v");
|
||||
String *conv = Getattr(pj, "implicitconv");
|
||||
if (conv) {
|
||||
if (conv && !implicitconvtypecheckoff) {
|
||||
Replaceall(tm, "$implicitconv", conv);
|
||||
} else {
|
||||
Replaceall(tm, "$implicitconv", "0");
|
||||
}
|
||||
Replaceall(tm, "$input", tmp);
|
||||
Printv(f, tm, "\n", NIL);
|
||||
Delete(tm);
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
|
@ -715,6 +765,7 @@ String *Swig_overload_dispatch(Node *n, const_String_or_char_ptr fmt, int *maxar
|
|||
for (i = 0; i < nfunc; i++) {
|
||||
Node *ni = Getitem(dispatch, i);
|
||||
Parm *pi = Getattr(ni, "wrap:parms");
|
||||
bool implicitconvtypecheckoff = GetFlag(ni, "implicitconvtypecheckoff") != 0;
|
||||
int num_required = emit_num_required(pi);
|
||||
int num_arguments = emit_num_arguments(pi);
|
||||
if (GetFlag(n, "wrap:this")) {
|
||||
|
@ -749,7 +800,7 @@ String *Swig_overload_dispatch(Node *n, const_String_or_char_ptr fmt, int *maxar
|
|||
Printf(f, "}\n");
|
||||
Delete(lfmt);
|
||||
}
|
||||
if (print_typecheck(f, (GetFlag(n, "wrap:this") ? j + 1 : j), pj)) {
|
||||
if (print_typecheck(f, (GetFlag(n, "wrap:this") ? j + 1 : j), pj, implicitconvtypecheckoff)) {
|
||||
Printf(f, "if (_v) {\n");
|
||||
num_braces++;
|
||||
}
|
||||
|
@ -773,6 +824,8 @@ String *Swig_overload_dispatch(Node *n, const_String_or_char_ptr fmt, int *maxar
|
|||
for ( /* empty */ ; num_braces > 0; num_braces--)
|
||||
Printf(f, "}\n");
|
||||
Printf(f, "}\n"); /* braces closes "if" for this method */
|
||||
if (implicitconvtypecheckoff)
|
||||
Delattr(ni, "implicitconvtypecheckoff");
|
||||
}
|
||||
Delete(dispatch);
|
||||
return f;
|
||||
|
|
Loading…
Reference in New Issue