| %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 */ | |
| %{ | |
| #if defined(__SUNPRO_CC) | |
| #pragma error_messages (off, wbadasg) /* Assigning extern "C" ... */ | |
| #endif | |
| %} | |
| #ifdef SWIGOCAML | |
| %warnfilter(SWIGWARN_PARSE_KEYWORD) method; | |
| #endif | |
| // | |
| // 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>; | |