add castmode in python and cleaning the castdispatch mechanism

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@8051 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2005-12-23 09:22:17 +00:00
commit 5a76bc68fc
16 changed files with 461 additions and 101 deletions

View file

@ -1,6 +1,46 @@
Version 1.3.28 (unreleased). Version 1.3.28 (unreleased).
=========================== ===========================
12/23/2005: mmatus
[python] Add the castmode that allows the python
type casting to occurr.
For example, if you have 'int foo(int)', now
class Ai():
def __init__(self,x):
self.x = x
def __int__(self):
return self.x
foo(1) // Ok
foo(1.0) // Ok
foo(1.3) // Error
a = Ai(4)
foo(ai) // Ok
The castmode, which can be enable either with the
'-castmode' option or the %module("castmode") option, uses
the new cast/rank dispatch mechanism. Hence, now if you
have 'int foo(int); int foo(double);', the following works
as expected:
foo(1) -> foo(int)
foo(1.0) -> foo(double)
ai = Ai(4)
foo(ai) -> foo(int)
Note1: the 'castmode' could disrupt some specialized
typemaps. In particular, the "implicit.i" library seems to
have problem with the castmode. But besides that one, the
entire test-suite compiles fine with and without the
castmode.
Note2: the castmode disables the -fatdispatch option.
See the file overload_dispatch_cast_runme.py file for
new cases and examples.
12/22/2005: mmatus 12/22/2005: mmatus
Add the cast and rank mechanism to dispatch overloading Add the cast and rank mechanism to dispatch overloading
functions. The UTF supports it now, but for each language functions. The UTF supports it now, but for each language

View file

@ -4,9 +4,6 @@ $f = new overload_simple::Foo();
$b = new overload_simple::Bar(); $b = new overload_simple::Bar();
$v = overload_simple::malloc_void(32); $v = overload_simple::malloc_void(32);
#
# 'simple' dispatch (no overload) of int and double arguments
#
# #
# Silence warnings about bad types # Silence warnings about bad types
@ -40,6 +37,10 @@ if (!$@) {
# #
$DOWARN =1; $DOWARN =1;
#
# 'simple' dispatch (no overload) of int and double arguments
#
if (!(overload_simple::fint(3) eq "fint:int")) { if (!(overload_simple::fint(3) eq "fint:int")) {
die("fint(int)"); die("fint(int)");
} }
@ -159,6 +160,8 @@ if (!($s->foo(3.0) eq "foo:double")) {
} }
if (!($s->foo("hello") eq "foo:char *")) { if (!($s->foo("hello") eq "foo:char *")) {
$r = $s->foo("hello");
print "res $r\n";
die("Spam::foo(char *)"); die("Spam::foo(char *)");
} }
@ -275,6 +278,8 @@ if (!(overload_simple::fid(3.0, "3") eq "fid:doubleint")) {
} }
if (!(overload_simple::fid("3.0", "3.0") eq "fid:doubledouble")) { if (!(overload_simple::fid("3.0", "3.0") eq "fid:doubledouble")) {
$r = overload_simple::fid("3.0", "3.0");
print "$r \n";
die("fid(double,double)"); die("fid(double,double)");
} }

View file

@ -35,6 +35,7 @@ CPP_TEST_CASES += \
li_std_wstream \ li_std_wstream \
li_std_wstring \ li_std_wstring \
nondynamic \ nondynamic \
overload_simple_cast \
primitive_types \ primitive_types \
std_containers \ std_containers \
swigobject \ swigobject \
@ -100,3 +101,4 @@ cvsignore:
@echo imports_b.py @echo imports_b.py
@echo template_typedef_import.py @echo template_typedef_import.py

View file

@ -0,0 +1,4 @@
// Simple tests of overloaded functions
%module("castmode") overload_simple_cast
%include overload_simple.i

View file

@ -0,0 +1,165 @@
from overload_simple_cast import *
class Ai:
def __init__(self,x):
self.x = x
def __int__(self):
return self.x
class Ad:
def __init__(self,x):
self.x = x
def __float__(self):
return self.x
ai = Ai(4)
ad = Ad(5.0)
add = Ad(5.5)
try:
fint(add)
good = 0
except:
good = 1
if not good:
raise RuntimeError, "fint(int)"
if fint(ad) != "fint:int":
raise RuntimeError, "fint(int)"
if fdouble(ad) != "fdouble:double":
raise RuntimeError, "fdouble(double)"
if fint(ai) != "fint:int":
raise RuntimeError, "fint(int)"
if fint(5.0) != "fint:int":
raise RuntimeError, "fint(int)"
if fint(3) != "fint:int":
raise RuntimeError, "fint(int)"
if fint(3.0) != "fint:int":
raise RuntimeError, "fint(int)"
if fdouble(ad) != "fdouble:double":
raise RuntimeError, "fdouble(double)"
if fdouble(3) != "fdouble:double":
raise RuntimeError, "fdouble(double)"
if fdouble(3.0) != "fdouble:double":
raise RuntimeError, "fdouble(double)"
if fid(3,3.0) != "fid:intdouble":
raise RuntimeError, "fid:intdouble"
if fid(3.0,3) != "fid:doubleint":
raise RuntimeError, "fid:doubleint"
if fid(ad,ai) != "fid:doubleint":
raise RuntimeError, "fid:doubleint"
if fid(ai,ad) != "fid:intdouble":
raise RuntimeError, "fid:intdouble"
if foo(3) != "foo:int":
raise RuntimeError, "foo(int)"
if foo(3.0) != "foo:double":
raise RuntimeError, "foo(double)"
if foo("hello") != "foo:char *":
raise RuntimeError, "foo(char *)"
f = Foo()
b = Bar()
if foo(f) != "foo:Foo *":
raise RuntimeError, "foo(Foo *)"
if foo(b) != "foo:Bar *":
raise RuntimeError, "foo(Bar *)"
v = malloc_void(32)
if foo(v) != "foo:void *":
raise RuntimeError, "foo(void *)"
s = Spam()
if s.foo(3) != "foo:int":
raise RuntimeError, "Spam::foo(int)"
if s.foo(3.0) != "foo:double":
raise RuntimeError, "Spam::foo(double)"
if s.foo("hello") != "foo:char *":
raise RuntimeError, "Spam::foo(char *)"
if s.foo(f) != "foo:Foo *":
raise RuntimeError, "Spam::foo(Foo *)"
if s.foo(b) != "foo:Bar *":
raise RuntimeError, "Spam::foo(Bar *)"
if s.foo(v) != "foo:void *":
raise RuntimeError, "Spam::foo(void *)"
if Spam_bar(3) != "bar:int":
raise RuntimeError, "Spam::bar(int)"
if Spam_bar(3.0) != "bar:double":
raise RuntimeError, "Spam::bar(double)"
if Spam_bar("hello") != "bar:char *":
raise RuntimeError, "Spam::bar(char *)"
if Spam_bar(f) != "bar:Foo *":
raise RuntimeError, "Spam::bar(Foo *)"
if Spam_bar(b) != "bar:Bar *":
raise RuntimeError, "Spam::bar(Bar *)"
if Spam_bar(v) != "bar:void *":
raise RuntimeError, "Spam::bar(void *)"
# Test constructors
s = Spam()
if s.type != "none":
raise RuntimeError, "Spam()"
s = Spam(3)
if s.type != "int":
raise RuntimeError, "Spam(int)"
s = Spam(3.4)
if s.type != "double":
raise RuntimeError, "Spam(double)"
s = Spam("hello")
if s.type != "char *":
raise RuntimeError, "Spam(char *)"
s = Spam(f)
if s.type != "Foo *":
raise RuntimeError, "Spam(Foo *)"
s = Spam(b)
if s.type != "Bar *":
raise RuntimeError, "Spam(Bar *)"
s = Spam(v)
if s.type != "void *":
raise RuntimeError, "Spam(void *)"
free_void(v)

View file

@ -15,7 +15,7 @@ SWIG_From_dec(long)(long value)
} }
%fragment(SWIG_AsVal_frag(long),"header", %fragment(SWIG_AsVal_frag(long),"header",
fragment=SWIG_AsVal_frag(double)) { fragment="SWIG_CanCastAsInteger") {
SWIGINTERN int SWIGINTERN int
SWIG_AsVal_dec(long)(SV *obj, long* val) SWIG_AsVal_dec(long)(SV *obj, long* val)
{ {
@ -34,25 +34,16 @@ SWIG_AsVal_dec(long)(SV *obj, long* val)
} else { } else {
if (*endptr == '\0') { if (*endptr == '\0') {
if (val) *val = v; if (val) *val = v;
return SWIG_AddCast(SWIG_OK); return SWIG_CastRank(SWIG_OK);
} }
} }
} }
if (!dispatch) { if (!dispatch) {
double d; double d;
int res = SWIG_AsVal(double)(obj,&d); int res = SWIG_CastRank(SWIG_AsVal(double)(obj,&d));
if (SWIG_IsOK(res)) { if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) {
if (LONG_MIN <= d && d <= LONG_MAX) { if (val) *val = (long)(d);
double rd = rint(d); return res;
if (errno) {
errno = 0;
} else {
if (rd == d) {
if (val) *val = (long)(rd);
return SWIG_AddCast(res);
}
}
}
} }
} }
} }
@ -74,7 +65,7 @@ SWIG_From_dec(unsigned long)(unsigned long value)
} }
%fragment(SWIG_AsVal_frag(unsigned long),"header", %fragment(SWIG_AsVal_frag(unsigned long),"header",
fragment=SWIG_AsVal_frag(double)) { fragment="SWIG_CanCastAsInteger") {
SWIGINTERN int SWIGINTERN int
SWIG_AsVal_dec(unsigned long)(SV *obj, unsigned long *val) SWIG_AsVal_dec(unsigned long)(SV *obj, unsigned long *val)
{ {
@ -101,29 +92,19 @@ SWIG_AsVal_dec(unsigned long)(SV *obj, unsigned long *val)
} else { } else {
if (*endptr == '\0') { if (*endptr == '\0') {
if (val) *val = v; if (val) *val = v;
return SWIG_AddCast(SWIG_OK); return SWIG_CastRank(SWIG_OK);
} }
} }
} }
if (!dispatch) { if (!dispatch) {
double d; double d;
int res = SWIG_AsVal(double)(obj,&d); int res = SWIG_CastRank(SWIG_AsVal(double)(obj,&d));
if (SWIG_IsOK(res) && (d >= 0)) { if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULONG_MAX)) {
if (d <= ULONG_MAX) { if (val) *val = (unsigned long)(d);
double rd = rint(d); return res;
if (errno) {
errno = 0;
} else {
if (rd == d) {
if (val) *val = (long)(rd);
return SWIG_AddCast(res);
}
}
}
} }
} }
} }
return SWIG_TypeError; return SWIG_TypeError;
} }
} }
@ -149,8 +130,8 @@ SWIG_From_dec(long long)(long long value)
} }
%fragment(SWIG_AsVal_frag(long long),"header", %fragment(SWIG_AsVal_frag(long long),"header",
fragment=SWIG_AsVal_frag(double), fragment="<limits.h>",
fragment="<limits.h>") { fragment="SWIG_CanCastAsInteger") {
SWIGINTERN int SWIGINTERN int
SWIG_AsVal_dec(long long)(SV *obj, long long *val) SWIG_AsVal_dec(long long)(SV *obj, long long *val)
@ -170,25 +151,16 @@ SWIG_AsVal_dec(long long)(SV *obj, long long *val)
} else { } else {
if (*endptr == '\0') { if (*endptr == '\0') {
if (val) *val = v; if (val) *val = v;
return SWIG_AddCast(SWIG_OK); return SWIG_CastRank(SWIG_OK);
} }
} }
} }
if (!dispatch) { if (!dispatch) {
double d; double d;
int res = SWIG_AsVal(double)(obj,&d); int res = SWIG_CastRank(SWIG_AsVal(double)(obj,&d));
if (SWIG_IsOK(res)) { if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LLONG_MIN, LLONG_MAX)) {
if (LLONG_MIN <= d && d <= LLONG_MAX) { if (val) *val = (long long)(d);
double rd = rint(d); return res;
if (errno) {
errno = 0;
} else {
if (rd == d) {
if (val) *val = (long long)(rd);
return SWIG_AddCast(res);
}
}
}
} }
} }
} }
@ -217,8 +189,8 @@ SWIG_From_dec(unsigned long long)(unsigned long long value)
} }
%fragment(SWIG_AsVal_frag(unsigned long long),"header", %fragment(SWIG_AsVal_frag(unsigned long long),"header",
fragment=SWIG_AsVal_frag(double), fragment="<limits.h>",
fragment="<limits.h>") { fragment="SWIG_CanCastAsInteger") {
SWIGINTERN int SWIGINTERN int
SWIG_AsVal_dec(unsigned long long)(SV *obj, unsigned long long *val) SWIG_AsVal_dec(unsigned long long)(SV *obj, unsigned long long *val)
{ {
@ -237,25 +209,16 @@ SWIG_AsVal_dec(unsigned long long)(SV *obj, unsigned long long *val)
} else { } else {
if (*endptr == '\0') { if (*endptr == '\0') {
if (val) *val = v; if (val) *val = v;
return SWIG_AddCast(SWIG_OK); return SWIG_CastRank(SWIG_OK);
} }
} }
} }
if (!dispatch) { if (!dispatch) {
double d; double d;
int res = SWIG_AsVal(double)(obj,&d); int res = SWIG_CastRank(SWIG_AsVal(double)(obj,&d));
if (SWIG_IsOK(res) && (d >=0 )) { if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULLONG_MAX)) {
if (d <= ULLONG_MAX) { if (val) *val = (unsigned long long)(d);
double rd = rint(d); return res;
if (errno) {
errno = 0;
} else {
if (rd == d) {
if (val) *val = (unsigned long long)(rd);
return SWIG_AddCast(res);
}
}
}
} }
} }
} }
@ -283,8 +246,8 @@ SWIG_AsVal_dec(double)(SV *obj, double *val)
if (val) *val = SvNV(obj); if (val) *val = SvNV(obj);
return SWIG_OK; return SWIG_OK;
} else if (SvIOK(obj)) { } else if (SvIOK(obj)) {
if (val) *val = SvIV(obj); if (val) *val = (double) SvIV(obj);
return SWIG_AddCast(SWIG_OK); return SWIG_CastRank(SWIG_OK);
} else { } else {
const char *nptr = SvPV(obj, PL_na); const char *nptr = SvPV(obj, PL_na);
if (nptr) { if (nptr) {
@ -296,7 +259,7 @@ SWIG_AsVal_dec(double)(SV *obj, double *val)
} else { } else {
if (*endptr == '\0') { if (*endptr == '\0') {
if (val) *val = v; if (val) *val = v;
return SWIG_AddCast(SWIG_OK); return SWIG_CastRank(SWIG_OK);
} }
} }
} }

View file

@ -32,11 +32,12 @@ SWIG_AsVal(Type) (PyObject *o, Type* val)
return SWIG_OK; return SWIG_OK;
} else { } else {
double d; double d;
if (SWIG_AsVal(double)(o, &d) == SWIG_OK) { int res = SWIG_CastRank(SWIG_AsVal(double)(o, &d));
if (SWIG_IsOK(res)) {
if (val) *val = Constructor(d, 0.0); if (val) *val = Constructor(d, 0.0);
return SWIG_OK; return res;
} }
} }
return SWIG_TypeError; return SWIG_TypeError;
} }
} }
@ -61,10 +62,11 @@ SWIG_AsVal(Type)(PyObject *o, Type *val)
return SWIG_OverflowError; return SWIG_OverflowError;
} }
} else { } else {
float re; float re;
if (SWIG_AsVal(float)(o, &re) == SWIG_OK) { int res = SWIG_CastRank(SWIG_AsVal(float)(o, &re));
if (SWIG_IsOK(res)) {
if (val) *val = Constructor(re, 0.0); if (val) *val = Constructor(re, 0.0);
return SWIG_OK; return res;
} }
} }
return SWIG_TypeError; return SWIG_TypeError;

View file

@ -27,8 +27,8 @@ SWIG_AsVal_dec(bool)(PyObject *obj, bool *val)
return SWIG_OK; return SWIG_OK;
} else { } else {
long v = 0; long v = 0;
int res = SWIG_AsVal(long)(obj, val ? &v : 0); int res = SWIG_CastRank(SWIG_AsVal(long)(obj, val ? &v : 0));
if (res == SWIG_OK && val) *val = v ? true : false; if (SWIG_IsOK(res) && val) *val = v ? true : false;
return res; return res;
} }
} }
@ -41,7 +41,8 @@ SWIG_AsVal_dec(bool)(PyObject *obj, bool *val)
%define_as(SWIG_From_dec(long), PyInt_FromLong) %define_as(SWIG_From_dec(long), PyInt_FromLong)
} }
%fragment(SWIG_AsVal_frag(long),"header") { %fragment(SWIG_AsVal_frag(long),"header",
fragment="SWIG_CanCastAsInteger") {
SWIGINTERN int SWIGINTERN int
SWIG_AsVal_dec(long)(PyObject *obj, long* val) SWIG_AsVal_dec(long)(PyObject *obj, long* val)
{ {
@ -57,6 +58,26 @@ SWIG_AsVal_dec(long)(PyObject *obj, long* val)
PyErr_Clear(); PyErr_Clear();
} }
} }
%#ifdef SWIG_PYTHON_CAST_MODE
{
int dispatch = 0;
long v = PyInt_AsLong(obj);
if (!PyErr_Occurred()) {
if (val) *val = v;
return SWIG_CastRank(SWIG_OK);
} else {
PyErr_Clear();
}
if (!dispatch) {
double d;
int res = SWIG_CastRank(SWIG_AsVal(double)(obj,&d));
if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) {
if (val) *val = (long)(d);
return res;
}
}
}
%#endif
return SWIG_TypeError; return SWIG_TypeError;
} }
} }
@ -73,7 +94,8 @@ SWIG_From_dec(unsigned long)(unsigned long value)
} }
} }
%fragment(SWIG_AsVal_frag(unsigned long),"header") { %fragment(SWIG_AsVal_frag(unsigned long),"header",
fragment="SWIG_CanCastAsInteger") {
SWIGINTERN int SWIGINTERN int
SWIG_AsVal_dec(unsigned long)(PyObject *obj, unsigned long *val) SWIG_AsVal_dec(unsigned long)(PyObject *obj, unsigned long *val)
{ {
@ -94,6 +116,30 @@ SWIG_AsVal_dec(unsigned long)(PyObject *obj, unsigned long *val)
PyErr_Clear(); PyErr_Clear();
} }
} }
%#ifdef SWIG_PYTHON_CAST_MODE
{
int dispatch = 0;
long v = PyInt_AsLong(obj);
if (!PyErr_Occurred()) {
if (v >= 0) {
if (val) *val = v;
return SWIG_CastRank(SWIG_OK);
} else {
return SWIG_OverflowError;
}
} else {
PyErr_Clear();
}
if (!dispatch) {
double d;
int res = SWIG_CastRank(SWIG_AsVal(double)(obj,&d));
if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULONG_MAX)) {
if (val) *val = (unsigned long)(d);
return res;
}
}
}
%#endif
return SWIG_TypeError; return SWIG_TypeError;
} }
} }
@ -111,7 +157,9 @@ SWIG_From_dec(long long)(long long value)
} }
} }
%fragment(SWIG_AsVal_frag(long long),"header") { %fragment(SWIG_AsVal_frag(long long),"header",
fragment="SWIG_CanCastAsInteger",
fragment="<limits.h>") {
SWIGINTERN int SWIGINTERN int
SWIG_AsVal_dec(long long)(PyObject *obj, long long *val) SWIG_AsVal_dec(long long)(PyObject *obj, long long *val)
{ {
@ -127,6 +175,26 @@ SWIG_AsVal_dec(long long)(PyObject *obj, long long *val)
PyErr_Clear(); PyErr_Clear();
} }
} }
%#ifdef SWIG_PYTHON_CAST_MODE
{
int dispatch = 0;
long v = PyInt_AsLong(obj);
if (!PyErr_Occurred()) {
if (val) *val = v;
return SWIG_CastRank(SWIG_OK);
} else {
PyErr_Clear();
}
if (!dispatch) {
double d;
int res = SWIG_CastRank(SWIG_AsVal(double)(obj,&d));
if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LLONG_MIN, LLONG_MAX)) {
if (val) *val = (long long)(d);
return res;
}
}
}
%#endif
return SWIG_TypeError; return SWIG_TypeError;
} }
} }
@ -145,7 +213,9 @@ SWIG_From_dec(unsigned long long)(unsigned long long value)
} }
%fragment(SWIG_AsVal_frag(unsigned long long),"header", %fragment(SWIG_AsVal_frag(unsigned long long),"header",
fragment=SWIG_AsVal_frag(unsigned long)) { fragment=SWIG_AsVal_frag(unsigned long),
fragment="SWIG_CanCastAsInteger",
fragment="<limits.h>") {
SWIGINTERN int SWIGINTERN int
SWIG_AsVal_dec(unsigned long long)(PyObject *obj, unsigned long long *val) SWIG_AsVal_dec(unsigned long long)(PyObject *obj, unsigned long long *val)
{ {
@ -160,9 +230,33 @@ SWIG_AsVal_dec(unsigned long long)(PyObject *obj, unsigned long long *val)
} else { } else {
unsigned long v; unsigned long v;
int res = SWIG_AsVal(unsigned long)(obj,&v); int res = SWIG_AsVal(unsigned long)(obj,&v);
if (res == SWIG_OK && val) *val = v; if (SWIG_IsOK(res) && val) *val = v;
return res; return res;
} }
%#ifdef SWIG_PYTHON_CAST_MODE
{
int dispatch = 0;
long v = PyInt_AsLong(obj);
if (!PyErr_Occurred()) {
if (v >= 0) {
if (val) *val = v;
return SWIG_CastRank(SWIG_OK);
} else {
return SWIG_OverflowError;
}
} else {
PyErr_Clear();
}
if (!dispatch) {
double d;
int res = SWIG_CastRank(SWIG_AsVal(double)(obj,&d));
if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULLONG_MAX)) {
if (val) *val = (unsigned long)(d);
return res;
}
}
}
%#endif
return SWIG_TypeError; return SWIG_TypeError;
} }
} }
@ -192,6 +286,27 @@ SWIG_AsVal_dec(double)(PyObject *obj, double *val)
PyErr_Clear(); PyErr_Clear();
} }
} }
%#ifdef SWIG_PYTHON_CAST_MODE
{
int dispatch = 0;
double d = PyFloat_AsDouble(obj);
if (!PyErr_Occurred()) {
if (val) *val = d;
return SWIG_CastRank(SWIG_OK);
} else {
PyErr_Clear();
}
if (!dispatch) {
long v = PyInt_AsLong(obj);
if (!PyErr_Occurred()) {
if (val) *val = v;
return SWIG_CastRank(SWIG_CastRank(SWIG_OK));
} else {
PyErr_Clear();
}
}
}
%#endif
return SWIG_TypeError; return SWIG_TypeError;
} }
} }

View file

@ -99,7 +99,7 @@ namespace swig {
struct traits_as<Type, value_category> { struct traits_as<Type, value_category> {
static Type as(PyObject *obj, bool throw_error) { static Type as(PyObject *obj, bool throw_error) {
Type v; Type v;
if (!obj || (asval(obj, &v) != SWIG_OK)) { if (!obj || !SWIG_IsOK(asval(obj, &v))) {
if (!PyErr_Occurred()) { if (!PyErr_Occurred()) {
%type_error(swig::type_name<Type>()); %type_error(swig::type_name<Type>());
} }
@ -160,7 +160,7 @@ namespace swig {
template <class Type> template <class Type>
struct traits_check<Type, value_category> { struct traits_check<Type, value_category> {
static bool check(PyObject *obj) { static bool check(PyObject *obj) {
return obj && (asval(obj, (Type *)(0)) == SWIG_OK); return obj && SWIG_IsOK(asval(obj, (Type *)(0)));
} }
}; };

View file

@ -12,3 +12,4 @@
#define SWIG_AttributeError -11 #define SWIG_AttributeError -11
#define SWIG_MemoryError -12 #define SWIG_MemoryError -12

View file

@ -58,10 +58,17 @@
#define SWIG_ERROR -1 #define SWIG_ERROR -1
/* Flags to manage cast and return states */ /* Flags to manage cast and return states */
#define SWIG_MAX_CAST_RANK 4 #ifndef SWIG_TypeRank
# define SWIG_TypeRank unsigned long
#endif
#ifndef SWIG_MAX_CAST_RANK
# define SWIG_MAX_CAST_RANK 2 /* Two cast allowed */
#endif
#define SWIG_IsOK(r) (r >= 0) #define SWIG_IsOK(r) (r >= 0)
#define SWIG_AddCast(r) (SWIG_IsOK(r) ? (r + 1) : r) SWIGINTERNINLINE int
#define SWIG_GetCastRank(r) (SWIG_IsOK(r) ? ((r < SWIG_MAX_CAST_RANK) ? (r + 1) : 0) : 0) SWIG_CastRank(int r) {
return (SWIG_IsOK(r)) ? ((r < SWIG_MAX_CAST_RANK) ? (r + 1) : SWIG_ERROR) : r;
}
#include <string.h> #include <string.h>

View file

@ -103,9 +103,9 @@ or you can use the %apply directive :
} }
%typemap(typecheck,noblock=1,precedence=code,fragment=asval_frag) Type *INPUT, Type &INPUT { %typemap(typecheck,noblock=1,precedence=code,fragment=asval_frag) Type *INPUT, Type &INPUT {
void *ptr; void *ptr;
int res = asval_meth($input, 0); int res = SWIG_CastRank(asval_meth($input, 0));
if (SWIG_IsOK(res)) { if (SWIG_IsOK(res)) {
$1 = SWIG_GetCastRank(res); $1 = res;
} else { } else {
$1 = %check_input_ptr($input,&ptr,$1_descriptor,0); $1 = %check_input_ptr($input,&ptr,$1_descriptor,0);
} }

View file

@ -197,6 +197,40 @@ SWIG_AsVal_dec(ptrdiff_t)(SWIG_Object obj, ptrdiff_t *val)
} }
} }
%fragment("SWIG_CanCastAsInteger","header",
fragment=SWIG_AsVal_frag(double),
fragment="<float.h>",
fragment="<math.h>") {
SWIGINTERNINLINE int
SWIG_CanCastAsInteger(double *d, double min, double max) {
double x = *d;
if (min <= x && x <= max) {
%#ifndef SWIG_HAS_NO_RINT
/* Use the python mechanism to round, or so */
double rd = (x < 0) ? ceil(x) : floor(x);
%#else
double rd = rint(x);
%#endif
if ((errno == EDOM) || (errno == ERANGE)) {
errno = 0;
} else {
if (rd == x) {
return 1;
} else {
double diff = rd - x;
double summ = rd + x;
double reps = diff/summ;
if (fabs(reps) < 8*DBL_EPSILON) {
*d = rd;
return 1;
}
}
}
}
return 0;
}
}
/* ------------------------------------------------------------ /* ------------------------------------------------------------
* Generate the typemaps for primitive type * Generate the typemaps for primitive type
* ------------------------------------------------------------ */ * ------------------------------------------------------------ */

View file

@ -161,8 +161,8 @@
%define %value_typecheck_typemap(check,asval_meth,frag,Type...) %define %value_typecheck_typemap(check,asval_meth,frag,Type...)
%typemap(typecheck,noblock=1,precedence=check,fragment=frag) Type, const Type& { %typemap(typecheck,noblock=1,precedence=check,fragment=frag) Type, const Type& {
int res = asval_meth($input, NULL); int res = SWIG_CastRank(asval_meth($input, NULL));
$1 = SWIG_GetCastRank(res); $1 = SWIG_IsOK(res) ? res : 0;
} }
%enddef %enddef

View file

@ -372,7 +372,7 @@ Swig_overload_dispatch_cast(Node *n, const String_or_char *fmt, int *maxargs) {
String *sw = NewString(""); String *sw = NewString("");
Printf(f,"{\n"); Printf(f,"{\n");
Printf(f,"unsigned long _index = 0;\n"); Printf(f,"unsigned long _index = 0;\n");
Printf(f,"double _rank = 0; \n"); Printf(f,"SWIG_TypeRank _rank = 0; \n");
/* Get a list of methods ranked by precedence values and argument count */ /* Get a list of methods ranked by precedence values and argument count */
List *dispatch = Swig_overload_rank(n, true); List *dispatch = Swig_overload_rank(n, true);
@ -401,8 +401,8 @@ Swig_overload_dispatch_cast(Node *n, const String_or_char *fmt, int *maxargs) {
} else { } else {
Printf(f,"if (%s >= %d) {\n", argc_template_string, num_required); Printf(f,"if (%s >= %d) {\n", argc_template_string, num_required);
} }
Printf(f,"double _ranki = 0;\n"); Printf(f,"SWIG_TypeRank _ranki = 0;\n");
Printf(f,"double _pi = 1;\n",num_arguments); Printf(f,"SWIG_TypeRank _pi = 1;\n",num_arguments);
/* create a list with the wrappers that collide with the /* create a list with the wrappers that collide with the
current one based on argument number */ current one based on argument number */
@ -471,7 +471,7 @@ Swig_overload_dispatch_cast(Node *n, const String_or_char *fmt, int *maxargs) {
if (emitcheck) { if (emitcheck) {
if (need_v) { if (need_v) {
Printf(f,"int _v;\n"); Printf(f,"int _v = 0;\n");
need_v = 0; need_v = 0;
} }
if (j >= num_required) { if (j >= num_required) {
@ -631,7 +631,7 @@ Swig_overload_dispatch_fast(Node *n, const String_or_char *fmt, int *maxargs) {
if (emitcheck) { if (emitcheck) {
if (need_v) { if (need_v) {
Printf(f,"int _v = 1;\n"); Printf(f,"int _v = 0;\n");
need_v = 0; need_v = 0;
} }
if (j >= num_required) { if (j >= num_required) {

View file

@ -69,6 +69,7 @@ static int proxydel = 1;
static int fastunpack = 0; static int fastunpack = 0;
static int modernargs = 0; static int modernargs = 0;
static int aliasobj0 = 0; static int aliasobj0 = 0;
static int castmode = 0;
/* flags for the make_autodoc function */ /* flags for the make_autodoc function */
enum autodoc_t { enum autodoc_t {
@ -114,6 +115,8 @@ Python Options (available with -python)\n\
-nofastunpack - Use traditional UnpackTuple method to parse the argument functions (default) \n\ -nofastunpack - Use traditional UnpackTuple method to parse the argument functions (default) \n\
-aliasobj0 - Alias obj0 when using fastunpack, needed for some old typemaps \n\ -aliasobj0 - Alias obj0 when using fastunpack, needed for some old typemaps \n\
-noaliasobj0 - Don't generate an obj0 alias when using fastunpack (default) \n\ -noaliasobj0 - Don't generate an obj0 alias when using fastunpack (default) \n\
-castmode - Enable the casting mode, which allows implicit cast between types\n\
-nocastmode - Disable the casting mode (default)\n\
-O - Enable all the optimizations options: \n\ -O - Enable all the optimizations options: \n\
-modern -fastdispatch -dirvtable -nosafecstrings -fvirtual -noproxydel -fastunpack -modernargs\n\ -modern -fastdispatch -dirvtable -nosafecstrings -fvirtual -noproxydel -fastunpack -modernargs\n\
\n"; \n";
@ -294,6 +297,12 @@ public:
} else if (strcmp(argv[i],"-nofastunpack") == 0) { } else if (strcmp(argv[i],"-nofastunpack") == 0) {
fastunpack = 0; fastunpack = 0;
Swig_mark_arg(i); Swig_mark_arg(i);
} else if (strcmp(argv[i],"-castmode") == 0) {
castmode = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i],"-nocastmode") == 0) {
castmode = 0;
Swig_mark_arg(i);
} else if (strcmp(argv[i],"-modernargs") == 0) { } else if (strcmp(argv[i],"-modernargs") == 0) {
modernargs = 1; modernargs = 1;
Swig_mark_arg(i); Swig_mark_arg(i);
@ -394,6 +403,12 @@ public:
if (Getattr(options, "threads")) { if (Getattr(options, "threads")) {
threads = 1; threads = 1;
} }
if (Getattr(options, "castmode")) {
castmode = 1;
}
if (Getattr(options, "nocastmode")) {
castmode = 0;
}
mod_docstring = Getattr(options, "docstring"); mod_docstring = Getattr(options, "docstring");
package = Getattr(options, "package"); package = Getattr(options, "package");
} }
@ -464,6 +479,10 @@ public:
Printf(f_runtime,"#define SWIG_PYTHON_DIRECTOR_NO_VTABLE\n"); Printf(f_runtime,"#define SWIG_PYTHON_DIRECTOR_NO_VTABLE\n");
} }
if (castmode) {
Printf(f_runtime,"#define SWIG_PYTHON_CAST_MODE\n");
}
/* Set module name */ /* Set module name */
module = Copy(Getattr(n,"name")); module = Copy(Getattr(n,"name"));
@ -1301,11 +1320,14 @@ public:
int allow_thread = threads_enable(n); int allow_thread = threads_enable(n);
String *tmp = NewString(""); String *tmp = NewString("");
String *dispatch;
String *dispatch = funpack ? const char *dispatch_code = funpack ? "return %s(self, argv);" : "return %s(self, args);";
Swig_overload_dispatch(n,"return %s(self, argv);",&maxargs)
: Swig_overload_dispatch(n,"return %s(self, args);",&maxargs); if (castmode) {
dispatch = Swig_overload_dispatch_cast(n,dispatch_code,&maxargs);
} else {
dispatch = Swig_overload_dispatch(n,dispatch_code,&maxargs);
}
/* Generate a dispatch wrapper for all overloaded functions */ /* Generate a dispatch wrapper for all overloaded functions */