Abstract directors and typemap fixes.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@5024 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
7ad2fa11dc
commit
ec6251e86d
10 changed files with 97 additions and 17 deletions
|
|
@ -1,5 +1,19 @@
|
||||||
Version 1.3.20 (In progress)
|
Version 1.3.20 (In progress)
|
||||||
============================
|
============================
|
||||||
|
08/29/2003: mrose (Mark Rose)
|
||||||
|
Completed initial support for wrapping abstract classes with directors.
|
||||||
|
Constructor wrappers will be generated for abstract classes that have
|
||||||
|
directors, and instances of the director classes will be created regardless
|
||||||
|
of whether the proxy class has been subclassed in the target language.
|
||||||
|
No checks are made during construction to ensure that all pure virtual
|
||||||
|
methods are implemented in the target language. Instead, calls to
|
||||||
|
unimplemented methods will throw SWIG_DIRECTOR_PURE_VIRTUAL exceptions in
|
||||||
|
C++.
|
||||||
|
|
||||||
|
Integrated Prabhu Ramachandran's typemap patches, which provide director
|
||||||
|
typemap support for enums and std::size_t, and fix a couple bugs in the
|
||||||
|
director std::vector<> typemaps.
|
||||||
|
|
||||||
08/29/2003: cheetah (William Fulton)
|
08/29/2003: cheetah (William Fulton)
|
||||||
[C#] Implemented exception handling for throwing C# exceptions from C/C++ code.
|
[C#] Implemented exception handling for throwing C# exceptions from C/C++ code.
|
||||||
A few delegate functions are available for calling which then throw the C#
|
A few delegate functions are available for calling which then throw the C#
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,7 @@ CPP_TEST_CASES += \
|
||||||
default_constructor \
|
default_constructor \
|
||||||
default_ns \
|
default_ns \
|
||||||
default_ref \
|
default_ref \
|
||||||
|
director_abstract \
|
||||||
director_basic \
|
director_basic \
|
||||||
director_exception \
|
director_exception \
|
||||||
director_finalizer \
|
director_finalizer \
|
||||||
|
|
|
||||||
26
Examples/test-suite/director_abstract.i
Normal file
26
Examples/test-suite/director_abstract.i
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
%module(directors="1") director_abstract
|
||||||
|
%{
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
public:
|
||||||
|
virtual ~Foo() {}
|
||||||
|
virtual std::string ping() = 0;
|
||||||
|
virtual std::string pong() { return "Foo::pong();" + ping(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
%include "typemaps.i"
|
||||||
|
%include "exception.i"
|
||||||
|
%include "std_string.i"
|
||||||
|
|
||||||
|
%feature("director") Foo;
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
public:
|
||||||
|
virtual ~Foo() {}
|
||||||
|
virtual std::string ping() = 0;
|
||||||
|
virtual std::string pong() { return "Foo::pong();" + ping(); }
|
||||||
|
};
|
||||||
|
|
||||||
16
Examples/test-suite/python/director_abstract_runme.py
Normal file
16
Examples/test-suite/python/director_abstract_runme.py
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
import director_abstract
|
||||||
|
|
||||||
|
class MyFoo(director_abstract.Foo):
|
||||||
|
def ping(self):
|
||||||
|
return "MyFoo::ping()"
|
||||||
|
|
||||||
|
|
||||||
|
a = MyFoo()
|
||||||
|
|
||||||
|
if a.ping() != "MyFoo::ping()":
|
||||||
|
raise RuntimeError, a.ping()
|
||||||
|
|
||||||
|
if a.pong() != "Foo::pong();MyFoo::ping()":
|
||||||
|
raise RuntimeError, a.pong()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -53,6 +53,7 @@ class SWIG_DIRECTOR_PURE_VIRTUAL_EXCEPTION: public SWIG_DIRECTOR_EXCEPTION { };
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* director base class */
|
/* director base class */
|
||||||
class __DIRECTOR__ {
|
class __DIRECTOR__ {
|
||||||
private:
|
private:
|
||||||
|
|
@ -171,6 +172,7 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace {
|
||||||
int __DIRECTOR__::_up = 0;
|
int __DIRECTOR__::_up = 0;
|
||||||
|
|
||||||
#ifdef __PTHREAD__
|
#ifdef __PTHREAD__
|
||||||
|
|
@ -179,6 +181,8 @@ int __DIRECTOR__::_up = 0;
|
||||||
int __DIRECTOR__::_mutex_active = 0;
|
int __DIRECTOR__::_mutex_active = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -435,6 +435,7 @@
|
||||||
%typemap(inv,parse="d") double "";
|
%typemap(inv,parse="d") double "";
|
||||||
%typemap(inv,parse="s") char* "";
|
%typemap(inv,parse="s") char* "";
|
||||||
%typemap(inv,parse="i") bool "";
|
%typemap(inv,parse="i") bool "";
|
||||||
|
%typemap(inv,parse="i") enum SWIGTYPE "";
|
||||||
|
|
||||||
%typemap(inv,parse="l") unsigned int, unsigned short, unsigned long, unsigned char "(long) $1_name";
|
%typemap(inv,parse="l") unsigned int, unsigned short, unsigned long, unsigned char "(long) $1_name";
|
||||||
|
|
||||||
|
|
@ -453,6 +454,7 @@
|
||||||
|
|
||||||
%typemap(inv, parse="O") PyObject* "";
|
%typemap(inv, parse="O") PyObject* "";
|
||||||
|
|
||||||
|
%typemap(inv, parse="l") std::size_t "(long) $input";
|
||||||
|
|
||||||
/* // this is rather dangerous
|
/* // this is rather dangerous
|
||||||
%typemap(inv) SWIGTYPE {
|
%typemap(inv) SWIGTYPE {
|
||||||
|
|
@ -514,6 +516,7 @@ OUTV_TYPEMAP(double, PyFloat_AsDouble);
|
||||||
OUTV_TYPEMAP(bool, PyInt_AsLong);
|
OUTV_TYPEMAP(bool, PyInt_AsLong);
|
||||||
OUTV_TYPEMAP(PyObject *, );
|
OUTV_TYPEMAP(PyObject *, );
|
||||||
OUTV_TYPEMAP(char *, PyString_AsString);
|
OUTV_TYPEMAP(char *, PyString_AsString);
|
||||||
|
OUTV_TYPEMAP(std::size_t, PyInt_AsLong);
|
||||||
|
|
||||||
/* Object returned by value. Convert from a pointer */
|
/* Object returned by value. Convert from a pointer */
|
||||||
%typemap(outv) SWIGTYPE ($<ype argp)
|
%typemap(outv) SWIGTYPE ($<ype argp)
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ SwigComplex_AsComplexDouble(PyObject *o)
|
||||||
}
|
}
|
||||||
|
|
||||||
%typemap(inv) const complex<T> & {
|
%typemap(inv) const complex<T> & {
|
||||||
$inupt = PyComplex_FromDoubles($1_name->real(), $1_name->imag());
|
$input = PyComplex_FromDoubles($1_name->real(), $1_name->imag());
|
||||||
}
|
}
|
||||||
|
|
||||||
%typemap(outv) complex<T> {
|
%typemap(outv) complex<T> {
|
||||||
|
|
|
||||||
|
|
@ -203,9 +203,9 @@ namespace std {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
%typemap(inv) vector<T> {
|
%typemap(inv) vector<T> {
|
||||||
$input = PyTuple_New($1.size());
|
$input = PyTuple_New($1_name.size());
|
||||||
for (unsigned int i=0; i<$1.size(); i++) {
|
for (unsigned int i=0; i<$1_name.size(); i++) {
|
||||||
T* ptr = new T((($1_type &)$1)[i]);
|
T* ptr = new T((($1_type &)$1_name)[i]);
|
||||||
PyTuple_SetItem($input,i,
|
PyTuple_SetItem($input,i,
|
||||||
SWIG_NewPointerObj((void *) ptr,
|
SWIG_NewPointerObj((void *) ptr,
|
||||||
$descriptor(T *), 1));
|
$descriptor(T *), 1));
|
||||||
|
|
@ -486,7 +486,7 @@ namespace std {
|
||||||
%typemap(inv) vector<T> {
|
%typemap(inv) vector<T> {
|
||||||
$input = PyTuple_New($1_name.size());
|
$input = PyTuple_New($1_name.size());
|
||||||
for (unsigned int i=0; i<$1_name.size(); i++) {
|
for (unsigned int i=0; i<$1_name.size(); i++) {
|
||||||
T ptr = (($1_type &)$1)[i];
|
T ptr = (($1_type &)$1_name)[i];
|
||||||
PyTuple_SetItem($input,i,
|
PyTuple_SetItem($input,i,
|
||||||
SWIG_NewPointerObj((void *) ptr,
|
SWIG_NewPointerObj((void *) ptr,
|
||||||
$descriptor(T), 0));
|
$descriptor(T), 0));
|
||||||
|
|
|
||||||
|
|
@ -1640,6 +1640,8 @@ int Language::classDeclaration(Node *n) {
|
||||||
|
|
||||||
int Language::classHandler(Node *n) {
|
int Language::classHandler(Node *n) {
|
||||||
|
|
||||||
|
bool hasDirector = Swig_directorclass(n);
|
||||||
|
|
||||||
/* Emit all of the class members */
|
/* Emit all of the class members */
|
||||||
emit_children(n);
|
emit_children(n);
|
||||||
|
|
||||||
|
|
@ -1659,7 +1661,7 @@ int Language::classHandler(Node *n) {
|
||||||
if (!ImportMode && (GenerateDefault && !Getattr(n,"feature:nodefault"))) {
|
if (!ImportMode && (GenerateDefault && !Getattr(n,"feature:nodefault"))) {
|
||||||
if (!Getattr(n,"has_constructor") && !Getattr(n,"allocate:has_constructor") && (Getattr(n,"allocate:default_constructor"))) {
|
if (!Getattr(n,"has_constructor") && !Getattr(n,"allocate:has_constructor") && (Getattr(n,"allocate:default_constructor"))) {
|
||||||
/* Note: will need to change this to support different kinds of classes */
|
/* Note: will need to change this to support different kinds of classes */
|
||||||
if (!Abstract) {
|
if (!Abstract || hasDirector) {
|
||||||
Setattr(CurrentClass,"feature:new","1");
|
Setattr(CurrentClass,"feature:new","1");
|
||||||
constructorHandler(CurrentClass);
|
constructorHandler(CurrentClass);
|
||||||
Delattr(CurrentClass,"feature:new");
|
Delattr(CurrentClass,"feature:new");
|
||||||
|
|
@ -1671,7 +1673,7 @@ int Language::classHandler(Node *n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* emit director disown method */
|
/* emit director disown method */
|
||||||
if (Getattr(n, "vtable")) {
|
if (hasDirector) {
|
||||||
classDirectorDisown(n);
|
classDirectorDisown(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -650,24 +650,38 @@ Swig_ConstructorToFunction(Node *n, String *classname,
|
||||||
if (cplus) {
|
if (cplus) {
|
||||||
/* if a C++ director class exists, create it rather than the original class */
|
/* if a C++ director class exists, create it rather than the original class */
|
||||||
if (use_director) {
|
if (use_director) {
|
||||||
|
int abstract = Getattr(n, "abstract") != 0;
|
||||||
Node *parent = Swig_methodclass(n);
|
Node *parent = Swig_methodclass(n);
|
||||||
String *name = Getattr(parent, "sym:name");
|
String *name = Getattr(parent, "sym:name");
|
||||||
String* directorname = NewStringf("__DIRECTOR__%s", name);
|
String* directorname = NewStringf("__DIRECTOR__%s", name);
|
||||||
String* action = NewString("");
|
String* action = NewString("");
|
||||||
String* tmp_none_comparison = Copy(none_comparison);
|
String* tmp_none_comparison = Copy(none_comparison);
|
||||||
|
String* director_call;
|
||||||
|
String* nodirector_call;
|
||||||
|
|
||||||
Replaceall( tmp_none_comparison, "$arg", "arg1" );
|
Replaceall( tmp_none_comparison, "$arg", "arg1" );
|
||||||
|
|
||||||
/* if Python class has been subclassed, create a director instance.
|
director_call = Swig_cppconstructor_director_call(directorname, parms);
|
||||||
* otherwise, just create a normal instance.
|
nodirector_call = Swig_cppconstructor_nodirector_call(classname, parms);
|
||||||
*/
|
if (abstract) {
|
||||||
/* arty: arg1 != Py_None => tmp_none_comparison */
|
/* whether or not the abstract class has been subclassed in python,
|
||||||
Printv(action, "if (",tmp_none_comparison,") {/* subclassed */\n",
|
* create a director instance (there's no way to create a normal
|
||||||
Swig_cresult(type, "result", Swig_cppconstructor_director_call(directorname, parms)),
|
* instance). if any of the pure virtual methods haven't been
|
||||||
"} else {\n",
|
* implemented in the target language, calls to those methods will
|
||||||
Swig_cresult(type, "result", Swig_cppconstructor_nodirector_call(classname, parms)),
|
* generate SWIG_DIRECTOR_PURE_VIRTUAL exceptions.
|
||||||
"}\n",
|
*/
|
||||||
NULL);
|
Printv(action, Swig_cresult(type, "result", director_call), NULL);
|
||||||
|
} else {
|
||||||
|
/* if the proxy class has been subclassed, create a director instance.
|
||||||
|
* otherwise, just create a normal instance.
|
||||||
|
*/
|
||||||
|
Printv(action,
|
||||||
|
"if (",tmp_none_comparison,") {/* subclassed */\n",
|
||||||
|
Swig_cresult(type, "result", director_call),
|
||||||
|
"} else {\n",
|
||||||
|
Swig_cresult(type, "result", nodirector_call),
|
||||||
|
"}\n", NULL);
|
||||||
|
}
|
||||||
Setattr(n, "wrap:action", action);
|
Setattr(n, "wrap:action", action);
|
||||||
Delete(tmp_none_comparison);
|
Delete(tmp_none_comparison);
|
||||||
Delete(action);
|
Delete(action);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue