changeset 11211:2554b4a0806e

use templates for some lo-mappers functions
author John W. Eaton <jwe@octave.org>
date Tue, 09 Nov 2010 03:24:18 -0500
parents b79924abf776
children ce27d6f4e134
files liboctave/ChangeLog liboctave/lo-mappers.cc liboctave/lo-mappers.h liboctave/lo-utils.cc liboctave/lo-utils.h
diffstat 5 files changed, 182 insertions(+), 258 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/ChangeLog	Tue Nov 09 01:28:45 2010 -0500
+++ b/liboctave/ChangeLog	Tue Nov 09 03:24:18 2010 -0500
@@ -1,3 +1,16 @@
+2010-11-09  John W. Eaton  <jwe@octave.org>
+
+	* lo-mappers.cc, lo-mappers.h (xmod, xrem): Move definitions
+	from lo-mappers.cc to lo-mappers.h and convert to templates.
+	(xtrunc): Move definitions from lo-mappers.cc to lo-mappers.h.
+	* lo-mappers.cc (fix): Use xtrunc.
+	* lo-mappers.h (xfloor): New functions.
+	(X_NINT): New template function.
+	(D_NINT, F_NINT): Define in terms of X_NINT.
+	* lo-utils.h, lo-utils.cc (D_NINT, F_NINT): Delete.
+	* lo-mappers.h, lo-mappers.cc (NINTbig,	NINT): Move from
+	lo-utils.cc and lo-utils.h.
+
 2010-11-09  John W. Eaton  <jwe@octave.org>
 
 	* Array.cc (Array<T>::sort, Array<T>::is_sorted,
--- a/liboctave/lo-mappers.cc	Tue Nov 09 01:28:45 2010 -0500
+++ b/liboctave/lo-mappers.cc	Tue Nov 09 03:24:18 2010 -0500
@@ -55,7 +55,7 @@
 double
 fix (double x)
 {
-  return gnulib::trunc (x);
+  return xtrunc (x);
 }
 
 double
@@ -76,12 +76,6 @@
   return gnulib::round (x);
 }
 
-double
-xtrunc (double x)
-{
-  return gnulib::trunc (x);
-}
-
 double 
 xroundb (double x)
 {
@@ -107,88 +101,6 @@
 }
 
 double
-xmod (double x, double y)
-{
-  double retval;
-
-  if (y == 0)
-    retval = x;
-  else
-    {
-      double q = x / y;
-
-      double n = floor (q);
-
-      if (D_NINT (y) != y)
-        {
-          if (D_NINT (q) == q)
-            n = q;
-          else
-            {
-              if (x >= -1 && x <= 1)
-                {
-                  if (std::abs (q - D_NINT (q)) < DBL_EPSILON)
-                    n = D_NINT (q);
-                }
-              else
-                {
-                  if (std::abs ((q - D_NINT (q))/ D_NINT (q)) < DBL_EPSILON)
-                    n = D_NINT (q);
-                }
-            }
-        }
-
-      retval = x - y * n;
-    }
-
-  if (x != y && y != 0)
-    retval = copysignf (retval, y);
-
-  return retval;
-}
-
-double
-xrem (double x, double y)
-{
-  double retval;
-
-  if (y == 0)
-    retval = x;
-  else
-    {
-      double q = x / y;
-
-      double n = trunc (q);
-
-      if (D_NINT (y) != y)
-        {
-          if (D_NINT (q) == q)
-            n = q;
-          else
-            {
-              if (x >= -1 && x <= 1)
-                {
-                  if (std::abs (q - D_NINT (q)) < DBL_EPSILON)
-                    n = D_NINT (q);
-                }
-              else
-                {
-                  if (std::abs ((q - D_NINT (q))/ D_NINT (q)) < DBL_EPSILON)
-                    n = D_NINT (q);
-                }
-            }
-        }
-
-      retval = x - y * n;
-    }
-
-  if (x != y && y != 0)
-    retval = copysignf (retval, x);
-
-  return retval;
-}
-
-double
 xlog2 (double x)
 {
 #if defined (HAVE_LOG2)
@@ -416,7 +328,7 @@
 float
 fix (float x)
 {
-  return gnulib::truncf (x);
+  return xtrunc (x);
 }
 
 float
@@ -437,12 +349,6 @@
   return gnulib::round (x);
 }
 
-float
-xtrunc (float x)
-{
-  return gnulib::truncf (x);
-}
-
 float 
 xroundb (float x)
 {
@@ -468,88 +374,6 @@
 }
 
 float
-xmod (float x, float y)
-{
-  float retval;
-
-  if (y == 0)
-    retval = x;
-  else
-    {
-      float q = x / y;
-
-      float n = floor (q);
-
-      if (F_NINT (y) != y)
-        {
-          if (F_NINT (q) == q)
-            n = q;
-          else
-            {
-              if (x >= -1 && x <= 1)
-                {
-                  if (std::abs (q - F_NINT (q)) < FLT_EPSILON)
-                    n = F_NINT (q);
-                }
-              else
-                {
-                  if (std::abs ((q - F_NINT (q))/ F_NINT (q)) < FLT_EPSILON)
-                    n = F_NINT (q);
-                }
-            }
-        }
-
-      retval = x - y * n;
-    }
-
-  if (x != y && y != 0)
-    retval = copysignf (retval, y);
-
-  return retval;
-}
-
-float
-xrem (float x, float y)
-{
-  float retval;
-
-  if (y == 0)
-    retval = x;
-  else
-    {
-      float q = x / y;
-
-      float n = truncf (q);
-
-      if (F_NINT (y) != y)
-        {
-          if (F_NINT (q) == q)
-            n = q;
-          else
-            {
-              if (x >= -1 && x <= 1)
-                {
-                  if (std::abs (q - F_NINT (q)) < FLT_EPSILON)
-                    n = F_NINT (q);
-                }
-              else
-                {
-                  if (std::abs ((q - F_NINT (q))/ F_NINT (q)) < FLT_EPSILON)
-                    n = F_NINT (q);
-                }
-            }
-        }
-
-      retval = x - y * n;
-    }
-
-  if (x != y && y != 0)
-    retval = copysignf (retval, x);
-
-  return retval;
-}
-
-float
 xlog2 (float x)
 {
 #if defined (HAVE_LOG2)
@@ -852,3 +676,52 @@
 
 bool xnegative_sign (float x)
 { return __lo_ieee_float_signbit (x); }
+
+// Convert X to the nearest integer value.  Should not pass NaN to
+// this function.
+
+// Sometimes you need a large integer, but not always.
+
+octave_idx_type
+NINTbig (double x)
+{
+  if (x > std::numeric_limits<octave_idx_type>::max ())
+    return std::numeric_limits<octave_idx_type>::max ();
+  else if (x < std::numeric_limits<octave_idx_type>::min ())
+    return std::numeric_limits<octave_idx_type>::min ();
+  else
+    return static_cast<octave_idx_type> ((x > 0) ? (x + 0.5) : (x - 0.5));
+}
+
+octave_idx_type
+NINTbig (float x)
+{
+  if (x > std::numeric_limits<octave_idx_type>::max ())
+    return std::numeric_limits<octave_idx_type>::max ();
+  else if (x < std::numeric_limits<octave_idx_type>::min ())
+    return std::numeric_limits<octave_idx_type>::min ();
+  else
+    return static_cast<octave_idx_type> ((x > 0) ? (x + 0.5) : (x - 0.5));
+}
+
+int
+NINT (double x)
+{
+  if (x > std::numeric_limits<int>::max ())
+    return std::numeric_limits<int>::max ();
+  else if (x < std::numeric_limits<int>::min ())
+    return std::numeric_limits<int>::min ();
+  else
+    return static_cast<int> ((x > 0) ? (x + 0.5) : (x - 0.5));
+}
+
+int
+NINT (float x)
+{
+  if (x > std::numeric_limits<int>::max ())
+    return std::numeric_limits<int>::max ();
+  else if (x < std::numeric_limits<int>::min ())
+    return std::numeric_limits<int>::min ();
+  else
+    return static_cast<int> ((x > 0) ? (x + 0.5) : (x - 0.5));
+}
--- a/liboctave/lo-mappers.h	Tue Nov 09 01:28:45 2010 -0500
+++ b/liboctave/lo-mappers.h	Tue Nov 09 03:24:18 2010 -0500
@@ -25,10 +25,16 @@
 #if !defined (octave_liboctave_mappers_h)
 #define octave_liboctave_mappers_h 1
 
+#include <limits>
+
 #include "oct-cmplx.h"
 #include "lo-math.h"
 
 // Double Precision 
+inline double xtrunc (double x) { return gnulib::trunc (x); }
+inline double xcopysign (double x, double y) { return copysignf (x, y); }
+inline double xfloor (double x) { return floor (x); }
+
 extern OCTAVE_API double arg (double x);
 extern OCTAVE_API double conj (double x);
 extern OCTAVE_API double fix (double x);
@@ -37,9 +43,6 @@
 extern OCTAVE_API double xround (double x);
 extern OCTAVE_API double xroundb (double x);
 extern OCTAVE_API double signum (double x);
-extern OCTAVE_API double xtrunc (double x);
-extern OCTAVE_API double xmod (double x, double y);
-extern OCTAVE_API double xrem (double x, double y);
 extern OCTAVE_API double xlog2 (double x); 
 extern OCTAVE_API Complex xlog2 (const Complex& x); 
 extern OCTAVE_API double xlog2 (double x, int& exp);
@@ -119,6 +122,10 @@
 extern OCTAVE_API Complex xmax (const Complex& x, const Complex& y);
 
 // Single Precision 
+inline float xtrunc (float x) { return gnulib::truncf (x); }
+inline float xcopysign (float x, float y) { return copysignf (x, y); }
+inline float xfloor (float x) { return floorf (x); }
+
 extern OCTAVE_API float arg (float x);
 extern OCTAVE_API float conj (float x);
 extern OCTAVE_API float fix (float x);
@@ -127,9 +134,6 @@
 extern OCTAVE_API float xround (float x);
 extern OCTAVE_API float xroundb (float x);
 extern OCTAVE_API float signum (float x);
-extern OCTAVE_API float xtrunc (float x);
-extern OCTAVE_API float xmod (float x, float y);
-extern OCTAVE_API float xrem (float x, float y);
 extern OCTAVE_API float xlog2 (float x); 
 extern OCTAVE_API FloatComplex xlog2 (const FloatComplex& x); 
 extern OCTAVE_API float xlog2 (float x, int& exp);
@@ -224,5 +228,113 @@
 extern OCTAVE_API bool xnegative_sign (double x);
 extern OCTAVE_API bool xnegative_sign (float x);
 
+extern OCTAVE_API octave_idx_type NINTbig (double x);
+extern OCTAVE_API octave_idx_type NINTbig (float x);
+
+extern OCTAVE_API int NINT (double x);
+extern OCTAVE_API int NINT (float x);
+
+template <typename T>
+OCTAVE_API
+T
+X_NINT (T x)
+{
+  return (xisinf (x) || xisnan (x)) ? x : xfloor (x + 0.5);
+}
+
+inline OCTAVE_API double D_NINT (double x) { return X_NINT (x); }
+inline OCTAVE_API float F_NINT (float x) { return X_NINT (x); }
+
+// Template functions can have either float or double arguments.
+
+template <typename T>
+OCTAVE_API
+T
+xmod (T x, T y)
+{
+  T retval;
+
+  if (y == 0)
+    retval = x;
+  else
+    {
+      T q = x / y;
+
+      T n = floor (q);
+
+      if (X_NINT (y) != y)
+        {
+          if (X_NINT (q) == q)
+            n = q;
+          else
+            {
+              if (x >= -1 && x <= 1)
+                {
+                  if (std::abs (q - X_NINT (q))
+                      < std::numeric_limits<T>::epsilon ())
+                    n = X_NINT (q);
+                }
+              else
+                {
+                  if (std::abs ((q - X_NINT (q))/ X_NINT (q))
+                      < std::numeric_limits<T>::epsilon ())
+                    n = D_NINT (q);
+                }
+            }
+        }
+
+      retval = x - y * n;
+    }
+
+  if (x != y && y != 0)
+    retval = xcopysign (retval, y);
+
+  return retval;
+}
+
+template <typename T>
+OCTAVE_API
+T
+xrem (T x, T y)
+{
+  T retval;
+
+  if (y == 0)
+    retval = x;
+  else
+    {
+      T q = x / y;
+
+      T n = xtrunc (q);
+
+      if (X_NINT (y) != y)
+        {
+          if (X_NINT (q) == q)
+            n = q;
+          else
+            {
+              if (x >= -1 && x <= 1)
+                {
+                  if (std::abs (q - X_NINT (q))
+                      < std::numeric_limits<T>::epsilon ())
+                    n = X_NINT (q);
+                }
+              else
+                {
+                  if (std::abs ((q - X_NINT (q))/ X_NINT (q))
+                      < std::numeric_limits<T>::epsilon ())
+                    n = X_NINT (q);
+                }
+            }
+        }
+
+      retval = x - y * n;
+    }
+
+  if (x != y && y != 0)
+    retval = xcopysign (retval, x);
+
+  return retval;
+}
 
 #endif
--- a/liboctave/lo-utils.cc	Tue Nov 09 01:28:45 2010 -0500
+++ b/liboctave/lo-utils.cc	Tue Nov 09 03:24:18 2010 -0500
@@ -45,73 +45,6 @@
 #include "lo-mappers.h"
 #include "lo-utils.h"
 
-// Convert X to the nearest integer value.  Should not pass NaN to
-// this function.
-
-// Sometimes you need a large integer, but not always.
-
-octave_idx_type
-NINTbig (double x)
-{
-  if (x > std::numeric_limits<octave_idx_type>::max ())
-    return std::numeric_limits<octave_idx_type>::max ();
-  else if (x < std::numeric_limits<octave_idx_type>::min ())
-    return std::numeric_limits<octave_idx_type>::min ();
-  else
-    return static_cast<octave_idx_type> ((x > 0) ? (x + 0.5) : (x - 0.5));
-}
-
-octave_idx_type
-NINTbig (float x)
-{
-  if (x > std::numeric_limits<octave_idx_type>::max ())
-    return std::numeric_limits<octave_idx_type>::max ();
-  else if (x < std::numeric_limits<octave_idx_type>::min ())
-    return std::numeric_limits<octave_idx_type>::min ();
-  else
-    return static_cast<octave_idx_type> ((x > 0) ? (x + 0.5) : (x - 0.5));
-}
-
-int
-NINT (double x)
-{
-  if (x > std::numeric_limits<int>::max ())
-    return std::numeric_limits<int>::max ();
-  else if (x < std::numeric_limits<int>::min ())
-    return std::numeric_limits<int>::min ();
-  else
-    return static_cast<int> ((x > 0) ? (x + 0.5) : (x - 0.5));
-}
-
-int
-NINT (float x)
-{
-  if (x > std::numeric_limits<int>::max ())
-    return std::numeric_limits<int>::max ();
-  else if (x < std::numeric_limits<int>::min ())
-    return std::numeric_limits<int>::min ();
-  else
-    return static_cast<int> ((x > 0) ? (x + 0.5) : (x - 0.5));
-}
-
-double
-D_NINT (double x)
-{
-  if (xisinf (x) || xisnan (x))
-    return x;
-  else
-    return floor (x + 0.5);
-}
-
-float
-F_NINT (float x)
-{
-  if (xisinf (x) || xisnan (x))
-    return x;
-  else
-    return floor (x + 0.5);
-}
-
 bool xis_int_or_inf_or_nan (double x)
 { return xisnan (x) || D_NINT (x) == x; }
 
--- a/liboctave/lo-utils.h	Tue Nov 09 01:28:45 2010 -0500
+++ b/liboctave/lo-utils.h	Tue Nov 09 03:24:18 2010 -0500
@@ -32,13 +32,6 @@
 #include "oct-cmplx.h"
 #include "syswait.h"
 
-extern OCTAVE_API octave_idx_type NINTbig (double x);
-extern OCTAVE_API octave_idx_type NINTbig (float x);
-extern OCTAVE_API int NINT (double x);
-extern OCTAVE_API int NINT (float x);
-extern OCTAVE_API double D_NINT (double x);
-extern OCTAVE_API float F_NINT (float x);
-
 extern OCTAVE_API bool xis_int_or_inf_or_nan (double x);
 extern OCTAVE_API bool xis_one_or_zero (double x);
 extern OCTAVE_API bool xis_zero (double x);