From 44264e554464b579985cd5ebb59acf5f1a554ef8 Mon Sep 17 00:00:00 2001 From: Marcelo Matus Date: Wed, 22 Feb 2006 18:42:20 +0000 Subject: [PATCH] add the factory library for UTL git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@8865 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/li_factory.i | 37 +++++++++ Examples/test-suite/python/Makefile.in | 1 + .../test-suite/python/li_factory_runme.py | 11 +++ Lib/perl5/factory.i | 1 + Lib/python/factory.i | 1 + Lib/ruby/factory.i | 1 + Lib/tcl/factory.i | 1 + Lib/typemaps/factory.swg | 75 +++++++++++++++++++ 8 files changed, 128 insertions(+) create mode 100644 Examples/test-suite/li_factory.i create mode 100644 Examples/test-suite/python/li_factory_runme.py create mode 100644 Lib/perl5/factory.i create mode 100644 Lib/python/factory.i create mode 100644 Lib/ruby/factory.i create mode 100644 Lib/tcl/factory.i create mode 100644 Lib/typemaps/factory.swg diff --git a/Examples/test-suite/li_factory.i b/Examples/test-suite/li_factory.i new file mode 100644 index 000000000..97bf56e17 --- /dev/null +++ b/Examples/test-suite/li_factory.i @@ -0,0 +1,37 @@ +%module li_factory +%include factory.i + +%newobject Geometry::create; +%factory(Geometry *Geometry::create, Point, Circle); + +%inline { + struct Geometry { + enum GeomType{ + POINT, + CIRCLE + }; + + virtual ~Geometry() {} + virtual int draw() = 0; + static Geometry *create(GeomType i); + }; + + struct Point : Geometry { + int draw() { return 1; } + double width() { return 1.0; } + }; + + struct Circle : Geometry { + int draw() { return 2; } + double radius() { return 1.5; } + }; + + Geometry *Geometry::create(GeomType type) { + switch (type) { + case POINT: return new Point(); + case CIRCLE: return new Circle(); + default: return 0; + } + } +} + diff --git a/Examples/test-suite/python/Makefile.in b/Examples/test-suite/python/Makefile.in index 4453a6e78..a3291e9a4 100644 --- a/Examples/test-suite/python/Makefile.in +++ b/Examples/test-suite/python/Makefile.in @@ -31,6 +31,7 @@ CPP_TEST_CASES += \ kwargs \ li_cstring \ li_cwstring \ + li_factory \ li_implicit \ li_std_vectora \ li_std_map \ diff --git a/Examples/test-suite/python/li_factory_runme.py b/Examples/test-suite/python/li_factory_runme.py new file mode 100644 index 000000000..ce0e3caef --- /dev/null +++ b/Examples/test-suite/python/li_factory_runme.py @@ -0,0 +1,11 @@ +from li_factory import * + +circle = Geometry.create(Geometry.CIRCLE) +r = circle.radius() +if (r != 1.5): + raise RuntimeError + +point = Geometry.create(Geometry.POINT) +w = point.width() +if (w != 1.0): + raise RuntimeError diff --git a/Lib/perl5/factory.i b/Lib/perl5/factory.i new file mode 100644 index 000000000..46a0a8733 --- /dev/null +++ b/Lib/perl5/factory.i @@ -0,0 +1 @@ +%include diff --git a/Lib/python/factory.i b/Lib/python/factory.i new file mode 100644 index 000000000..46a0a8733 --- /dev/null +++ b/Lib/python/factory.i @@ -0,0 +1 @@ +%include diff --git a/Lib/ruby/factory.i b/Lib/ruby/factory.i new file mode 100644 index 000000000..46a0a8733 --- /dev/null +++ b/Lib/ruby/factory.i @@ -0,0 +1 @@ +%include diff --git a/Lib/tcl/factory.i b/Lib/tcl/factory.i new file mode 100644 index 000000000..46a0a8733 --- /dev/null +++ b/Lib/tcl/factory.i @@ -0,0 +1 @@ +%include diff --git a/Lib/typemaps/factory.swg b/Lib/typemaps/factory.swg new file mode 100644 index 000000000..ccdbd77f9 --- /dev/null +++ b/Lib/typemaps/factory.swg @@ -0,0 +1,75 @@ +/* + Implement a more natural wrap for factory methods, for example, if + you have: + + ---- geometry.h -------- + struct Geometry { + enum GeomType{ + POINT, + CIRCLE + }; + + virtual ~Geometry() {} + virtual int draw() = 0; + + // + // Factory method for all the Geometry objects + // + static Geometry *create(GeomType i); + }; + + struct Point : Geometry { + int draw() { return 1; } + double width() { return 1.0; } + }; + + struct Circle : Geometry { + int draw() { return 2; } + double radius() { return 1.5; } + }; + + // + // Factory method for all the Geometry objects + // + Geometry *Geometry::create(GeomType type) { + switch (type) { + case POINT: return new Point(); + case CIRCLE: return new Circle(); + default: return 0; + } + } + ---- geometry.h -------- + + + You can use the %factory with the Geometry::create method as follows: + + %newobject Geometry::create; + %factory(Geometry *Geometry::create, Point, Circle); + %include "geometry.h" + + and Geometry::create will return a 'Point' or 'Circle' instance + instead of the plain 'Geometry' type. For example, in python: + + circle = Geometry.create(Geometry.CIRCLE) + r = circle.radius() + + where circle is a Circle proxy instance. +*/ + +%define %_factory_dispatch(Type) +if (!dcast) { + Type *dobj = dynamic_cast($1); + if (dobj) { + dcast = 1; + %set_output(SWIG_NewPointerObj(%as_voidptr(dobj),$descriptor(Type *), $owner | %newpointer_flags)); + } +}%enddef + +%define %factory(Method,Types...) +%typemap(out) Method { + int dcast = 0; + %formacro(%_factory_dispatch, Types) + if (!dcast) { + %set_output(SWIG_NewPointerObj(%as_voidptr($1),$descriptor, $owner | %newpointer_flags)); + } +}%enddef