1/* 2 Implement a more natural wrap for factory methods, for example, if 3 you have: 4 5 ---- geometry.h -------- 6 struct Geometry { 7 enum GeomType{ 8 POINT, 9 CIRCLE 10 }; 11 12 virtual ~Geometry() {} 13 virtual int draw() = 0; 14 15 // 16 // Factory method for all the Geometry objects 17 // 18 static Geometry *create(GeomType i); 19 }; 20 21 struct Point : Geometry { 22 int draw() { return 1; } 23 double width() { return 1.0; } 24 }; 25 26 struct Circle : Geometry { 27 int draw() { return 2; } 28 double radius() { return 1.5; } 29 }; 30 31 // 32 // Factory method for all the Geometry objects 33 // 34 Geometry *Geometry::create(GeomType type) { 35 switch (type) { 36 case POINT: return new Point(); 37 case CIRCLE: return new Circle(); 38 default: return 0; 39 } 40 } 41 ---- geometry.h -------- 42 43 44 You can use the %factory with the Geometry::create method as follows: 45 46 %newobject Geometry::create; 47 %factory(Geometry *Geometry::create, Point, Circle); 48 %include "geometry.h" 49 50 and Geometry::create will return a 'Point' or 'Circle' instance 51 instead of the plain 'Geometry' type. For example, in python: 52 53 circle = Geometry.create(Geometry.CIRCLE) 54 r = circle.radius() 55 56 where circle is a Circle proxy instance. 57 58 NOTES: remember to fully qualify all the type names and don't 59 use %factory inside a namespace declaration, ie, instead of 60 61 namespace Foo { 62 %factory(Geometry *Geometry::create, Point, Circle); 63 } 64 65 use 66 67 %factory(Foo::Geometry *Foo::Geometry::create, Foo::Point, Foo::Circle); 68 69 70*/ 71 72%define %_factory_dispatch(Type) 73if (!dcast) { 74 Type *dobj = dynamic_cast<Type *>($1); 75 if (dobj) { 76 dcast = 1; 77 %set_output(SWIG_NewPointerObj(%as_voidptr(dobj),$descriptor(Type *), $owner | %newpointer_flags)); 78 } 79}%enddef 80 81%define %factory(Method,Types...) 82%typemap(out) Method { 83 int dcast = 0; 84 %formacro(%_factory_dispatch, Types) 85 if (!dcast) { 86 %set_output(SWIG_NewPointerObj(%as_voidptr($1),$descriptor, $owner | %newpointer_flags)); 87 } 88}%enddef 89