From d0081ebb82f0822453bb60bbe124fb4c17c6f200 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 13 Aug 2011 00:36:12 +0000 Subject: [PATCH] %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 --- Examples/test-suite/common.mk | 1 + .../li_boost_shared_ptr_template_runme.java | 49 +++++++++ .../test-suite/li_boost_shared_ptr_template.i | 99 +++++++++++++++++++ .../li_boost_shared_ptr_template_runme.py | 28 ++++++ Source/Modules/typepass.cxx | 91 ++++++++++------- 5 files changed, 231 insertions(+), 37 deletions(-) create mode 100644 Examples/test-suite/java/li_boost_shared_ptr_template_runme.java create mode 100644 Examples/test-suite/li_boost_shared_ptr_template.i create mode 100644 Examples/test-suite/python/li_boost_shared_ptr_template_runme.py diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index c007588ef..e86c0fb65 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -227,6 +227,7 @@ CPP_TEST_CASES += \ li_attribute \ li_boost_shared_ptr \ li_boost_shared_ptr_bits \ + li_boost_shared_ptr_template \ li_carrays \ li_cdata \ li_cpointer \ diff --git a/Examples/test-suite/java/li_boost_shared_ptr_template_runme.java b/Examples/test-suite/java/li_boost_shared_ptr_template_runme.java new file mode 100644 index 000000000..35f517a53 --- /dev/null +++ b/Examples/test-suite/java/li_boost_shared_ptr_template_runme.java @@ -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"); + } + } +} + diff --git a/Examples/test-suite/li_boost_shared_ptr_template.i b/Examples/test-suite/li_boost_shared_ptr_template.i new file mode 100644 index 000000000..62086c99d --- /dev/null +++ b/Examples/test-suite/li_boost_shared_ptr_template.i @@ -0,0 +1,99 @@ +%module li_boost_shared_ptr_template + +// First test- Bug 3333549 - using INTEGER typedef in %shared_ptr before typedef defined +%{ +#include + + typedef int INTEGER; + + template + class Base { + public: + virtual T bar() {return 1;} + }; + + template + class Derived : public Base { + public: + virtual T bar() {return 2;} + }; + + INTEGER bar_getter(Base& 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 +%shared_ptr(Base) +%shared_ptr(Derived) + +#endif + +typedef int INTEGER; + +template +class Base { + public: + virtual T bar() {return 1;} +}; + +template +class Derived : public Base { + public: + virtual T bar() {return 2;} +}; + +INTEGER bar_getter(Base& foo) { + return foo.bar(); +} + +%template(BaseINTEGER) Base; +%template(DerivedINTEGER) Derived; + + +// 2nd test - templates with default template parameters +#if defined(SHARED_PTR_WRAPPERS_IMPLEMENTED) + +%shared_ptr(Space::BaseDefault) +%shared_ptr(Space::DerivedDefault) +%shared_ptr(Space::DerivedDefault2) + +#endif + +%inline %{ +namespace Space { +typedef int INT_TYPEDEF; +template +class BaseDefault { + public: + virtual T bar2() {return 3;} +}; + +template +class DerivedDefault : public BaseDefault { + public: + virtual T bar2() {return 4;} +}; +template +class DerivedDefault2 : public BaseDefault { + public: + virtual int bar2() {return 4;} +}; + +int bar2_getter(BaseDefault& foo) { + return foo.bar2(); +} +} +%} + +%template(BaseDefaultInt) Space::BaseDefault; +%template(DerivedDefaultInt) Space::DerivedDefault; +%template(DerivedDefaultInt2) Space::DerivedDefault2; + diff --git a/Examples/test-suite/python/li_boost_shared_ptr_template_runme.py b/Examples/test-suite/python/li_boost_shared_ptr_template_runme.py new file mode 100644 index 000000000..20e7a8060 --- /dev/null +++ b/Examples/test-suite/python/li_boost_shared_ptr_template_runme.py @@ -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 diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx index 15768f203..575b8e6b2 100644 --- a/Source/Modules/typepass.cxx +++ b/Source/Modules/typepass.cxx @@ -227,51 +227,64 @@ class TypePass:private Dispatcher { for (i = 0; i < len; i++) { Node *n = Getitem(ilist, i); String *bname = Getattr(n, "name"); - Node *bclass = n; /* Getattr(n,"class"); */ + Node *bclass = n; Hash *scopes = Getattr(bclass, "typescope"); 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) { String *btype = Copy(bname); SwigType_add_pointer(btype); SwigType_remember(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) { SwigType_inherit_scope(scopes); } @@ -429,6 +442,10 @@ class TypePass:private Dispatcher { } } else { Swig_symbol_cadd(fname, n); + /* needed? + if (template_default_expanded) + Swig_symbol_cadd(template_default_expanded, n); + */ SwigType_typedef_class(fname); scopename = Copy(fname); }