Fix assertion handling defaultargs
Occurs when using %extend for a template class and the extended methods contain default arguments. Closes #611
This commit is contained in:
parent
b0ba1cae76
commit
15ebf3df03
5 changed files with 87 additions and 7 deletions
|
|
@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release.
|
|||
Version 3.0.9 (in progress)
|
||||
===========================
|
||||
|
||||
2016-05-07: wsfulton
|
||||
Fix #611. Fix assertion handling defaultargs when using %extend for a template
|
||||
class and the extended methods contain default arguments.
|
||||
|
||||
2016-05-05: ejulian
|
||||
[Python] Patch #617. Fix operator/ wrappers.
|
||||
|
||||
|
|
|
|||
|
|
@ -402,6 +402,7 @@ CPP_TEST_CASES += \
|
|||
template_default2 \
|
||||
template_default_arg \
|
||||
template_default_arg_overloaded \
|
||||
template_default_arg_overloaded_extend \
|
||||
template_default_arg_virtual_destructor \
|
||||
template_default_class_parms \
|
||||
template_default_class_parms_typedef \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
from template_default_arg_overloaded_extend import *
|
||||
|
||||
def check(flag):
|
||||
if not flag:
|
||||
raise RuntimeError("failed")
|
||||
|
||||
rs = ResultSet()
|
||||
|
||||
check(rs.go_get(0, SearchPoint()) == -1)
|
||||
check(rs.go_get(0, SearchPoint(), 100) == 100)
|
||||
|
||||
check(rs.go_get_template(0, SearchPoint()) == -2)
|
||||
check(rs.go_get_template(0, SearchPoint(), 100) == 100)
|
||||
|
||||
check(rs.over() == "over(int)")
|
||||
check(rs.over(10) == "over(int)")
|
||||
check(rs.over(SearchPoint()) == "over(giai2::SearchPoint, int)")
|
||||
check(rs.over(SearchPoint(), 10) == "over(giai2::SearchPoint, int)")
|
||||
check(rs.over(True, SearchPoint()) == "over(bool, gaia2::SearchPoint, int)")
|
||||
check(rs.over(True, SearchPoint(), 10) == "over(bool, gaia2::SearchPoint, int)")
|
||||
44
Examples/test-suite/template_default_arg_overloaded_extend.i
Normal file
44
Examples/test-suite/template_default_arg_overloaded_extend.i
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
%module template_default_arg_overloaded_extend
|
||||
|
||||
%inline %{
|
||||
namespace gaia2 {
|
||||
|
||||
struct Filter {};
|
||||
struct SearchPoint {};
|
||||
struct DataSet {};
|
||||
|
||||
template <typename SearchPointType, typename DataSetType>
|
||||
class BaseSearchSpace {};
|
||||
|
||||
template <typename SearchPointType, typename DataSetType>
|
||||
class BaseResultSet {
|
||||
public:
|
||||
const char *over(int i = 0) {
|
||||
return "over(int)";
|
||||
}
|
||||
};
|
||||
}
|
||||
%}
|
||||
|
||||
// Specialized template extend
|
||||
%extend gaia2::BaseResultSet<gaia2::SearchPoint, gaia2::DataSet> {
|
||||
int go_get(int n, gaia2::SearchPoint, int offset = -1) {
|
||||
return offset;
|
||||
}
|
||||
const char *over(gaia2::SearchPoint, int x = 0) {
|
||||
return "over(giai2::SearchPoint, int)";
|
||||
}
|
||||
}
|
||||
|
||||
// Generic extend for all template instantiations
|
||||
%extend gaia2::BaseResultSet {
|
||||
int go_get_template(int n, SearchPointType sss, int offset = -2) {
|
||||
return offset;
|
||||
}
|
||||
const char *over(bool b, SearchPointType, int x = 0) {
|
||||
return "over(bool, SearchPointType, int)";
|
||||
}
|
||||
}
|
||||
|
||||
%template(ResultSet) gaia2::BaseResultSet<gaia2::SearchPoint, gaia2::DataSet>;
|
||||
|
||||
|
|
@ -145,7 +145,7 @@ static Node *copy_node(Node *n) {
|
|||
Setattr(nn, key, k.item);
|
||||
continue;
|
||||
}
|
||||
/* defaultargs will be patched back in later */
|
||||
/* defaultargs will be patched back in later in update_defaultargs() */
|
||||
if (strcmp(ckey,"defaultargs") == 0) {
|
||||
Setattr(nn, "needs_defaultargs", "1");
|
||||
continue;
|
||||
|
|
@ -660,19 +660,26 @@ static void add_symbols_copy(Node *n) {
|
|||
}
|
||||
}
|
||||
|
||||
/* Add in the "defaultargs" attribute for functions in instantiated templates.
|
||||
* n should be any instantiated template (class or start of linked list of functions). */
|
||||
static void update_defaultargs(Node *n) {
|
||||
if (n) {
|
||||
Node *firstdefaultargs = n;
|
||||
update_defaultargs(firstChild(n));
|
||||
n = nextSibling(n);
|
||||
/* recursively loop through nodes of all types, but all we really need are the overloaded functions */
|
||||
while (n) {
|
||||
update_defaultargs(firstChild(n));
|
||||
assert(!Getattr(n, "defaultargs"));
|
||||
if (Getattr(n, "needs_defaultargs")) {
|
||||
Setattr(n, "defaultargs", firstdefaultargs);
|
||||
Delattr(n, "needs_defaultargs");
|
||||
if (!Getattr(n, "defaultargs")) {
|
||||
if (Getattr(n, "needs_defaultargs")) {
|
||||
Setattr(n, "defaultargs", firstdefaultargs);
|
||||
Delattr(n, "needs_defaultargs");
|
||||
} else {
|
||||
firstdefaultargs = n;
|
||||
}
|
||||
} else {
|
||||
firstdefaultargs = n;
|
||||
/* Functions added in with %extend (for specialized template classes) will already have default args patched up */
|
||||
assert(Getattr(n, "defaultargs") == firstdefaultargs);
|
||||
}
|
||||
n = nextSibling(n);
|
||||
}
|
||||
|
|
@ -2756,7 +2763,11 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va
|
|||
Swig_symbol_setscope(csyms);
|
||||
}
|
||||
|
||||
/* Merge in %extend methods for this class */
|
||||
/* Merge in %extend methods for this class.
|
||||
This only merges methods within %extend for a template specialized class such as
|
||||
template<typename T> class K {}; %extend K<int> { ... }
|
||||
The copy_node() call above has already added in the generic %extend methods such as
|
||||
template<typename T> class K {}; %extend K { ... } */
|
||||
|
||||
/* !!! This may be broken. We may have to add the
|
||||
%extend methods at the beginning of the class */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue