%shared_ptr fixes when the type is a template using template parameters that are typedef'd to another type. Also fixed %shared_ptr when the template parameter has a default value.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12776 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
95cd530c8f
commit
d0081ebb82
5 changed files with 231 additions and 37 deletions
|
|
@ -227,6 +227,7 @@ CPP_TEST_CASES += \
|
||||||
li_attribute \
|
li_attribute \
|
||||||
li_boost_shared_ptr \
|
li_boost_shared_ptr \
|
||||||
li_boost_shared_ptr_bits \
|
li_boost_shared_ptr_bits \
|
||||||
|
li_boost_shared_ptr_template \
|
||||||
li_carrays \
|
li_carrays \
|
||||||
li_cdata \
|
li_cdata \
|
||||||
li_cpointer \
|
li_cpointer \
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
|
||||||
|
|
||||||
|
import li_boost_shared_ptr_template.*;
|
||||||
|
|
||||||
|
public class li_boost_shared_ptr_template_runme {
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
System.loadLibrary("li_boost_shared_ptr_template");
|
||||||
|
} catch (UnsatisfiedLinkError e) {
|
||||||
|
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String argv[]) {
|
||||||
|
{
|
||||||
|
BaseINTEGER b = new BaseINTEGER();
|
||||||
|
DerivedINTEGER d = new DerivedINTEGER();
|
||||||
|
if (b.bar() != 1)
|
||||||
|
throw new RuntimeException("test 1");
|
||||||
|
if (d.bar() != 2)
|
||||||
|
throw new RuntimeException("test 2");
|
||||||
|
if (li_boost_shared_ptr_template.bar_getter(b) != 1)
|
||||||
|
throw new RuntimeException("test 3");
|
||||||
|
if (li_boost_shared_ptr_template.bar_getter(d) != 2)
|
||||||
|
throw new RuntimeException("test 4");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
BaseDefaultInt b = new BaseDefaultInt();
|
||||||
|
DerivedDefaultInt d = new DerivedDefaultInt();
|
||||||
|
DerivedDefaultInt2 d2 = new DerivedDefaultInt2();
|
||||||
|
if (b.bar2() != 3)
|
||||||
|
throw new RuntimeException("test 5");
|
||||||
|
if (d.bar2() != 4)
|
||||||
|
throw new RuntimeException("test 6");
|
||||||
|
if (d2.bar2() != 4)
|
||||||
|
throw new RuntimeException("test 6");
|
||||||
|
if (li_boost_shared_ptr_template.bar2_getter(b) != 3)
|
||||||
|
throw new RuntimeException("test 7");
|
||||||
|
if (li_boost_shared_ptr_template.bar2_getter(d) != 4)
|
||||||
|
throw new RuntimeException("test 8");
|
||||||
|
if (li_boost_shared_ptr_template.bar2_getter(d2) != 4)
|
||||||
|
throw new RuntimeException("test 8");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
99
Examples/test-suite/li_boost_shared_ptr_template.i
Normal file
99
Examples/test-suite/li_boost_shared_ptr_template.i
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
%module li_boost_shared_ptr_template
|
||||||
|
|
||||||
|
// First test- Bug 3333549 - using INTEGER typedef in %shared_ptr before typedef defined
|
||||||
|
%{
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
typedef int INTEGER;
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class Base {
|
||||||
|
public:
|
||||||
|
virtual T bar() {return 1;}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class Derived : public Base<T> {
|
||||||
|
public:
|
||||||
|
virtual T bar() {return 2;}
|
||||||
|
};
|
||||||
|
|
||||||
|
INTEGER bar_getter(Base<INTEGER>& foo) {
|
||||||
|
return foo.bar();
|
||||||
|
}
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGD)
|
||||||
|
#define SHARED_PTR_WRAPPERS_IMPLEMENTED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(SHARED_PTR_WRAPPERS_IMPLEMENTED)
|
||||||
|
|
||||||
|
%include <boost_shared_ptr.i>
|
||||||
|
%shared_ptr(Base<INTEGER>)
|
||||||
|
%shared_ptr(Derived<INTEGER>)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef int INTEGER;
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class Base {
|
||||||
|
public:
|
||||||
|
virtual T bar() {return 1;}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class Derived : public Base<T> {
|
||||||
|
public:
|
||||||
|
virtual T bar() {return 2;}
|
||||||
|
};
|
||||||
|
|
||||||
|
INTEGER bar_getter(Base<INTEGER>& foo) {
|
||||||
|
return foo.bar();
|
||||||
|
}
|
||||||
|
|
||||||
|
%template(BaseINTEGER) Base<INTEGER>;
|
||||||
|
%template(DerivedINTEGER) Derived<INTEGER>;
|
||||||
|
|
||||||
|
|
||||||
|
// 2nd test - templates with default template parameters
|
||||||
|
#if defined(SHARED_PTR_WRAPPERS_IMPLEMENTED)
|
||||||
|
|
||||||
|
%shared_ptr(Space::BaseDefault<short>)
|
||||||
|
%shared_ptr(Space::DerivedDefault<short>)
|
||||||
|
%shared_ptr(Space::DerivedDefault2<short>)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
namespace Space {
|
||||||
|
typedef int INT_TYPEDEF;
|
||||||
|
template <class X, class T = int>
|
||||||
|
class BaseDefault {
|
||||||
|
public:
|
||||||
|
virtual T bar2() {return 3;}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class X, class T = int>
|
||||||
|
class DerivedDefault : public BaseDefault<X, T> {
|
||||||
|
public:
|
||||||
|
virtual T bar2() {return 4;}
|
||||||
|
};
|
||||||
|
template <class X>
|
||||||
|
class DerivedDefault2 : public BaseDefault<X> {
|
||||||
|
public:
|
||||||
|
virtual int bar2() {return 4;}
|
||||||
|
};
|
||||||
|
|
||||||
|
int bar2_getter(BaseDefault<short>& foo) {
|
||||||
|
return foo.bar2();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
%template(BaseDefaultInt) Space::BaseDefault<short>;
|
||||||
|
%template(DerivedDefaultInt) Space::DerivedDefault<short>;
|
||||||
|
%template(DerivedDefaultInt2) Space::DerivedDefault2<short>;
|
||||||
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
from li_boost_shared_ptr_template import *
|
||||||
|
|
||||||
|
b = BaseINTEGER()
|
||||||
|
d = DerivedINTEGER()
|
||||||
|
if b.bar() != 1:
|
||||||
|
raise RuntimeError
|
||||||
|
if d.bar() != 2:
|
||||||
|
raise RuntimeError
|
||||||
|
if bar_getter(b) != 1:
|
||||||
|
raise RuntimeError
|
||||||
|
if bar_getter(d) != 2:
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
b = BaseDefaultInt()
|
||||||
|
d = DerivedDefaultInt()
|
||||||
|
d2 = DerivedDefaultInt2()
|
||||||
|
if b.bar2() != 3:
|
||||||
|
raise RuntimeError
|
||||||
|
if d.bar2() != 4:
|
||||||
|
raise RuntimeError
|
||||||
|
if d2.bar2() != 4:
|
||||||
|
raise RuntimeError
|
||||||
|
if bar2_getter(b) != 3:
|
||||||
|
raise RuntimeError
|
||||||
|
if bar2_getter(d) != 4:
|
||||||
|
raise RuntimeError
|
||||||
|
if bar2_getter(d2) != 4:
|
||||||
|
raise RuntimeError
|
||||||
|
|
@ -227,51 +227,64 @@ class TypePass:private Dispatcher {
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
Node *n = Getitem(ilist, i);
|
Node *n = Getitem(ilist, i);
|
||||||
String *bname = Getattr(n, "name");
|
String *bname = Getattr(n, "name");
|
||||||
Node *bclass = n; /* Getattr(n,"class"); */
|
Node *bclass = n;
|
||||||
Hash *scopes = Getattr(bclass, "typescope");
|
Hash *scopes = Getattr(bclass, "typescope");
|
||||||
SwigType_inherit(clsname, bname, cast, 0);
|
SwigType_inherit(clsname, bname, cast, 0);
|
||||||
String *smartptr = Getattr(first, "feature:smartptr");
|
|
||||||
if (smartptr) {
|
|
||||||
SwigType *smart = 0;
|
|
||||||
SwigType *spt = Swig_cparse_type(smartptr);
|
|
||||||
if (spt) {
|
|
||||||
smart = SwigType_typedef_resolve_all(spt);
|
|
||||||
Delete(spt);
|
|
||||||
/* Record a (fake) inheritance relationship between smart pointer
|
|
||||||
and smart pointer to base class, so that smart pointer upcasts
|
|
||||||
are automatically generated. */
|
|
||||||
SwigType *bsmart = Copy(smart);
|
|
||||||
SwigType *rclsname = SwigType_typedef_resolve_all(clsname);
|
|
||||||
SwigType *rbname = SwigType_typedef_resolve_all(bname);
|
|
||||||
Replaceall(bsmart, rclsname, rbname);
|
|
||||||
Delete(rclsname);
|
|
||||||
Delete(rbname);
|
|
||||||
String *smartnamestr = SwigType_namestr(smart);
|
|
||||||
String *bsmartnamestr = SwigType_namestr(bsmart);
|
|
||||||
/* construct casting code */
|
|
||||||
String *convcode = NewStringf("\n *newmemory = SWIG_CAST_NEW_MEMORY;\n return (void *) new %s(*(%s *)$from);\n", bsmartnamestr, smartnamestr);
|
|
||||||
Delete(bsmartnamestr);
|
|
||||||
Delete(smartnamestr);
|
|
||||||
/* setup inheritance relationship between smart pointer templates */
|
|
||||||
SwigType_inherit(smart, bsmart, 0, convcode);
|
|
||||||
if (!GetFlag(bclass, "feature:smartptr"))
|
|
||||||
Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Base class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(bclass, "name")), SwigType_namestr(Getattr(first, "name")));
|
|
||||||
Delete(convcode);
|
|
||||||
Delete(bsmart);
|
|
||||||
Delete(smart);
|
|
||||||
} else {
|
|
||||||
Swig_error(Getfile(first), Getline(first), "Invalid type (%s) in 'smartptr' feature for class %s.\n", SwigType_namestr(smartptr), SwigType_namestr(clsname));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (GetFlag(bclass, "feature:smartptr"))
|
|
||||||
Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Derived class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(first, "name")), SwigType_namestr(Getattr(bclass, "name")));
|
|
||||||
}
|
|
||||||
if (!importmode) {
|
if (!importmode) {
|
||||||
String *btype = Copy(bname);
|
String *btype = Copy(bname);
|
||||||
SwigType_add_pointer(btype);
|
SwigType_add_pointer(btype);
|
||||||
SwigType_remember(btype);
|
SwigType_remember(btype);
|
||||||
Delete(btype);
|
Delete(btype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String *smartptr = Getattr(first, "feature:smartptr");
|
||||||
|
String *base_smartptr = Getattr(bclass, "feature:smartptr");
|
||||||
|
if (smartptr) {
|
||||||
|
SwigType *spt = Swig_cparse_type(smartptr);
|
||||||
|
if (spt) {
|
||||||
|
if (base_smartptr) {
|
||||||
|
SwigType *base_spt = Swig_cparse_type(base_smartptr);
|
||||||
|
if (base_spt) {
|
||||||
|
/* Record a (fake) inheritance relationship between smart pointer
|
||||||
|
and smart pointer to base class, so that smart pointer upcasts
|
||||||
|
are automatically generated. */
|
||||||
|
SwigType *smart = SwigType_typedef_resolve_all(spt);
|
||||||
|
SwigType *bsmart = SwigType_typedef_resolve_all(base_spt);
|
||||||
|
String *smartnamestr = SwigType_namestr(smart);
|
||||||
|
String *bsmartnamestr = SwigType_namestr(bsmart);
|
||||||
|
|
||||||
|
/* Construct casting code */
|
||||||
|
String *convcode = NewStringf("\n *newmemory = SWIG_CAST_NEW_MEMORY;\n return (void *) new %s(*(%s *)$from);\n", bsmartnamestr, smartnamestr);
|
||||||
|
|
||||||
|
/* Setup inheritance relationship between smart pointers */
|
||||||
|
SwigType_inherit(smart, bsmart, 0, convcode);
|
||||||
|
if (!importmode) {
|
||||||
|
String *btype = Copy(bsmart);
|
||||||
|
SwigType_add_pointer(btype);
|
||||||
|
SwigType_remember(btype);
|
||||||
|
Delete(btype);
|
||||||
|
}
|
||||||
|
Delete(convcode);
|
||||||
|
Delete(bsmartnamestr);
|
||||||
|
Delete(smartnamestr);
|
||||||
|
Delete(bsmart);
|
||||||
|
Delete(smart);
|
||||||
|
Delete(base_spt);
|
||||||
|
} else {
|
||||||
|
Swig_error(Getfile(first), Getline(first), "Invalid type (%s) in 'smartptr' feature for class %s.\n", SwigType_namestr(base_smartptr), SwigType_namestr(bname));
|
||||||
|
}
|
||||||
|
Delete(spt);
|
||||||
|
} else {
|
||||||
|
Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Base class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(bclass, "name")), SwigType_namestr(Getattr(first, "name")));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Swig_error(Getfile(first), Getline(first), "Invalid type (%s) in 'smartptr' feature for class %s.\n", SwigType_namestr(smartptr), SwigType_namestr(clsname));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (base_smartptr)
|
||||||
|
Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Derived class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(first, "name")), SwigType_namestr(Getattr(bclass, "name")));
|
||||||
|
}
|
||||||
|
|
||||||
if (scopes) {
|
if (scopes) {
|
||||||
SwigType_inherit_scope(scopes);
|
SwigType_inherit_scope(scopes);
|
||||||
}
|
}
|
||||||
|
|
@ -429,6 +442,10 @@ class TypePass:private Dispatcher {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Swig_symbol_cadd(fname, n);
|
Swig_symbol_cadd(fname, n);
|
||||||
|
/* needed?
|
||||||
|
if (template_default_expanded)
|
||||||
|
Swig_symbol_cadd(template_default_expanded, n);
|
||||||
|
*/
|
||||||
SwigType_typedef_class(fname);
|
SwigType_typedef_class(fname);
|
||||||
scopename = Copy(fname);
|
scopename = Copy(fname);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue