add the factory library for UTL

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@8865 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2006-02-22 18:42:20 +00:00
commit 44264e5544
8 changed files with 128 additions and 0 deletions

View file

@ -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;
}
}
}

View file

@ -31,6 +31,7 @@ CPP_TEST_CASES += \
kwargs \
li_cstring \
li_cwstring \
li_factory \
li_implicit \
li_std_vectora \
li_std_map \

View file

@ -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

1
Lib/perl5/factory.i Normal file
View file

@ -0,0 +1 @@
%include <typemaps/factory.swg>

1
Lib/python/factory.i Normal file
View file

@ -0,0 +1 @@
%include <typemaps/factory.swg>

1
Lib/ruby/factory.i Normal file
View file

@ -0,0 +1 @@
%include <typemaps/factory.swg>

1
Lib/tcl/factory.i Normal file
View file

@ -0,0 +1 @@
%include <typemaps/factory.swg>

75
Lib/typemaps/factory.swg Normal file
View file

@ -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<Type *>($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