diff --git a/CHANGES.current b/CHANGES.current index ffb805ccd..77d2df753 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,22 @@ See the RELEASENOTES file for a summary of changes in each release. Version 2.0.11 (in progress) ============================ +2013-09-12: wsfulton + [UTL] Infinity is now by default an acceptable value for type 'float'. This fix makes + the handling of type 'float' and 'double' the same. The implementation requires the + C99 isfinite() macro, or otherwise some platform dependent equivalents, to be available. + + Users requiring the old behaviour of not accepting infinity, can define a 'check' typemap + wherever a float is used, such as: + + %typemap(check,fragment="") float, const float & %{ + if ($1 < -FLT_MAX || $1 > FLT_MAX) { + SWIG_exception_fail(SWIG_TypeError, "Overflow in type float"); + } + %} + + *** POTENTIAL INCOMPATIBILITY *** + 2013-08-30: wsfulton [Lua] Pull Git patch #81: Include Lua error locus in SWIG error messages. This is standard information in Lua error messages, and makes it much diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 5d6a4730a..997f8e715 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -285,8 +285,9 @@ CPP_TEST_CASES += \ operbool \ ordering \ overload_copy \ - overload_method \ overload_extend \ + overload_method \ + overload_numeric \ overload_rename \ overload_return_type \ overload_simple \ diff --git a/Examples/test-suite/overload_numeric.i b/Examples/test-suite/overload_numeric.i new file mode 100644 index 000000000..44c3b811c --- /dev/null +++ b/Examples/test-suite/overload_numeric.i @@ -0,0 +1,51 @@ +%module overload_numeric + +// Tests overloading of integral and floating point types to verify the range checking required +// for dispatch to the correct overloaded method + +#ifdef SWIGLUA +// lua only has one numeric type, so most of the overloads shadow each other creating warnings +%warnfilter(SWIGWARN_LANG_OVERLOAD_SHADOW) Nums::over; +#endif + +%{ +#include +%} + +%inline %{ +#include +#include +struct Limits { + signed char schar_min() { return SCHAR_MIN; } + signed char schar_max() { return SCHAR_MAX; } + short shrt_min() { return SHRT_MIN; } + short shrt_max() { return SHRT_MAX; } + int int_min() { return INT_MIN; } + int int_max() { return INT_MAX; } + float flt_min() { return FLT_MIN; } + float flt_max() { return FLT_MAX; } + double dbl_max() { return DBL_MAX; } +}; + +struct Nums { + const char * over(signed char v) { + return "signed char"; + } + const char * over(short v) { + return "short"; + } + const char * over(int v) { + return "int"; + } + const char * over(float v) { + return "float"; + } + const char * over(double v) { + return "double"; + } + double doublebounce(double v) { + return v; + } +}; +%} + diff --git a/Examples/test-suite/python/overload_numeric_runme.py b/Examples/test-suite/python/overload_numeric_runme.py new file mode 100644 index 000000000..639fb5e5d --- /dev/null +++ b/Examples/test-suite/python/overload_numeric_runme.py @@ -0,0 +1,43 @@ + +from overload_numeric import * +import math + +nums = Nums() +limits = Limits() + +def check(got, expected): + if got != expected: + raise RuntimeError("got: " + got + " expected: " + expected) + +check(nums.over(0), "signed char") +check(nums.over(0.0), "float") + +check(nums.over(limits.schar_min()), "signed char") +check(nums.over(limits.schar_max()), "signed char") + +check(nums.over(limits.schar_min()-1), "short") +check(nums.over(limits.schar_max()+1), "short") +check(nums.over(limits.shrt_min()), "short") +check(nums.over(limits.shrt_max()), "short") + +check(nums.over(limits.shrt_min()-1), "int") +check(nums.over(limits.shrt_max()+1), "int") +check(nums.over(limits.int_min()), "int") +check(nums.over(limits.int_max()), "int") + +check(nums.over(limits.flt_min()), "float") +check(nums.over(limits.flt_max()), "float") + +check(nums.over(limits.flt_max()*10), "double") +check(nums.over(-limits.flt_max()*10), "double") +check(nums.over(limits.dbl_max()), "double") +check(nums.over(-limits.dbl_max()), "double") + +check(nums.over(float("inf")), "float") +check(nums.over(float("-inf")), "float") +check(nums.over(float("nan")), "float") + +# Just check if the following are accepted without exceptions being thrown +nums.doublebounce(float("inf")) +nums.doublebounce(float("-inf")) +nums.doublebounce(float("nan")) diff --git a/Lib/typemaps/fragments.swg b/Lib/typemaps/fragments.swg index 4dbc1f20d..8f887e34e 100644 --- a/Lib/typemaps/fragments.swg +++ b/Lib/typemaps/fragments.swg @@ -153,6 +153,29 @@ #include %} +%fragment("SWIG_isfinite","header",fragment=",") %{ +/* Getting isfinite working pre C99 across multiple platforms is non-trivial. Users can provide SWIG_isfinite on older platforms. */ +#ifndef SWIG_isfinite +# if defined(isfinite) +# define SWIG_isfinite(X) (isfinite(X)) +# elif defined(_MSC_VER) +# define SWIG_isfinite(X) (_finite(X)) +# elif defined(__sun) && defined(__SVR4) +# include +# define SWIG_isfinite(X) (finite(X)) +# endif +#endif +%} + +%fragment("SWIG_Float_Overflow_Check","header",fragment=",SWIG_isfinite") %{ +/* Accept infinite as a valid float value unless we are unable to check if a value is finite */ +#ifdef SWIG_isfinite +# define SWIG_Float_Overflow_Check(X) ((X < -FLT_MAX || X > FLT_MAX) && SWIG_isfinite(X)) +#else +# define SWIG_Float_Overflow_Check(X) ((X < -FLT_MAX || X > FLT_MAX)) +#endif +%} + /* ----------------------------------------------------------------------------- * special macros for fragments * ----------------------------------------------------------------------------- */ @@ -213,13 +236,20 @@ SWIG_AsVal_dec(Type)(SWIG_Object obj, Type *val) %enddef -/* Macro for 'double' derived types */ +/* Macro for floating point derived types (original macro) */ %define %numeric_double(Type, Frag, Min, Max) %numeric_type_from(Type, double) %numeric_signed_type_asval(Type, double, Frag , Min, Max) %enddef +/* Macro for floating point derived types */ + +%define %numeric_float(Type, Frag, OverflowCond) +%numeric_type_from(Type, double) +%numeric_type_asval(Type, double, Frag, OverflowCond) +%enddef + /* Macros for missing fragments */ diff --git a/Lib/typemaps/primtypes.swg b/Lib/typemaps/primtypes.swg index cc8a55e6e..45632c31f 100644 --- a/Lib/typemaps/primtypes.swg +++ b/Lib/typemaps/primtypes.swg @@ -139,7 +139,7 @@ SWIG_AsVal_dec(bool)(SWIG_Object obj, bool *val) /* float */ -%numeric_double(float, "", -FLT_MAX, FLT_MAX) +%numeric_float(float, "SWIG_Float_Overflow_Check", SWIG_Float_Overflow_Check(v)) /* long/unsigned long */