diff options
author | William S Fulton <wsf@fultondesigns.co.uk> | 2010-05-22 22:49:47 +0000 |
---|---|---|
committer | William S Fulton <wsf@fultondesigns.co.uk> | 2010-05-22 22:49:47 +0000 |
commit | 12cfc251e423a526811b84ccb0f11fd7684cbc56 (patch) | |
tree | 836a89c3c8e781b3d5650c31a6fe2f3ee447daf8 | |
parent | 1fe29bae873b2c389a5bcdbfbc54dae9e7851d1b (diff) | |
download | swig-12cfc251e423a526811b84ccb0f11fd7684cbc56.tar.gz |
Fix #2408232. Improve shared_ptr and intrusive_ptr wrappers for classes in an inheritance hierarchy. No special treatment is needed for derived classes, the SWIG_SHARED_PTR_DERIVED macro is deprecated.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12036 626c5289-ae23-0410-ae9c-e8d60b6d4f22
-rw-r--r-- | CHANGES.current | 6 | ||||
-rw-r--r-- | Examples/test-suite/li_boost_intrusive_ptr.i | 9 | ||||
-rw-r--r-- | Examples/test-suite/li_boost_shared_ptr.i | 17 | ||||
-rw-r--r-- | Lib/csharp/boost_shared_ptr.i | 5 | ||||
-rw-r--r-- | Lib/intrusive_ptr.i | 38 | ||||
-rw-r--r-- | Lib/java/boost_intrusive_ptr.i | 4 | ||||
-rw-r--r-- | Lib/java/boost_shared_ptr.i | 6 | ||||
-rw-r--r-- | Lib/octave/boost_shared_ptr.i | 3 | ||||
-rw-r--r-- | Lib/python/boost_shared_ptr.i | 3 | ||||
-rw-r--r-- | Lib/shared_ptr.i | 18 | ||||
-rw-r--r-- | Source/Modules/csharp.cxx | 36 | ||||
-rw-r--r-- | Source/Modules/java.cxx | 52 | ||||
-rw-r--r-- | Source/Modules/typepass.cxx | 31 |
13 files changed, 124 insertions, 104 deletions
diff --git a/CHANGES.current b/CHANGES.current index 68732468c..9e70c291e 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,12 @@ Version 2.0.0 (in progress) ============================ +2010-05-22: wsfulton + Fix #2408232. Improve shared_ptr and intrusive_ptr wrappers for classes in an + inheritance hierarchy. No special treatment is needed for derived classes, the + SWIG_SHARED_PTR_DERIVED macro is deprecated and SWIG_SHARED_PTR should be used + instead. + 2010-05-21: olly [PHP] Stop generating a bogus line of code in certain constructors. This was mostly harmless, but caused a PHP notice to be issued, if diff --git a/Examples/test-suite/li_boost_intrusive_ptr.i b/Examples/test-suite/li_boost_intrusive_ptr.i index 47b64682a..23d78bcdc 100644 --- a/Examples/test-suite/li_boost_intrusive_ptr.i +++ b/Examples/test-suite/li_boost_intrusive_ptr.i @@ -46,8 +46,8 @@ %include <boost_intrusive_ptr.i>
SWIG_INTRUSIVE_PTR(Klass, Space::Klass)
SWIG_INTRUSIVE_PTR_NO_WRAP(KlassWithoutRefCount, Space::KlassWithoutRefCount)
-SWIG_INTRUSIVE_PTR_DERIVED(KlassDerived, Space::KlassWithoutRefCount, Space::KlassDerived)
-SWIG_INTRUSIVE_PTR_DERIVED(KlassDerivedDerived, Space::KlassDerived, Space::KlassDerivedDerived)
+SWIG_INTRUSIVE_PTR(KlassDerived, Space::KlassDerived)
+SWIG_INTRUSIVE_PTR(KlassDerivedDerived, Space::KlassDerivedDerived)
//For the use_count shared_ptr functions
%typemap(in) SWIG_INTRUSIVE_PTR_QNAMESPACE::shared_ptr< Space::Klass > & ($*1_ltype tempnull) %{
@@ -390,9 +390,7 @@ Space::Klass & GlobalReference = GlobalValue; // Note: %template after the intrusive_ptr typemaps
SWIG_INTRUSIVE_PTR(BaseIntDouble, Base<int, double>)
-// Note: cannot use Base<int, double> in the macro below because of the comma in the type,
-// so we use a typedef instead. Alternatively use %arg(Base<int, double>). %arg is defined in swigmacros.swg.
-SWIG_INTRUSIVE_PTR_DERIVED(PairIntDouble, BaseIntDouble_t, Pair<int, double>)
+SWIG_INTRUSIVE_PTR(PairIntDouble, Pair<int, double>)
#endif
@@ -409,7 +407,6 @@ template <class T1, class T2> struct Base { void release(void) const { if (--count == 0) delete this; }
int use_count(void) const { return count; }
};
-typedef Base<int, double> BaseIntDouble_t;
%}
%template(BaseIntDouble) Base<int, double>;
diff --git a/Examples/test-suite/li_boost_shared_ptr.i b/Examples/test-suite/li_boost_shared_ptr.i index 7a9468e4f..886a8d9c8 100644 --- a/Examples/test-suite/li_boost_shared_ptr.i +++ b/Examples/test-suite/li_boost_shared_ptr.i @@ -42,15 +42,9 @@ %include <boost_shared_ptr.i> SWIG_SHARED_PTR(Klass, Space::Klass) -SWIG_SHARED_PTR_DERIVED(KlassDerived, Space::Klass, Space::KlassDerived) -SWIG_SHARED_PTR_DERIVED(Klass2ndDerived, Space::Klass, Space::Klass2ndDerived) -SWIG_SHARED_PTR_DERIVED(Klass3rdDerived, Space::Klass2ndDerived, Space::Klass3rdDerived) - -// TEMP for python -%types(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< Space::Klass3rdDerived > = SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< Space::Klass >) { - *newmemory = SWIG_CAST_NEW_MEMORY; - return (void *) new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< Space::Klass >(*(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< Space::Klass3rdDerived > *)$from); -} +SWIG_SHARED_PTR(KlassDerived, Space::KlassDerived) +SWIG_SHARED_PTR(Klass2ndDerived, Space::Klass2ndDerived) +SWIG_SHARED_PTR(Klass3rdDerived, Space::Klass3rdDerived) #endif @@ -324,9 +318,7 @@ Space::Klass & GlobalReference = GlobalValue; // Note: %template after the shared_ptr typemaps SWIG_SHARED_PTR(BaseIntDouble, Base<int, double>) -// Note: cannot use Base<int, double> in the macro below because of the comma in the type, -// so we use a typedef instead. Alternatively use %arg(Base<int, double>). %arg is defined in swigmacros.swg. -SWIG_SHARED_PTR_DERIVED(PairIntDouble, BaseIntDouble_t, Pair<int, double>) +SWIG_SHARED_PTR(PairIntDouble, Pair<int, double>) #endif @@ -339,7 +331,6 @@ template <class T1, class T2> struct Base { Base(T1 t1, T2 t2) : baseVal1(t1*2), baseVal2(t2*2) {} virtual std::string getValue() const { return "Base<>"; }; }; -typedef Base<int, double> BaseIntDouble_t; %} %template(BaseIntDouble) Base<int, double>; diff --git a/Lib/csharp/boost_shared_ptr.i b/Lib/csharp/boost_shared_ptr.i index 86a62c33c..8463c2b81 100644 --- a/Lib/csharp/boost_shared_ptr.i +++ b/Lib/csharp/boost_shared_ptr.i @@ -190,7 +190,7 @@ private HandleRef swigCPtr; private bool swigCMemOwnDerived; - internal $csclassname(IntPtr cPtr, bool cMemoryOwn) : base($imclassname.$csclassname_SWIGSharedPtrUpcast(cPtr), true) { + internal $csclassname(IntPtr cPtr, bool cMemoryOwn) : base($imclassname.$csclassname_SWIGSmartPtrUpcast(cPtr), true) { swigCMemOwnDerived = cMemoryOwn; swigCPtr = new HandleRef(this, cPtr); } @@ -227,9 +227,6 @@ } } -%typemap(imtype) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > swigSharedPtrUpcast "IntPtr" -%typemap(csin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > swigSharedPtrUpcast "PROXYCLASS.getCPtr($csinput).Handle" - %template() SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >; %enddef diff --git a/Lib/intrusive_ptr.i b/Lib/intrusive_ptr.i index 43e78f986..a7c922fea 100644 --- a/Lib/intrusive_ptr.i +++ b/Lib/intrusive_ptr.i @@ -45,51 +45,17 @@ struct SWIG_null_deleter { }
// Main user macro for defining intrusive_ptr typemaps for both const and non-const pointer types
-// For plain classes, do not use for derived classes
%define SWIG_INTRUSIVE_PTR(PROXYCLASS, TYPE...)
+%feature("smartptr", noblock=1) TYPE { SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > }
SWIG_INTRUSIVE_PTR_TYPEMAPS(PROXYCLASS, , TYPE)
SWIG_INTRUSIVE_PTR_TYPEMAPS(PROXYCLASS, const, TYPE)
%enddef
-// Main user macro for defining intrusive_ptr typemaps for both const and non-const pointer types
-// For derived classes
-%define SWIG_INTRUSIVE_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE...)
-SWIG_INTRUSIVE_PTR_TYPEMAPS(PROXYCLASS, , TYPE)
-SWIG_INTRUSIVE_PTR_TYPEMAPS(PROXYCLASS, const, TYPE)
-%types(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > = SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< BASECLASSTYPE >) %{
- *newmemory = SWIG_CAST_NEW_MEMORY;
- return (void *) new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< BASECLASSTYPE >(*(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *)$from);
- %}
-%extend TYPE {
- static SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< BASECLASSTYPE > SWIGSharedPtrUpcast(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > swigSharedPtrUpcast) {
- return swigSharedPtrUpcast;
- }
-}
-%enddef
-
// Extra user macro for including classes in intrusive_ptr typemaps for both const and non-const pointer types
// This caters for classes which cannot be wrapped by intrusive_ptrs but are still part of the class hierarchy
-// For plain classes, do not use for derived classes
%define SWIG_INTRUSIVE_PTR_NO_WRAP(PROXYCLASS, TYPE...)
+%feature("smartptr", noblock=1) TYPE { SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > }
SWIG_INTRUSIVE_PTR_TYPEMAPS_NO_WRAP(PROXYCLASS, , TYPE)
SWIG_INTRUSIVE_PTR_TYPEMAPS_NO_WRAP(PROXYCLASS, const, TYPE)
%enddef
-// Extra user macro for including classes in intrusive_ptr typemaps for both const and non-const pointer types
-// This caters for classes which cannot be wrapped by intrusive_ptrs but are still part of the class hierarchy
-// For derived classes
-%define SWIG_INTRUSIVE_PTR_DERIVED_NO_WRAP(PROXYCLASS, BASECLASSTYPE, TYPE...)
-SWIG_INTRUSIVE_PTR_TYPEMAPS_NO_WRAP(PROXYCLASS, , TYPE)
-SWIG_INTRUSIVE_PTR_TYPEMAPS_NO_WRAP(PROXYCLASS, const, TYPE)
-%types(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > = SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< BASECLASSTYPE >) %{
- *newmemory = SWIG_CAST_NEW_MEMORY;
- return (void *) new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< BASECLASSTYPE >(*(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *)$from);
-%}
-%extend TYPE {
- static SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< BASECLASSTYPE > SWIGSharedPtrUpcast(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > swigSharedPtrUpcast) {
- return swigSharedPtrUpcast;
- }
-}
-%enddef
-
-
diff --git a/Lib/java/boost_intrusive_ptr.i b/Lib/java/boost_intrusive_ptr.i index f7b7da32f..28446908f 100644 --- a/Lib/java/boost_intrusive_ptr.i +++ b/Lib/java/boost_intrusive_ptr.i @@ -272,7 +272,7 @@ private boolean swigCMemOwnDerived;
protected $javaclassname(long cPtr, boolean cMemoryOwn) {
- super($imclassname.$javaclassname_SWIGSharedPtrUpcast(cPtr), true);
+ super($imclassname.$javaclassname_SWIGSmartPtrUpcast(cPtr), true);
swigCMemOwnDerived = cMemoryOwn;
swigCPtr = cPtr;
}
@@ -422,7 +422,7 @@ private boolean swigCMemOwnDerived;
protected $javaclassname(long cPtr, boolean cMemoryOwn) {
- super($imclassname.$javaclassname_SWIGSharedPtrUpcast(cPtr), true);
+ super($imclassname.$javaclassname_SWIGSmartPtrUpcast(cPtr), true);
swigCMemOwnDerived = cMemoryOwn;
swigCPtr = cPtr;
}
diff --git a/Lib/java/boost_shared_ptr.i b/Lib/java/boost_shared_ptr.i index 1c74a2453..5b89cafb7 100644 --- a/Lib/java/boost_shared_ptr.i +++ b/Lib/java/boost_shared_ptr.i @@ -158,7 +158,7 @@ private boolean swigCMemOwnDerived; protected $javaclassname(long cPtr, boolean cMemoryOwn) { - super($imclassname.$javaclassname_SWIGSharedPtrUpcast(cPtr), true); + super($imclassname.$javaclassname_SWIGSmartPtrUpcast(cPtr), true); swigCMemOwnDerived = cMemoryOwn; swigCPtr = cPtr; } @@ -189,10 +189,6 @@ super.delete(); } -// CONST version needed ???? also for C# -%typemap(jtype, nopgcpp="1") SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > swigSharedPtrUpcast "long" -%typemap(jtype, nopgcpp="1") SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > swigSharedPtrUpcast "long" - %template() SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >; %enddef diff --git a/Lib/octave/boost_shared_ptr.i b/Lib/octave/boost_shared_ptr.i index d702108a6..e475b2308 100644 --- a/Lib/octave/boost_shared_ptr.i +++ b/Lib/octave/boost_shared_ptr.i @@ -12,9 +12,6 @@ //"if (debug_shared) { cout << \"deleting use_count: \" << (*smartarg1).use_count() << \" [\" << (boost::get_deleter<SWIG_null_deleter>(*smartarg1) ? std::string(\"CANNOT BE DETERMINED SAFELY\") : ( (*smartarg1).get() ? (*smartarg1)->getValue() : std::string(\"NULL PTR\") )) << \"]\" << endl << flush; }\n" "(void)arg1; delete smartarg1;" -// Feature to adapt the code generated in the swigregister functions for smart pointers -%feature("smartptr", noblock=1) TYPE { SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > } - // Typemap customisations... // plain value diff --git a/Lib/python/boost_shared_ptr.i b/Lib/python/boost_shared_ptr.i index 59a3a9298..a3006e36a 100644 --- a/Lib/python/boost_shared_ptr.i +++ b/Lib/python/boost_shared_ptr.i @@ -18,9 +18,6 @@ //"if (debug_shared) { cout << \"deleting use_count: \" << (*smartarg1).use_count() << \" [\" << (boost::get_deleter<SWIG_null_deleter>(*smartarg1) ? std::string(\"CANNOT BE DETERMINED SAFELY\") : ( (*smartarg1).get() ? (*smartarg1)->getValue() : std::string(\"NULL PTR\") )) << \"]\" << endl << flush; }\n" "(void)arg1; delete smartarg1;" -// Feature to adapt the code generated in the swigregister functions for smart pointers -%feature("smartptr", noblock=1) TYPE { SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > } - // Typemap customisations... // plain value diff --git a/Lib/shared_ptr.i b/Lib/shared_ptr.i index ffff2b40b..877330721 100644 --- a/Lib/shared_ptr.i +++ b/Lib/shared_ptr.i @@ -41,25 +41,9 @@ struct SWIG_null_deleter { // Main user macro for defining shared_ptr typemaps for both const and non-const pointer types -// For plain classes, do not use for derived classes %define SWIG_SHARED_PTR(PROXYCLASS, TYPE...) +%feature("smartptr", noblock=1) TYPE { SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > } SWIG_SHARED_PTR_TYPEMAPS(PROXYCLASS, , TYPE) SWIG_SHARED_PTR_TYPEMAPS(PROXYCLASS, const, TYPE) %enddef -// Main user macro for defining shared_ptr typemaps for both const and non-const pointer types -// For derived classes -%define SWIG_SHARED_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE...) -SWIG_SHARED_PTR_TYPEMAPS(PROXYCLASS, , TYPE) -SWIG_SHARED_PTR_TYPEMAPS(PROXYCLASS, const, TYPE) -%types(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > = SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< BASECLASSTYPE >) %{ - *newmemory = SWIG_CAST_NEW_MEMORY; - return (void *) new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< BASECLASSTYPE >(*(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *)$from); -%} -%extend TYPE { - static SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< BASECLASSTYPE > SWIGSharedPtrUpcast(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > swigSharedPtrUpcast) { - return swigSharedPtrUpcast; - } -} -%enddef - diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index bedaae7f2..ba8f34b47 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -1817,7 +1817,8 @@ public: // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy) if (derived) { - String *upcast_method = Swig_name_member(getNSpace(), proxy_class_name, "SWIGUpcast"); + String *smartptr = Getattr(n, "feature:smartptr"); + String *upcast_method = Swig_name_member(getNSpace(), proxy_class_name, smartptr != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast"); String *wname = Swig_name_wrapper(upcast_method); Printv(imclass_cppcasts_code, "\n [DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL); @@ -1825,10 +1826,35 @@ public: Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name); - Printv(upcasts_code, - "SWIGEXPORT ", c_baseclass, " * SWIGSTDCALL ", wname, - "(", c_classname, " *jarg1) {\n", " return (", c_baseclass, " *)jarg1;\n" "}\n", "\n", NIL); - + if (smartptr) { + SwigType *spt = Swig_cparse_type(smartptr); + if (spt) { + SwigType *smart = SwigType_typedef_resolve_all(spt); + Delete(spt); + SwigType *bsmart = Copy(smart); + SwigType *rclassname = SwigType_typedef_resolve_all(c_classname); + SwigType *rbaseclass = SwigType_typedef_resolve_all(c_baseclass); + Replaceall(bsmart, rclassname, rbaseclass); + Delete(rclassname); + Delete(rbaseclass); + String *smartnamestr = SwigType_namestr(smart); + String *bsmartnamestr = SwigType_namestr(bsmart); + Printv(upcasts_code, + "SWIGEXPORT ", bsmartnamestr, " * SWIGSTDCALL ", wname, "(", smartnamestr, " *jarg1) {\n", + " return jarg1 ? new ", bsmartnamestr, "(*jarg1) : 0;\n" + "}\n", "\n", NIL); + Delete(bsmartnamestr); + Delete(smartnamestr); + Delete(bsmart); + } else { + Swig_error(Getfile(n), Getline(n), "Invalid type (%s) in 'smartptr' feature for class %s.\n", smartptr, c_classname); + } + } else { + Printv(upcasts_code, + "SWIGEXPORT ", c_baseclass, " * SWIGSTDCALL ", wname, "(", c_classname, " *jarg1) {\n", + " return (", c_baseclass, " *)jarg1;\n" + "}\n", "\n", NIL); + } Delete(wname); Delete(upcast_method); } diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index ee68af948..8c4770a9e 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -1825,19 +1825,51 @@ public: // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy) if (derived) { - String *upcast_method = Swig_name_member(getNSpace(), proxy_class_name, "SWIGUpcast"); + String *smartptr = Getattr(n, "feature:smartptr"); + String *upcast_method = Swig_name_member(getNSpace(), proxy_class_name, smartptr != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast"); String *jniname = makeValidJniName(upcast_method); String *wname = Swig_name_wrapper(jniname); - Printf(imclass_cppcasts_code, " public final static native long %s(long jarg1);\n", upcast_method); - - Printv(upcasts_code, - "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n", - " jlong baseptr = 0;\n" - " (void)jenv;\n" " (void)jcls;\n" " *(", c_baseclass, " **)&baseptr = *(", c_classname, " **)&jarg1;\n" - " return baseptr;\n" - "}\n", "\n", NIL); - + if (smartptr) { + SwigType *spt = Swig_cparse_type(smartptr); + if (spt) { + SwigType *smart = SwigType_typedef_resolve_all(spt); + Delete(spt); + SwigType *bsmart = Copy(smart); + SwigType *rclassname = SwigType_typedef_resolve_all(c_classname); + SwigType *rbaseclass = SwigType_typedef_resolve_all(c_baseclass); + Replaceall(bsmart, rclassname, rbaseclass); + Delete(rclassname); + Delete(rbaseclass); + String *smartnamestr = SwigType_namestr(smart); + String *bsmartnamestr = SwigType_namestr(bsmart); + Printv(upcasts_code, + "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n", + " jlong baseptr = 0;\n" + " ", smartnamestr, " *argp1;\n" + " ", bsmartnamestr, " result;\n" + " (void)jenv;\n" + " (void)jcls;\n" + " argp1 = *(", smartnamestr, " **)&jarg1;\n" + " *(", bsmartnamestr, " **)&baseptr = argp1 ? new ", bsmartnamestr, "(*argp1) : 0;\n" + " return baseptr;\n" + "}\n", "\n", NIL); + Delete(bsmartnamestr); + Delete(smartnamestr); + Delete(bsmart); + } else { + Swig_error(Getfile(n), Getline(n), "Invalid type (%s) in 'smartptr' feature for class %s.\n", smartptr, c_classname); + } + } else { + Printv(upcasts_code, + "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n", + " jlong baseptr = 0;\n" + " (void)jenv;\n" + " (void)jcls;\n" + " *(", c_baseclass, " **)&baseptr = *(", c_classname, " **)&jarg1;\n" + " return baseptr;\n" + "}\n", "\n", NIL); + } Delete(wname); Delete(jniname); Delete(upcast_method); diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx index e63b58a10..57a7663eb 100644 --- a/Source/Modules/typepass.cxx +++ b/Source/Modules/typepass.cxx @@ -231,6 +231,37 @@ class TypePass:private Dispatcher { Node *bclass = n; /* Getattr(n,"class"); */ 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); + Delete(convcode); + Delete(bsmart); + Delete(smart); + } else { + Swig_error(Getfile(first), Getline(first), "Invalid type (%s) in 'smartptr' feature for class %s.\n", smartptr, clsname); + } + } if (!importmode) { String *btype = Copy(bname); SwigType_add_pointer(btype); |