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:
Marcelo Matus 2003-12-23 10:10:04 +00:00
commit 394aacb890
4 changed files with 56 additions and 37 deletions

View file

@ -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);
}
}

View file

@ -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

View file

@ -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

View file

@ -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).
*/
%}