mirror of https://github.com/swig/swig
Merge branch 'shared-ptr-template-upcast'
* shared-ptr-template-upcast: comments Applying shared_ptr template upcast fix to CSharp, adding CSharp test, and cleanup Adding test case demonstrating issue where SWIG does not generate a correctly typed, upcasted shared_ptr for a template instantiation deriving from a base class WIP - Use the non-encoded type string for upcasting a shared_ptr of a derived type to a shared_ptr of the base type comments Applying shared_ptr template upcast fix to CSharp, adding CSharp test, and cleanup Adding test case demonstrating issue where SWIG does not generate a correctly typed, upcasted shared_ptr for a template instantiation deriving from a base class WIP - Use the non-encoded type string for upcasting a shared_ptr of a derived type to a shared_ptr of the base type
This commit is contained in:
commit
6910e5f09c
|
@ -0,0 +1,88 @@
|
|||
%module cpp11_shared_ptr_template_upcast
|
||||
|
||||
%{
|
||||
#include <memory>
|
||||
#include <string>
|
||||
%}
|
||||
|
||||
%include <std_shared_ptr.i>
|
||||
%include <std_string.i>
|
||||
|
||||
%{
|
||||
class Base {
|
||||
public:
|
||||
Base() : value(0) {}
|
||||
Base(int v) : value(v) {}
|
||||
virtual ~Base() {}
|
||||
|
||||
virtual int GetResult() = 0;
|
||||
|
||||
int value;
|
||||
};
|
||||
|
||||
class Derived : public Base {
|
||||
public:
|
||||
Derived() : Base() {}
|
||||
Derived(int v) : Base(v) {}
|
||||
virtual ~Derived() {}
|
||||
|
||||
int GetResult() { return value*2; }
|
||||
};
|
||||
|
||||
template <class T> class Printable : virtual public T {
|
||||
public:
|
||||
Printable(int param) : T(param) {}
|
||||
~Printable() {}
|
||||
|
||||
std::string GetFormatted() { return std::string("The formatted result is: ").append(std::to_string(this->GetResult())); }
|
||||
};
|
||||
|
||||
std::shared_ptr<Printable<Derived> > MakePrintableDerived(int param) {
|
||||
return std::make_shared<Printable<Derived> >(param);
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%shared_ptr(Base);
|
||||
%shared_ptr(Derived);
|
||||
%shared_ptr(Printable<Derived>)
|
||||
|
||||
class Base {
|
||||
public:
|
||||
Base();
|
||||
Base(int v);
|
||||
virtual ~Base();
|
||||
|
||||
virtual int GetResult() = 0;
|
||||
|
||||
int value;
|
||||
};
|
||||
|
||||
class Derived : public Base {
|
||||
public:
|
||||
Derived();
|
||||
Derived(int v);
|
||||
virtual ~Derived();
|
||||
|
||||
int GetResult();
|
||||
};
|
||||
|
||||
/*
|
||||
Virtual inheritance is contrived for this case, but exposes whether SWIGSmartPtrUpcast generated a correctly typed shared pointer of the upcasted class type -
|
||||
if the pointer type is incorrect, this will result in a segmentation fault (on Windows, this could manifest as undefined behavior) when trying to access members
|
||||
inherited from T through a shared_ptr<Printable<T> >.
|
||||
*/
|
||||
template <class T> class Printable : virtual public T {
|
||||
public:
|
||||
Printable(int param);
|
||||
~Printable();
|
||||
|
||||
std::string GetFormatted();
|
||||
};
|
||||
|
||||
std::shared_ptr<Printable<Derived> > MakePrintableDerived(int param);
|
||||
|
||||
|
||||
%template(PrintableDerived) Printable<Derived>;
|
||||
|
||||
|
|
@ -35,6 +35,7 @@ CPP11_TEST_CASES = \
|
|||
cpp11_shared_ptr_const \
|
||||
cpp11_shared_ptr_nullptr_in_containers \
|
||||
cpp11_shared_ptr_overload \
|
||||
cpp11_shared_ptr_template_upcast \
|
||||
cpp11_shared_ptr_upcast \
|
||||
cpp11_strongly_typed_enumerations_simple \
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// This is the cpp11_shared_ptr_template_upcast runtime testcase. It checks that SWIG generates the appropriate upcasted shared_ptr type for a template instantiation deriving from a base class.
|
||||
// For this case, the expected behavior is: given a cptr with underlying type shared_ptr<Printable<Derived> >, PrintableDerived_SWIGSmartPtrUpcast returns a cptr with
|
||||
// underlying type std::shared_ptr< Derived >, where Printable<Derived> inherits from Derived.
|
||||
using System;
|
||||
using cpp11_shared_ptr_template_upcastNamespace;
|
||||
|
||||
public class cpp11_shared_ptr_template_upcast_runme
|
||||
{
|
||||
static void Main()
|
||||
{
|
||||
PrintableDerived pd = cpp11_shared_ptr_template_upcast.MakePrintableDerived(20);
|
||||
pd.GetResult();
|
||||
pd.GetFormatted();
|
||||
}
|
||||
}
|
|
@ -53,6 +53,7 @@ CPP11_TEST_CASES = \
|
|||
cpp11_shared_ptr_const \
|
||||
cpp11_shared_ptr_nullptr_in_containers \
|
||||
cpp11_shared_ptr_overload \
|
||||
cpp11_shared_ptr_template_upcast \
|
||||
cpp11_shared_ptr_upcast \
|
||||
cpp11_std_unordered_map \
|
||||
cpp11_std_unordered_set \
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
// This is the cpp11_shared_ptr_template_upcast runtime testcase. It checks that SWIG generates the appropriate upcasted shared_ptr type for a template instantiation deriving from a base class.
|
||||
// For this case, the expected behavior is: given a cptr with underlying type shared_ptr<Printable<Derived> >, PrintableDerived_SWIGSmartPtrUpcast returns a cptr with
|
||||
// underlying type std::shared_ptr< Derived >, where Printable<Derived> inherits from Derived.
|
||||
|
||||
import cpp11_shared_ptr_template_upcast.*;
|
||||
|
||||
public class cpp11_shared_ptr_template_upcast_runme {
|
||||
|
||||
static {
|
||||
try {
|
||||
System.loadLibrary("cpp11_shared_ptr_template_upcast");
|
||||
} 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[]) {
|
||||
PrintableDerived pd = cpp11_shared_ptr_template_upcast.MakePrintableDerived(20);
|
||||
pd.GetResult();
|
||||
pd.GetFormatted();
|
||||
}
|
||||
}
|
||||
|
|
@ -1758,21 +1758,22 @@ public:
|
|||
Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name);
|
||||
|
||||
if (smart) {
|
||||
SwigType *bsmart = Copy(smart);
|
||||
String *smartnamestr = SwigType_namestr(smart);
|
||||
String *bsmartnamestr = SwigType_namestr(smart);
|
||||
|
||||
SwigType *rclassname = SwigType_typedef_resolve_all(c_classname);
|
||||
SwigType *rbaseclass = SwigType_typedef_resolve_all(c_baseclass);
|
||||
Replaceall(bsmart, rclassname, rbaseclass);
|
||||
Replaceall(bsmartnamestr, 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 {
|
||||
Printv(upcasts_code,
|
||||
"SWIGEXPORT ", c_baseclass, " * SWIGSTDCALL ", wname, "(", c_classname, " *jarg1) {\n",
|
||||
|
|
|
@ -1897,14 +1897,17 @@ public:
|
|||
String *wname = Swig_name_wrapper(jniname);
|
||||
Printf(imclass_cppcasts_code, " public final static native long %s(long jarg1);\n", upcast_method_name);
|
||||
if (smart) {
|
||||
SwigType *bsmart = Copy(smart);
|
||||
String *smartnamestr = SwigType_namestr(smart);
|
||||
String *bsmartnamestr = SwigType_namestr(smart);
|
||||
|
||||
SwigType *rclassname = SwigType_typedef_resolve_all(c_classname);
|
||||
SwigType *rbaseclass = SwigType_typedef_resolve_all(c_baseclass);
|
||||
Replaceall(bsmart, rclassname, rbaseclass);
|
||||
|
||||
Replaceall(bsmartnamestr, 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"
|
||||
|
@ -1917,7 +1920,6 @@ public:
|
|||
"}\n", "\n", NIL);
|
||||
Delete(bsmartnamestr);
|
||||
Delete(smartnamestr);
|
||||
Delete(bsmart);
|
||||
} else {
|
||||
Printv(upcasts_code,
|
||||
"SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n",
|
||||
|
@ -1928,6 +1930,7 @@ public:
|
|||
" return baseptr;\n"
|
||||
"}\n", "\n", NIL);
|
||||
}
|
||||
|
||||
Delete(wname);
|
||||
Delete(jniname);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue