using static narrow methods instead of %extended ones.
now it looks more natural and similar to the CORBA downcasting mechanism. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@5587 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
42fd4b9c42
commit
394aacb890
4 changed files with 56 additions and 37 deletions
|
|
@ -18,6 +18,7 @@ public class virtual_poly_runme {
|
|||
NDouble d = new NDouble(3.5);
|
||||
NInt i = new NInt(2);
|
||||
|
||||
NInt j = virtual_poly.incr(i);
|
||||
//
|
||||
// These two natural 'copy' forms fail, only java and csharp
|
||||
// because no polymorphic return types are supported.
|
||||
|
|
@ -32,13 +33,16 @@ public class virtual_poly_runme {
|
|||
NNumber dc = d.copy();
|
||||
NNumber ic = i.copy();
|
||||
|
||||
|
||||
//
|
||||
// The real problem is that there is no way to recover the
|
||||
// original NInt or NDouble objects, even when you try
|
||||
// to use the plain and natural C++ dynamic_cast operations,
|
||||
// since they fail:
|
||||
// The real problem is that there is no way to recover the
|
||||
// original NInt or NDouble objects, even when you try to use the
|
||||
// plain and natural C++ dynamic_cast operation, or the user
|
||||
// downcasting mechanism:
|
||||
//
|
||||
NDouble ddc = virtual_poly.NDouble_dynamic_cast(dc);
|
||||
NInt dic = virtual_poly.NInt_dynamic_cast(ic);
|
||||
|
||||
// don't work
|
||||
NDouble ddc = NDouble.narrow(dc);
|
||||
NInt dic = NInt.narrow(ic);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,15 +15,20 @@ if d.get() != dc.get():
|
|||
if i.get() != ic.get():
|
||||
raise RuntimeError
|
||||
|
||||
virtual_poly.incr(ic)
|
||||
|
||||
if (i.get() + 1) != ic.get():
|
||||
raise RuntimeError
|
||||
|
||||
|
||||
|
||||
#
|
||||
# here this dynamic_cast is not needed at all,
|
||||
# but works fine anyway ('nnumber()' returns a NNumber).
|
||||
# 'narrowing' also works
|
||||
#
|
||||
ddc = virtual_poly.NDouble_dynamic_cast(dc.nnumber())
|
||||
ddc = virtual_poly.NDouble_narrow(d.nnumber())
|
||||
if d.get() != ddc.get():
|
||||
raise RuntimeError
|
||||
|
||||
dic = virtual_poly.NInt_dynamic_cast(ic.nnumber())
|
||||
dic = virtual_poly.NInt_narrow(i.nnumber())
|
||||
if i.get() != dic.get():
|
||||
raise RuntimeError
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ raise RuntimeError if d.get != dc.get
|
|||
raise RuntimeError if i.get != ic.get
|
||||
|
||||
#
|
||||
# dynamic cast working ('nnumber' returns a NNumber)
|
||||
# 'narrowing' working ('nnumber' returns a NNumber)
|
||||
#
|
||||
ddc = Virtual_poly.NDouble_dynamic_cast(dc.nnumber)
|
||||
ddc = Virtual_poly::NDouble.narrow(dc.nnumber)
|
||||
raise RuntimeError if d.get != ddc.get
|
||||
|
||||
dic = Virtual_poly.NInt_dynamic_cast(ic.nnumber)
|
||||
dic = Virtual_poly::NInt.narrow(ic.nnumber)
|
||||
raise RuntimeError if i.get != dic.get
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
%module(directors="1") virtual_poly
|
||||
|
||||
//
|
||||
// Check this example with directors wherever is possible.
|
||||
// It seems to be a good test since it breaks ruby at least.
|
||||
// python works fine with and without directors
|
||||
// In theory, Java should starts working with directors,
|
||||
// but this is not tested yet (my Java installation is broken).
|
||||
// Check this example with directors wherever is possible. Python and
|
||||
// ruby work fine with and without directors. In theory, Java may
|
||||
// start to work with directors, but this is not tested yet (my Java
|
||||
// installation is broken).
|
||||
//
|
||||
//%feature("director");
|
||||
|
||||
|
|
@ -17,7 +16,7 @@
|
|||
{
|
||||
virtual ~NNumber() {};
|
||||
virtual NNumber* copy() const = 0;
|
||||
|
||||
|
||||
NNumber* nnumber()
|
||||
{
|
||||
return this;
|
||||
|
|
@ -58,10 +57,18 @@
|
|||
return new NInt(val);
|
||||
}
|
||||
|
||||
/* See below */
|
||||
static NInt* narrow(NNumber* nn);
|
||||
|
||||
private:
|
||||
int val;
|
||||
};
|
||||
|
||||
inline NInt& incr(NInt& i) {
|
||||
i = i.get() + 1;
|
||||
return i;
|
||||
}
|
||||
|
||||
struct NDouble : NNumber
|
||||
{
|
||||
NDouble(double v) : val(v)
|
||||
|
|
@ -78,6 +85,9 @@
|
|||
return new NDouble(val);
|
||||
}
|
||||
|
||||
/* See below */
|
||||
static NDouble* narrow(NNumber* nn);
|
||||
|
||||
private:
|
||||
double val;
|
||||
};
|
||||
|
|
@ -95,32 +105,32 @@
|
|||
of the language (strongly typed and 'by value' oriented), and
|
||||
there is not much that can be done to work it around.
|
||||
|
||||
However, to improve the situation, and to be able to recover the
|
||||
original data types, we try adding 'dynamic_cast' interfaces in
|
||||
the target language sides. This is a natural mechanism since is
|
||||
exactly the same you will do in the C++ side if is needed.
|
||||
However, since the objects provide their own downcasting
|
||||
mechanim, the narrow methods similar to the CORBA mechanism,
|
||||
in theory you should be able to recover the original object
|
||||
types, just as you can do it in the C++ side or in other
|
||||
languages.
|
||||
*/
|
||||
inline NInt* NInt_dynamic_cast(NNumber* n) {
|
||||
inline NInt* NInt::narrow(NNumber* n) {
|
||||
// this is just a plain C++ dynamic_cast, but in theory the user
|
||||
// could use whatever he wants.
|
||||
return dynamic_cast<NInt*>(n);
|
||||
}
|
||||
|
||||
inline NDouble* NDouble_dynamic_cast(NNumber* n) {
|
||||
inline NDouble* NDouble::narrow(NNumber* n) {
|
||||
return dynamic_cast<NDouble*>(n);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
but they don't work either in Java (see the
|
||||
but the narrow methods don't work either in Java (see the
|
||||
java/virtual_poly_runme.java file), because of the current way
|
||||
polymorphic types are wrapped. Using the wrapping method employed
|
||||
with directors (which are also polymorphic types) should allows
|
||||
to use the C++ dynamic_cast and recover the original types at the
|
||||
Java side. And to do that, it is necessary to identify which
|
||||
classes are polymorphic (the "polymorphic" attribute does that)
|
||||
and apply the proper wrapping mechanism.
|
||||
polymorphic classes are wrapped, the user cannot downcast the
|
||||
Java temporary object when the C++ class (and associated Java
|
||||
class) is a base class in a class hierarchy.
|
||||
|
||||
The dynamic_cast interfaces added to this module, currently work
|
||||
great in languages like python, but in there the polymorphic
|
||||
return type also works, so, you are not forced to use them as a
|
||||
fixing mechanism (see the python/virtual_poly_runme.py file).
|
||||
The 'narrow' methods work currently fine in languages like
|
||||
python, but in there the polymorphic return type also works, so,
|
||||
you are not forced to use them everytime (see the
|
||||
python/virtual_poly_runme.py file).
|
||||
*/
|
||||
%}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue