changeset 31469:fb77a0b4a00a

move declaration and definition of legacy Range class to ov-legacy-range.cc * ov-legacy-range.cc: Move complete definition of legacy Range class here from Range.h and Range.cc so that it is completely hidden from users. Delete obsolete Range constructors. Remove OCTAVE_API tags from all Range functions. Delete directives to ignore deprecated declarations.
author John W. Eaton <jwe@octave.org>
date Thu, 17 Nov 2022 13:53:47 -0500
parents 777a42ebe45b
children da260fea6953
files libinterp/octave-value/ov-legacy-range.cc liboctave/array/Range.cc liboctave/array/Range.h
diffstat 3 files changed, 301 insertions(+), 338 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/octave-value/ov-legacy-range.cc	Thu Nov 17 13:48:20 2022 -0500
+++ b/libinterp/octave-value/ov-legacy-range.cc	Thu Nov 17 13:53:47 2022 -0500
@@ -50,10 +50,307 @@
 #include "ls-hdf5.h"
 #include "ls-utils.h"
 
-#if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC)
-#  pragma GCC diagnostic push
-#  pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
+class
+Range
+{
+public:
+
+  Range (void)
+    : m_base (0), m_limit (0), m_inc (0), m_numel (0)
+  { }
+
+  // Assume range is already properly constructed, so just copy internal
+  // values.  However, we set LIMIT to the computed final value because
+  // that mimics the behavior of the other Range class constructors that
+  // reset limit to the computed final value.
+
+  Range (const octave::range<double>& r)
+    : m_base (r.base ()), m_limit (r.final_value ()), m_inc (r.increment ()),
+      m_numel (r.numel ())
+  { }
+
+  Range (const Range& r) = default;
+
+  Range& operator = (const Range& r) = default;
+
+  ~Range (void) = default;
+
+  Range (double b, double l)
+    : m_base (b), m_limit (l), m_inc (1), m_numel (numel_internal ())
+  {
+    if (! octave::math::isinf (m_limit))
+      m_limit = limit_internal ();
+  }
+
+  Range (double b, double l, double i)
+    : m_base (b), m_limit (l), m_inc (i), m_numel (numel_internal ())
+  {
+    if (! octave::math::isinf (m_limit))
+      m_limit = limit_internal ();
+  }
+
+  // The range has a finite number of elements.
+  bool ok (void) const
+  {
+    return (octave::math::isfinite (m_limit)
+            && (m_numel >= 0 || m_numel == -2));
+  }
+
+  double base (void) const { return m_base; }
+  double limit (void) const { return m_limit; }
+  double increment (void) const { return m_inc; }
+
+  octave_idx_type numel (void) const { return m_numel; }
+
+  bool all_elements_are_ints (void) const;
+
+  Matrix matrix_value (void) const;
+
+  double min (void) const;
+  double max (void) const;
+
+private:
+
+  double m_base;
+  double m_limit;
+  double m_inc;
+
+  octave_idx_type m_numel;
+
+  octave_idx_type numel_internal (void) const;
+
+  double limit_internal (void) const;
+
+  void init (void);
+};
+
+bool
+Range::all_elements_are_ints (void) const
+{
+  // If the base and increment are ints, the final value in the range will also
+  // be an integer, even if the limit is not.  If there is one or fewer
+  // elements only the base needs to be an integer.
+
+  return (! (octave::math::isnan (m_base) || octave::math::isnan (m_inc))
+          && (octave::math::nint_big (m_base) == m_base || m_numel < 1)
+          && (octave::math::nint_big (m_inc) == m_inc || m_numel <= 1));
+}
+
+Matrix
+Range::matrix_value (void) const
+{
+  Matrix retval (1, m_numel);
+
+  if (m_numel > 0)
+    {
+      // The first element must always be *exactly* the base.
+      // E.g, -0 would otherwise become +0 in the loop (-0 + 0*increment).
+      retval(0) = m_base;
+
+      double b = m_base;
+      double increment = m_inc;
+      for (octave_idx_type i = 1; i < m_numel - 1; i++)
+        retval.xelem (i) = b + i * increment;
+
+      retval.xelem (m_numel - 1) = m_limit;
+    }
+
+  return retval;
+}
+
+// NOTE: max and min only return useful values if numel > 0.
+//       do_minmax_body() in max.cc avoids calling Range::min/max if numel == 0.
+
+double
+Range::min (void) const
+{
+  double retval = 0.0;
+  if (m_numel > 0)
+    {
+      if (m_inc > 0)
+        retval = m_base;
+      else
+        {
+          retval = m_base + (m_numel - 1) * m_inc;
+
+          // Require '<=' test.  See note in max ().
+          if (retval <= m_limit)
+            retval = m_limit;
+        }
+
+    }
+  return retval;
+}
+
+double
+Range::max (void) const
+{
+  double retval = 0.0;
+  if (m_numel > 0)
+    {
+      if (m_inc > 0)
+        {
+          retval = m_base + (m_numel - 1) * m_inc;
+
+          // On some machines (x86 with extended precision floating point
+          // arithmetic, for example) it is possible that we can overshoot the
+          // limit by approximately the machine precision even though we were
+          // very careful in our calculation of the number of elements.
+          // Therefore, we clip the result to the limit if it overshoots.
+          // The test also includes equality (>= m_limit) to have expressions
+          // such as -5:1:-0 result in a -0 endpoint.
+          if (retval >= m_limit)
+            retval = m_limit;
+        }
+      else
+        retval = m_base;
+    }
+  return retval;
+}
+
+// C  See Knuth, Art Of Computer Programming, Vol. 1, Problem 1.2.4-5.
+// C
+// C===Tolerant FLOOR function.
+// C
+// C    X  -  is given as a Double Precision argument to be operated on.
+// C          It is assumed that X is represented with M mantissa bits.
+// C    CT -  is   given   as   a   Comparison   Tolerance   such   that
+// C          0.LT.CT.LE.3-SQRT(5)/2. If the relative difference between
+// C          X and A whole number is  less  than  CT,  then  TFLOOR  is
+// C          returned   as   this   whole   number.   By  treating  the
+// C          floating-point numbers as a finite ordered set  note  that
+// C          the  heuristic  EPS=2.**(-(M-1))   and   CT=3*EPS   causes
+// C          arguments  of  TFLOOR/TCEIL to be treated as whole numbers
+// C          if they are  exactly  whole  numbers  or  are  immediately
+// C          adjacent to whole number representations.  Since EPS,  the
+// C          "distance"  between  floating-point  numbers  on  the unit
+// C          interval, and M, the number of bits in X'S mantissa, exist
+// C          on  every  floating-point   computer,   TFLOOR/TCEIL   are
+// C          consistently definable on every floating-point computer.
+// C
+// C          For more information see the following references:
+// C    (1) P. E. Hagerty, "More On Fuzzy Floor And Ceiling," APL  QUOTE
+// C        QUAD 8(4):20-24, June 1978. Note that TFLOOR=FL5.
+// C    (2) L. M. Breed, "Definitions For Fuzzy Floor And Ceiling",  APL
+// C        QUOTE QUAD 8(3):16-23, March 1978. This paper cites FL1 through
+// C        FL5, the history of five years of evolutionary development of
+// C        FL5 - the seven lines of code below - by open collaboration
+// C        and corroboration of the mathematical-computing community.
+// C
+// C  Penn State University Center for Academic Computing
+// C  H. D. Knoble - August, 1978.
+
+static inline double
+tfloor (double x, double ct)
+{
+// C---------FLOOR(X) is the largest integer algebraically less than
+// C         or equal to X; that is, the unfuzzy FLOOR function.
+
+//  DINT (X) = X - DMOD (X, 1.0);
+//  FLOOR (X) = DINT (X) - DMOD (2.0 + DSIGN (1.0, X), 3.0);
+
+// C---------Hagerty's FL5 function follows...
+
+  double q = 1.0;
+
+  if (x < 0.0)
+    q = 1.0 - ct;
+
+  double rmax = q / (2.0 - ct);
+
+  double t1 = 1.0 + std::floor (x);
+  t1 = (ct / q) * (t1 < 0.0 ? -t1 : t1);
+  t1 = (rmax < t1 ? rmax : t1);
+  t1 = (ct > t1 ? ct : t1);
+  t1 = std::floor (x + t1);
+
+  if (x <= 0.0 || (t1 - x) < rmax)
+    return t1;
+  else
+    return t1 - 1.0;
+}
+
+static inline bool
+teq (double u, double v,
+     double ct = 3.0 * std::numeric_limits<double>::epsilon ())
+{
+  double tu = std::abs (u);
+  double tv = std::abs (v);
+
+  return std::abs (u - v) < ((tu > tv ? tu : tv) * ct);
+}
+
+octave_idx_type
+Range::numel_internal (void) const
+{
+  octave_idx_type retval = -1;
+
+  if (! octave::math::isfinite (m_base) || ! octave::math::isfinite (m_inc)
+      || octave::math::isnan (m_limit))
+    retval = -2;
+  else if (octave::math::isinf (m_limit)
+           && ((m_inc > 0 && m_limit > 0)
+               || (m_inc < 0 && m_limit < 0)))
+    retval = std::numeric_limits<octave_idx_type>::max () - 1;
+  else if (m_inc == 0
+           || (m_limit > m_base && m_inc < 0)
+           || (m_limit < m_base && m_inc > 0))
+    {
+      retval = 0;
+    }
+  else
+    {
+      double ct = 3.0 * std::numeric_limits<double>::epsilon ();
+
+      double tmp = tfloor ((m_limit - m_base + m_inc) / m_inc, ct);
+
+      octave_idx_type n_elt = (tmp > 0.0
+                               ? static_cast<octave_idx_type> (tmp) : 0);
+
+      // If the final element that we would compute for the range is equal to
+      // the limit of the range, or is an adjacent floating point number,
+      // accept it.  Otherwise, try a range with one fewer element.  If that
+      // fails, try again with one more element.
+      //
+      // I'm not sure this is very good, but it seems to work better than just
+      // using tfloor as above.  For example, without it, the expression
+      // 1.8:0.05:1.9 fails to produce the expected result of [1.8, 1.85, 1.9].
+
+      if (! teq (m_base + (n_elt - 1) * m_inc, m_limit))
+        {
+          if (teq (m_base + (n_elt - 2) * m_inc, m_limit))
+            n_elt--;
+          else if (teq (m_base + n_elt * m_inc, m_limit))
+            n_elt++;
+        }
+
+      retval = ((n_elt < std::numeric_limits<octave_idx_type>::max ())
+                ? n_elt : -1);
+    }
+
+  return retval;
+}
+
+double
+Range::limit_internal (void) const
+{
+  double new_limit = m_inc > 0 ? max () : min ();
+
+  // If result must be an integer then force the new_limit to be one.
+  if (all_elements_are_ints ())
+    new_limit = std::round (new_limit);
+
+  return new_limit;
+}
+
+void
+Range::init (void)
+{
+  m_numel = numel_internal ();
+
+  if (! octave::math::isinf (m_limit))
+    m_limit = limit_internal ();
+}
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_legacy_range, "range", "double");
 
@@ -276,7 +573,3 @@
 
   return retval;
 }
-
-#if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC)
-#  pragma GCC diagnostic pop
-#endif
--- a/liboctave/array/Range.cc	Thu Nov 17 13:48:20 2022 -0500
+++ b/liboctave/array/Range.cc	Thu Nov 17 13:53:47 2022 -0500
@@ -452,231 +452,3 @@
     return xnnz (m_base, m_limit, m_increment, m_final, m_numel);
   }
 }
-
-bool
-Range::all_elements_are_ints (void) const
-{
-  // If the base and increment are ints, the final value in the range will also
-  // be an integer, even if the limit is not.  If there is one or fewer
-  // elements only the base needs to be an integer.
-
-  return (! (octave::math::isnan (m_base) || octave::math::isnan (m_inc))
-          && (octave::math::nint_big (m_base) == m_base || m_numel < 1)
-          && (octave::math::nint_big (m_inc) == m_inc || m_numel <= 1));
-}
-
-Matrix
-Range::matrix_value (void) const
-{
-  Matrix retval (1, m_numel);
-
-  if (m_numel > 0)
-    {
-      // The first element must always be *exactly* the base.
-      // E.g, -0 would otherwise become +0 in the loop (-0 + 0*increment).
-      retval(0) = m_base;
-
-      double b = m_base;
-      double increment = m_inc;
-      for (octave_idx_type i = 1; i < m_numel - 1; i++)
-        retval.xelem (i) = b + i * increment;
-
-      retval.xelem (m_numel - 1) = m_limit;
-    }
-
-  return retval;
-}
-
-// NOTE: max and min only return useful values if numel > 0.
-//       do_minmax_body() in max.cc avoids calling Range::min/max if numel == 0.
-
-double
-Range::min (void) const
-{
-  double retval = 0.0;
-  if (m_numel > 0)
-    {
-      if (m_inc > 0)
-        retval = m_base;
-      else
-        {
-          retval = m_base + (m_numel - 1) * m_inc;
-
-          // Require '<=' test.  See note in max ().
-          if (retval <= m_limit)
-            retval = m_limit;
-        }
-
-    }
-  return retval;
-}
-
-double
-Range::max (void) const
-{
-  double retval = 0.0;
-  if (m_numel > 0)
-    {
-      if (m_inc > 0)
-        {
-          retval = m_base + (m_numel - 1) * m_inc;
-
-          // On some machines (x86 with extended precision floating point
-          // arithmetic, for example) it is possible that we can overshoot the
-          // limit by approximately the machine precision even though we were
-          // very careful in our calculation of the number of elements.
-          // Therefore, we clip the result to the limit if it overshoots.
-          // The test also includes equality (>= m_limit) to have expressions
-          // such as -5:1:-0 result in a -0 endpoint.
-          if (retval >= m_limit)
-            retval = m_limit;
-        }
-      else
-        retval = m_base;
-    }
-  return retval;
-}
-
-// C  See Knuth, Art Of Computer Programming, Vol. 1, Problem 1.2.4-5.
-// C
-// C===Tolerant FLOOR function.
-// C
-// C    X  -  is given as a Double Precision argument to be operated on.
-// C          It is assumed that X is represented with M mantissa bits.
-// C    CT -  is   given   as   a   Comparison   Tolerance   such   that
-// C          0.LT.CT.LE.3-SQRT(5)/2. If the relative difference between
-// C          X and A whole number is  less  than  CT,  then  TFLOOR  is
-// C          returned   as   this   whole   number.   By  treating  the
-// C          floating-point numbers as a finite ordered set  note  that
-// C          the  heuristic  EPS=2.**(-(M-1))   and   CT=3*EPS   causes
-// C          arguments  of  TFLOOR/TCEIL to be treated as whole numbers
-// C          if they are  exactly  whole  numbers  or  are  immediately
-// C          adjacent to whole number representations.  Since EPS,  the
-// C          "distance"  between  floating-point  numbers  on  the unit
-// C          interval, and M, the number of bits in X'S mantissa, exist
-// C          on  every  floating-point   computer,   TFLOOR/TCEIL   are
-// C          consistently definable on every floating-point computer.
-// C
-// C          For more information see the following references:
-// C    (1) P. E. Hagerty, "More On Fuzzy Floor And Ceiling," APL  QUOTE
-// C        QUAD 8(4):20-24, June 1978. Note that TFLOOR=FL5.
-// C    (2) L. M. Breed, "Definitions For Fuzzy Floor And Ceiling",  APL
-// C        QUOTE QUAD 8(3):16-23, March 1978. This paper cites FL1 through
-// C        FL5, the history of five years of evolutionary development of
-// C        FL5 - the seven lines of code below - by open collaboration
-// C        and corroboration of the mathematical-computing community.
-// C
-// C  Penn State University Center for Academic Computing
-// C  H. D. Knoble - August, 1978.
-
-static inline double
-tfloor (double x, double ct)
-{
-// C---------FLOOR(X) is the largest integer algebraically less than
-// C         or equal to X; that is, the unfuzzy FLOOR function.
-
-//  DINT (X) = X - DMOD (X, 1.0);
-//  FLOOR (X) = DINT (X) - DMOD (2.0 + DSIGN (1.0, X), 3.0);
-
-// C---------Hagerty's FL5 function follows...
-
-  double q = 1.0;
-
-  if (x < 0.0)
-    q = 1.0 - ct;
-
-  double rmax = q / (2.0 - ct);
-
-  double t1 = 1.0 + std::floor (x);
-  t1 = (ct / q) * (t1 < 0.0 ? -t1 : t1);
-  t1 = (rmax < t1 ? rmax : t1);
-  t1 = (ct > t1 ? ct : t1);
-  t1 = std::floor (x + t1);
-
-  if (x <= 0.0 || (t1 - x) < rmax)
-    return t1;
-  else
-    return t1 - 1.0;
-}
-
-static inline bool
-teq (double u, double v,
-     double ct = 3.0 * std::numeric_limits<double>::epsilon ())
-{
-  double tu = std::abs (u);
-  double tv = std::abs (v);
-
-  return std::abs (u - v) < ((tu > tv ? tu : tv) * ct);
-}
-
-octave_idx_type
-Range::numel_internal (void) const
-{
-  octave_idx_type retval = -1;
-
-  if (! octave::math::isfinite (m_base) || ! octave::math::isfinite (m_inc)
-      || octave::math::isnan (m_limit))
-    retval = -2;
-  else if (octave::math::isinf (m_limit)
-           && ((m_inc > 0 && m_limit > 0)
-               || (m_inc < 0 && m_limit < 0)))
-    retval = std::numeric_limits<octave_idx_type>::max () - 1;
-  else if (m_inc == 0
-           || (m_limit > m_base && m_inc < 0)
-           || (m_limit < m_base && m_inc > 0))
-    {
-      retval = 0;
-    }
-  else
-    {
-      double ct = 3.0 * std::numeric_limits<double>::epsilon ();
-
-      double tmp = tfloor ((m_limit - m_base + m_inc) / m_inc, ct);
-
-      octave_idx_type n_elt = (tmp > 0.0
-                               ? static_cast<octave_idx_type> (tmp) : 0);
-
-      // If the final element that we would compute for the range is equal to
-      // the limit of the range, or is an adjacent floating point number,
-      // accept it.  Otherwise, try a range with one fewer element.  If that
-      // fails, try again with one more element.
-      //
-      // I'm not sure this is very good, but it seems to work better than just
-      // using tfloor as above.  For example, without it, the expression
-      // 1.8:0.05:1.9 fails to produce the expected result of [1.8, 1.85, 1.9].
-
-      if (! teq (m_base + (n_elt - 1) * m_inc, m_limit))
-        {
-          if (teq (m_base + (n_elt - 2) * m_inc, m_limit))
-            n_elt--;
-          else if (teq (m_base + n_elt * m_inc, m_limit))
-            n_elt++;
-        }
-
-      retval = ((n_elt < std::numeric_limits<octave_idx_type>::max ())
-                ? n_elt : -1);
-    }
-
-  return retval;
-}
-
-double
-Range::limit_internal (void) const
-{
-  double new_limit = m_inc > 0 ? max () : min ();
-
-  // If result must be an integer then force the new_limit to be one.
-  if (all_elements_are_ints ())
-    new_limit = std::round (new_limit);
-
-  return new_limit;
-}
-
-void
-Range::init (void)
-{
-  m_numel = numel_internal ();
-
-  if (! octave::math::isinf (m_limit))
-    m_limit = limit_internal ();
-}
--- a/liboctave/array/Range.h	Thu Nov 17 13:48:20 2022 -0500
+++ b/liboctave/array/Range.h	Thu Nov 17 13:53:47 2022 -0500
@@ -395,106 +395,4 @@
   template <> OCTAVE_API octave_idx_type range<float>::nnz (void) const;
 }
 
-class
-Range
-{
-public:
-
-  OCTAVE_DEPRECATED (7, "use the 'octave::range<double>' class instead")
-  Range (void)
-    : m_base (0), m_limit (0), m_inc (0), m_numel (0)
-  { }
-
-  // Assume range is already properly constructed, so just copy internal
-  // values.  However, we set LIMIT to the computed final value because
-  // that mimics the behavior of the other Range class constructors that
-  // reset limit to the computed final value.
-
-  OCTAVE_DEPRECATED (7, "use the 'octave::range<double>' class instead")
-  Range (const octave::range<double>& r)
-    : m_base (r.base ()), m_limit (r.final_value ()), m_inc (r.increment ()),
-      m_numel (r.numel ())
-  { }
-
-  Range (const Range& r) = default;
-
-  Range& operator = (const Range& r) = default;
-
-  ~Range (void) = default;
-
-  OCTAVE_DEPRECATED (7, "use the 'octave::range<double>' class instead")
-  Range (double b, double l)
-    : m_base (b), m_limit (l), m_inc (1), m_numel (numel_internal ())
-  {
-    if (! octave::math::isinf (m_limit))
-      m_limit = limit_internal ();
-  }
-
-  OCTAVE_DEPRECATED (7, "use the 'octave::range<double>' class instead")
-  Range (double b, double l, double i)
-    : m_base (b), m_limit (l), m_inc (i), m_numel (numel_internal ())
-  {
-    if (! octave::math::isinf (m_limit))
-      m_limit = limit_internal ();
-  }
-
-  // NOTE: The following constructor may be deprecated and removed after
-  // the arithmetic operators are removed.
-
-  // For operators' usage (to preserve element count) and to create
-  // constant row vectors (obsolete usage).
-
-  OCTAVE_DEPRECATED (7, "use the 'octave::range<double>' class instead")
-  Range (double b, double i, octave_idx_type n)
-    : m_base (b), m_limit (b + (n-1) * i), m_inc (i), m_numel (n)
-  {
-    if (! octave::math::isinf (m_limit))
-      m_limit = limit_internal ();
-  }
-
-  // The range has a finite number of elements.
-  bool ok (void) const
-  {
-    return (octave::math::isfinite (m_limit)
-            && (m_numel >= 0 || m_numel == -2));
-  }
-
-  double base (void) const { return m_base; }
-  double limit (void) const { return m_limit; }
-  double increment (void) const { return m_inc; }
-
-  octave_idx_type numel (void) const { return m_numel; }
-
-  OCTAVE_API bool all_elements_are_ints (void) const;
-
-  OCTAVE_API Matrix matrix_value (void) const;
-
-  OCTAVE_API double min (void) const;
-  OCTAVE_API double max (void) const;
-
-private:
-
-  double m_base;
-  double m_limit;
-  double m_inc;
-
-  octave_idx_type m_numel;
-
-  OCTAVE_API octave_idx_type numel_internal (void) const;
-
-  OCTAVE_API double limit_internal (void) const;
-
-  OCTAVE_API void init (void);
-
-protected:
-
-  // NOTE: The following constructor may be removed when the arithmetic
-  // operators are removed.
-
-  // For operators' usage (to allow all values to be set directly).
-  Range (double b, double l, double i, octave_idx_type n)
-    : m_base (b), m_limit (l), m_inc (i), m_numel (n)
-  { }
-};
-
 #endif