Complete the Python support for shared_ptr mainly for derived classes. This includes the smartptr feature for overriding the class registration function and shared_ptr typemaps
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@10236 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
a85143fe7d
commit
f39242fa92
6 changed files with 124 additions and 12 deletions
|
|
@ -1,9 +1,88 @@
|
|||
Version 1.3.34 (in progress)
|
||||
============================
|
||||
|
||||
<<<<<<< .mine
|
||||
02/09/2007: wsfulton
|
||||
[Python] Experimental shared_ptr typemaps added. Usage is the same as the recently
|
||||
added Java and C# shared_ptr typemaps. Two macros are available, although these
|
||||
may well change in a future version:
|
||||
|
||||
For base classes or classes not in an inheritance chain:
|
||||
SWIG_SHARED_PTR(PROXYCLASS, TYPE)
|
||||
For derived classes:
|
||||
SWIG_SHARED_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE)
|
||||
|
||||
The PROXYCLASS is the name of the proxy class, but is only required for Java/C#.
|
||||
Example usage:
|
||||
|
||||
%include "boost_shared_ptr.i"
|
||||
|
||||
SWIG_SHARED_PTR(Klass, Space::Klass)
|
||||
SWIG_SHARED_PTR_DERIVED(KlassDerived, Space::Klass, Space::KlassDerived)
|
||||
|
||||
namespace Space {
|
||||
struct Klass { ... };
|
||||
struct KlassDerived : Klass { ... };
|
||||
}
|
||||
|
||||
Further details to follow in future documentation, but the following features
|
||||
should be noted:
|
||||
|
||||
- Not restricted to boost::shared_ptr, eg std::tr1::shared_ptr can also be used.
|
||||
- Available typemap groups:
|
||||
(a) Typemaps for shared_ptr passed by value, reference, pointer and pointer
|
||||
reference.
|
||||
- (b) Typemaps for passing by raw value, raw pointer, raw reference, raw pointer
|
||||
reference.
|
||||
- The code being wrapped does not even have to use shared_ptr, SWIG can use
|
||||
shared_ptr as the underlying storage mechanism instead of a raw pointer due to
|
||||
the typemaps in group (b) above.
|
||||
- No array support as shared_ptr does not support arrays.
|
||||
- This works quite differently to the usual SWIG smart pointer support when
|
||||
operator-> is parsed by SWIG:
|
||||
- An additional smart pointer class is not generated reducing code bloat in
|
||||
the wrappers.
|
||||
- Using smart pointers and raw pointers can be mixed seamlessly.
|
||||
- Missing constructors for the smart pointers is no longer a problem and so
|
||||
separate factory type functions do not have to be written and wrapped.
|
||||
- The implicit C++ shared_ptr< derived class > to shared_ptr< base class >
|
||||
cast also works in the target language. This negates the necessity to write
|
||||
an explicit helper cast function providing the upcast which would need
|
||||
calling prior to passing a derived class to a method taking a shared_ptr to
|
||||
a base class.
|
||||
|
||||
02/09/2007: wsfulton
|
||||
[Python] Add support for overriding the class registration function via a new
|
||||
"smartptr" feature. This is a very low level of customisation most users
|
||||
would never need to know. The feature will typically be used for intrusive
|
||||
smart pointers along with additional typemaps. Example usage of the feature:
|
||||
|
||||
%feature("smartptr", noblock=1) Foo { boost::shared_ptr< Foo > }
|
||||
class Foo {};
|
||||
|
||||
The generated Foo_swigregister function will then register boost::shared < Foo >
|
||||
(SWIGTYPE_p_boost__shared_ptrTFoo_t instead of SWIGTYPE_p_Foo) as the underlying
|
||||
type for instantiations of Foo.
|
||||
|
||||
02/09/2008: wsfulton
|
||||
Features now supports the optional 'noblock' attribute for all usage of %feature.
|
||||
When specified, the { } braces are removed from the feature code. This is identical
|
||||
in behaviour to usage of 'noblock' in typemaps and is used when the preprocessor
|
||||
is required to operate on the code in the feature and the enclosing { } braces
|
||||
are not required. Example:
|
||||
|
||||
#define FOO foo
|
||||
%feature("smartptr", noblock="1") { FOO::bar }
|
||||
|
||||
The preprocessor then reduces this as if this had been used instead:
|
||||
|
||||
%feature("smartptr") "foo::bar"
|
||||
|
||||
=======
|
||||
02/01/2008: olly
|
||||
[Python] Fix format string bug (SF#1882220).
|
||||
|
||||
>>>>>>> .r10235
|
||||
01/31/2008: wsfulton
|
||||
Additions to the %types directive. Now the conversion / casting code can be
|
||||
overridden to some custom code in the %types directive, like so:
|
||||
|
|
|
|||
|
|
@ -448,7 +448,7 @@ PySwigObject_dealloc(PyObject *v)
|
|||
{
|
||||
PySwigObject *sobj = (PySwigObject *) v;
|
||||
PyObject *next = sobj->next;
|
||||
if (sobj->own) {
|
||||
if (sobj->own == SWIG_POINTER_OWN) {
|
||||
swig_type_info *ty = sobj->ty;
|
||||
PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0;
|
||||
PyObject *destroy = data ? data->destroy : 0;
|
||||
|
|
@ -977,7 +977,7 @@ SWIG_Python_GetSwigThis(PyObject *pyobj)
|
|||
|
||||
SWIGRUNTIME int
|
||||
SWIG_Python_AcquirePtr(PyObject *obj, int own) {
|
||||
if (own) {
|
||||
if (own == SWIG_POINTER_OWN) {
|
||||
PySwigObject *sobj = SWIG_Python_GetSwigThis(obj);
|
||||
if (sobj) {
|
||||
int oldown = sobj->own;
|
||||
|
|
@ -997,6 +997,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int
|
|||
if (ptr) *ptr = 0;
|
||||
return SWIG_OK;
|
||||
} else {
|
||||
if (own)
|
||||
*own = 0;
|
||||
PySwigObject *sobj = SWIG_Python_GetSwigThis(obj);
|
||||
while (sobj) {
|
||||
void *vptr = sobj->ptr;
|
||||
|
|
@ -1011,7 +1013,15 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int
|
|||
if (!tc) {
|
||||
sobj = (PySwigObject *)sobj->next;
|
||||
} else {
|
||||
if (ptr) *ptr = SWIG_TypeCast(tc,vptr);
|
||||
if (ptr) {
|
||||
int newmemory = 0;
|
||||
*ptr = SWIG_TypeCast(tc,vptr,&newmemory);
|
||||
if (newmemory == SWIG_CAST_NEW_MEMORY) {
|
||||
assert(own);
|
||||
if (own)
|
||||
*own = *own | SWIG_CAST_NEW_MEMORY;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1021,7 +1031,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int
|
|||
}
|
||||
}
|
||||
if (sobj) {
|
||||
if (own) *own = sobj->own;
|
||||
if (own)
|
||||
*own = *own | sobj->own;
|
||||
if (flags & SWIG_POINTER_DISOWN) {
|
||||
sobj->own = 0;
|
||||
}
|
||||
|
|
@ -1087,7 +1098,7 @@ SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) {
|
|||
if (ty) {
|
||||
swig_cast_info *tc = SWIG_TypeCheck(desc,ty);
|
||||
if (!tc) return SWIG_ERROR;
|
||||
*ptr = SWIG_TypeCast(tc,vptr);
|
||||
*ptr = SWIG_TypeCast(tc,vptr,0);
|
||||
} else {
|
||||
*ptr = vptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,8 +44,12 @@ SWIG_SHARED_PTR_TYPEMAPS(PROXYCLASS, const, TYPE)
|
|||
%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_NAMESPACE::shared_ptr< TYPE > = SWIG_SHARED_PTR_NAMESPACE::shared_ptr< BASECLASSTYPE >) %{
|
||||
*newmemory = SWIG_CAST_NEW_MEMORY;
|
||||
return (void *) new SWIG_SHARED_PTR_NAMESPACE::shared_ptr< BASECLASSTYPE >(*(SWIG_SHARED_PTR_NAMESPACE::shared_ptr< TYPE > *)$from);
|
||||
%}
|
||||
%extend TYPE {
|
||||
static SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< BASECLASSTYPE > SWIGSharedPtrUpcast(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > swigSharedPtrUpcast) {
|
||||
static SWIG_SHARED_PTR_NAMESPACE::shared_ptr< BASECLASSTYPE > SWIGSharedPtrUpcast(SWIG_SHARED_PTR_NAMESPACE::shared_ptr< TYPE > swigSharedPtrUpcast) {
|
||||
return swigSharedPtrUpcast;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
/* Flags for pointer conversions */
|
||||
#define SWIG_POINTER_DISOWN 0x1
|
||||
#define SWIG_CAST_NEW_MEMORY 0x2
|
||||
|
||||
/* Flags for new pointer objects */
|
||||
#define SWIG_POINTER_OWN 0x1
|
||||
|
|
@ -182,7 +183,7 @@ SWIGINTERNINLINE int SWIG_CheckState(int r) {
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void *(*swig_converter_func)(void *);
|
||||
typedef void *(*swig_converter_func)(void *, int *);
|
||||
typedef struct swig_type_info *(*swig_dycast_func)(void **);
|
||||
|
||||
/* Structure to store information on one type */
|
||||
|
|
@ -312,8 +313,8 @@ SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) {
|
|||
Cast a pointer up an inheritance hierarchy
|
||||
*/
|
||||
SWIGRUNTIMEINLINE void *
|
||||
SWIG_TypeCast(swig_cast_info *ty, void *ptr) {
|
||||
return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr);
|
||||
SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) {
|
||||
return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -2661,8 +2661,23 @@ public:
|
|||
if (shadow) {
|
||||
/* Generate a class registration function */
|
||||
{
|
||||
SwigType *ct = NewStringf("p.%s", real_classname);
|
||||
SwigType_remember(ct);
|
||||
String *smartptr = Getattr(n, "feature:smartptr"); // Replace storing a pointer to underlying class with a smart pointer (intended for use with non-intrusive smart pointers)
|
||||
SwigType *smart = 0;
|
||||
if (smartptr) {
|
||||
SwigType *cpt = Swig_cparse_type(smartptr);
|
||||
if (cpt) {
|
||||
smart = SwigType_typedef_resolve_all(cpt);
|
||||
Delete(cpt);
|
||||
} else {
|
||||
// TODO: report line number of where the feature comes from
|
||||
Swig_error(Getfile(n), Getline(n), "Invalid type (%s) in 'smartptr' feature for class %s.\n", smartptr, real_classname);
|
||||
}
|
||||
}
|
||||
SwigType *ct = Copy(smart ? smart : real_classname);
|
||||
SwigType_add_pointer(ct);
|
||||
SwigType *realct = Copy(real_classname);
|
||||
SwigType_add_pointer(realct);
|
||||
SwigType_remember(realct);
|
||||
Printv(f_wrappers, "SWIGINTERN PyObject *", class_name, "_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", NIL);
|
||||
Printv(f_wrappers, ctab4, "PyObject *obj;\n", NIL);
|
||||
if (modernargs) {
|
||||
|
|
@ -2680,8 +2695,10 @@ public:
|
|||
ctab4, "return SWIG_Py_Void();\n", "}\n\n", NIL);
|
||||
String *cname = NewStringf("%s_swigregister", class_name);
|
||||
add_method(cname, cname, 0);
|
||||
Delete(smart);
|
||||
Delete(cname);
|
||||
Delete(ct);
|
||||
Delete(realct);
|
||||
}
|
||||
if (!have_constructor) {
|
||||
Printv(f_shadow_file, tab4, "def __init__(self): raise AttributeError, \"No constructor defined\"\n", NIL);
|
||||
|
|
|
|||
|
|
@ -1795,7 +1795,7 @@ void SwigType_inherit_equiv(File *out) {
|
|||
String *lprefix = SwigType_lstr(prefix, 0);
|
||||
Hash *subhash = Getattr(sub, bk.key);
|
||||
String *convcode = Getattr(subhash, "convcode");
|
||||
Printf(out, "static void *%s(void *x) {", convname);
|
||||
Printf(out, "static void *%s(void *x, int *newmemory) {", convname);
|
||||
if (convcode) {
|
||||
String *fn = Copy(convcode);
|
||||
Replaceall(fn, "$from", "x");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue