/trunk/Lib/typemaps/factory.swg

# · Unknown · 88 lines · 68 code · 20 blank · 0 comment · 0 complexity · ad53503e3c425dc3d6969146317a14c7 MD5 · raw file

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