summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam S Fulton <wsf@fultondesigns.co.uk>2013-09-12 07:23:54 +0100
committerWilliam S Fulton <wsf@fultondesigns.co.uk>2013-09-12 07:28:12 +0100
commita91cd0bc5c1550bfa2c922c7434323c30ca1fb87 (patch)
treebe8be04be14fcebb642423ce927f006381be95cf
parentf47075ec991716733d7e3588aea5e58673c004ff (diff)
downloadswig-a91cd0bc5c1550bfa2c922c7434323c30ca1fb87.tar.gz
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.
-rw-r--r--CHANGES.current16
-rw-r--r--Examples/test-suite/common.mk3
-rw-r--r--Examples/test-suite/overload_numeric.i51
-rw-r--r--Examples/test-suite/python/overload_numeric_runme.py43
-rw-r--r--Lib/typemaps/fragments.swg32
-rw-r--r--Lib/typemaps/primtypes.swg2
6 files changed, 144 insertions, 3 deletions
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.h>") 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 <iostream>
+%}
+
+%inline %{
+#include <limits.h>
+#include <float.h>
+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 <stddef.h>
%}
+%fragment("SWIG_isfinite","header",fragment="<math.h>,<float.h>") %{
+/* 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 <ieeefp.h>
+# define SWIG_isfinite(X) (finite(X))
+# endif
+#endif
+%}
+
+%fragment("SWIG_Float_Overflow_Check","header",fragment="<float.h>,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, "<float.h>", -FLT_MAX, FLT_MAX)
+%numeric_float(float, "SWIG_Float_Overflow_Check", SWIG_Float_Overflow_Check(v))
/* long/unsigned long */