diff options
Diffstat (limited to 'Examples/test-suite/virtual_poly.i')
| -rw-r--r-- | Examples/test-suite/virtual_poly.i | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/Examples/test-suite/virtual_poly.i b/Examples/test-suite/virtual_poly.i new file mode 100644 index 0000000..d8051ae --- /dev/null +++ b/Examples/test-suite/virtual_poly.i @@ -0,0 +1,204 @@ +%module(directors="1") virtual_poly + +%warnfilter(SWIGWARN_JAVA_COVARIANT_RET, SWIGWARN_CSHARP_COVARIANT_RET) copy; /* Java, C# covariant return types */ +%warnfilter(SWIGWARN_JAVA_COVARIANT_RET, SWIGWARN_CSHARP_COVARIANT_RET) ref_this; /* Java, C# covariant return types */ +%warnfilter(SWIGWARN_JAVA_COVARIANT_RET, SWIGWARN_CSHARP_COVARIANT_RET) covariant; /* Java, C# covariant return types */ +%warnfilter(SWIGWARN_JAVA_COVARIANT_RET, SWIGWARN_CSHARP_COVARIANT_RET) covariant2; /* Java, C# covariant return types */ +%warnfilter(SWIGWARN_JAVA_COVARIANT_RET, SWIGWARN_CSHARP_COVARIANT_RET) covariant3; /* Java, C# covariant return types */ +%warnfilter(SWIGWARN_JAVA_COVARIANT_RET, SWIGWARN_CSHARP_COVARIANT_RET) covariant4; /* Java, C# covariant return types */ + +// +// Check this example with directors wherever possible. +// +//%feature("director"); + +// This shouldn't get used. +// %newobject *::copy(); + +%newobject *::copy() const; + + +%inline %{ + struct NNumber + { + virtual ~NNumber() {}; + virtual NNumber* copy() const = 0; + virtual NNumber& ref_this() + { + return *this; + } + + + NNumber* nnumber() + { + return this; + } + + + }; + + /* + NInt and NDouble are both NNumber derived classes, but they + have more different than common attributes. + + In particular the function 'get', that is type dependent, can't + be included in the NNumber abstract interface. + + For this reason, the virtual 'copy' method has a polymorphic (covariant) + return type, since in most of the cases we don't want to lose the + original object type, which is very very important. + + Using the polymorphic return type reduced greatly the need of + using 'dynamic_cast' at the C++ side, and at the target languages + that support it. + */ + struct NInt : NNumber + { + NInt(int v) : val(v) + { + } + + int get() const + { + return val; + } + + virtual NInt* copy() const + { + return new NInt(val); + } + + virtual NInt& ref_this() + { + return *this; + } + + /* 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) + { + } + + double get() const + { + return val; + } + + virtual NDouble* copy() const + { + return new NDouble(val); + } + + virtual NDouble& ref_this() + { + return *this; + } + + /* See below */ + static NDouble* narrow(NNumber* nn); + + private: + double val; + }; + + /* + Java and C# do not support the polymorphic (covariant) return types used + in the copy method. So, they just emit 'plain' copy functions as if this is + being wrapped instead: + + NNumber* NNumber::copy() const; + NNumber* NInt::copy() const; + NNumber* NDouble::copy() const; + + However, since the objects provide their own downcasting + mechanism, the narrow methods similar to the CORBA mechanism, + could be used, otherwise use the Java/C# downcasts. + */ + 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::narrow(NNumber* n) { + return dynamic_cast<NDouble*>(n); + } +%} + +%inline %{ + +// These three classes test covariant return types and whether swig accurately matches +// polymorphic methods (mainly for C# override keyword). Also tests methods which hide +// the base class' method (for C#, new keyword required on method declaration). + +typedef int* IntegerPtr; +typedef double Double; + +template<typename T> struct Base { + T t; + virtual IntegerPtr method() const = 0; + virtual IntegerPtr foxy() const = 0; + virtual IntegerPtr foxy(int a) const = 0; + virtual int * foxy(int*& a) { return 0; } + virtual double afunction() = 0; + virtual IntegerPtr defaultargs(double d, int * a = 0) = 0; + static void StaticHidden() {} + void AmIAmINotVirtual() {} + IntegerPtr NotVirtual(IntegerPtr i) { return 0; } + virtual Base * covariant(int a = 0, int * i = 0) { return 0; } + typedef Base * BasePtr; + virtual BasePtr covariant2() { return 0; } + virtual BasePtr covariant3() { return 0; } + virtual ~Base() {} +}; + +template<typename T> struct Derived : Base<T> { + int * method() const { return 0; } + IntegerPtr foxy() const { return 0; } + int * foxy(int a) const { return 0; } + virtual int * foxy(int*& a) { return 0; } + Double afunction() { return 0; } + int * defaultargs(Double d, IntegerPtr a = 0) { return 0; } + void AmIAmINotVirtual() {} + int * NotVirtual(int *i) { return 0; } + typedef Derived * DerivedPtr; + DerivedPtr covariant(int a = 0, IntegerPtr i = 0) { return 0; } + DerivedPtr covariant2() { return 0; } + Derived<T> * covariant3() { return 0; } + virtual Derived<T> * covariant4(double d) { return 0; } + virtual int IsVirtual() { return 0; } +}; + +template<typename T> struct Bottom : Derived<T> { + int * method() const { return 0; } + static void StaticHidden() {} + void AmIAmINotVirtual() {} + IntegerPtr NotVirtual(IntegerPtr i) { return 0; } + void (*funcptr)(int a, bool b); + Bottom<T> * covariant(int a = 0, IntegerPtr i = 0) { return 0; } + Derived<T> * covariant2() { return 0; } + Bottom<T> * covariant3() { return 0; } + Bottom<T> * covariant4(double d) { return 0; } + int IsVirtual() { return 0; } +}; +%} + + +%template(BaseInt) Base<int>; +%template(DerivedInt) Derived<int>; +%template(BottomInt) Bottom<int>; + + |
