changeset 28639:7ebe185e3818

new octave_value constructors for integer and float ranges. * ov-range.h (octave::octave_range): New constructors that accept range<T> for T = float and integer types. (make_double_range): New template function. (octave_range::octave_range): Use it to convert range<T> arguments to range<double> for T = float and integer types. (octave_float_range, octave_double_range, octave_int8_range, octave_int16_range, octave_int32_range, octave_int64_range, octave_uint8_range, octave_uint16_range, octave_uint32_range, octave_uint64_range): New typedefs. * ov.h, ov.cc (octave_value::octave_value): New constructors that accept range<T> for T = float and integer types. (make_range): Return range<T> instead of range<double> for float, double, and integer types. * Range.h (range<T>::range): New constructor accepting base, increment, limit, final, and numel values.
author John W. Eaton <jwe@octave.org>
date Thu, 06 Aug 2020 23:57:40 -0400
parents 98192ec1621f
children 308cee7cf3ee
files libinterp/octave-value/ov-range.h libinterp/octave-value/ov.cc libinterp/octave-value/ov.h liboctave/array/Range.h
diffstat 4 files changed, 204 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/octave-value/ov-range.h	Thu Aug 06 16:28:30 2020 -0400
+++ b/libinterp/octave-value/ov-range.h	Thu Aug 06 23:57:40 2020 -0400
@@ -50,6 +50,17 @@
 
 // Range values.
 
+template <typename T>
+octave::range<double>
+make_double_range (const octave::range<T>& r)
+{
+  return octave::range<double> (static_cast<double> (r.base ()),
+                                static_cast<double> (r.increment ()),
+                                static_cast<double> (r.limit ()),
+                                static_cast<double> (r.final_value ()),
+                                r.numel ());
+}
+
 class
 octave_range : public octave_base_value
 {
@@ -58,6 +69,13 @@
   octave_range (void)
     : octave_base_value (), m_range (), m_idx_cache () { }
 
+  octave_range (const octave::range<float>& r)
+    : octave_base_value (), m_range (make_double_range (r)), m_idx_cache ()
+  {
+    if (numel () < 0 && numel () != -2)
+      error ("invalid range");
+  }
+
   octave_range (const octave::range<double>& r)
     : octave_base_value (), m_range (r), m_idx_cache ()
   {
@@ -65,6 +83,62 @@
       error ("invalid range");
   }
 
+  octave_range (const octave::range<octave_int8>& r)
+    : octave_base_value (), m_range (make_double_range (r)), m_idx_cache ()
+  {
+    if (numel () < 0 && numel () != -2)
+      error ("invalid range");
+  }
+
+  octave_range (const octave::range<octave_int16>& r)
+    : octave_base_value (), m_range (make_double_range (r)), m_idx_cache ()
+  {
+    if (numel () < 0 && numel () != -2)
+      error ("invalid range");
+  }
+
+  octave_range (const octave::range<octave_int32>& r)
+    : octave_base_value (), m_range (make_double_range (r)), m_idx_cache ()
+  {
+    if (numel () < 0 && numel () != -2)
+      error ("invalid range");
+  }
+
+  octave_range (const octave::range<octave_int64>& r)
+    : octave_base_value (), m_range (make_double_range (r)), m_idx_cache ()
+  {
+    if (numel () < 0 && numel () != -2)
+      error ("invalid range");
+  }
+
+  octave_range (const octave::range<octave_uint8>& r)
+    : octave_base_value (), m_range (make_double_range (r)), m_idx_cache ()
+  {
+    if (numel () < 0 && numel () != -2)
+      error ("invalid range");
+  }
+
+  octave_range (const octave::range<octave_uint16>& r)
+    : octave_base_value (), m_range (make_double_range (r)), m_idx_cache ()
+  {
+    if (numel () < 0 && numel () != -2)
+      error ("invalid range");
+  }
+
+  octave_range (const octave::range<octave_uint32>& r)
+    : octave_base_value (), m_range (make_double_range (r)), m_idx_cache ()
+  {
+    if (numel () < 0 && numel () != -2)
+      error ("invalid range");
+  }
+
+  octave_range (const octave::range<octave_uint64>& r)
+    : octave_base_value (), m_range (make_double_range (r)), m_idx_cache ()
+  {
+    if (numel () < 0 && numel () != -2)
+      error ("invalid range");
+  }
+
   octave_range (double base, double limit, double increment)
     : octave_base_value (), m_range (base, limit, increment), m_idx_cache ()
   {
@@ -360,4 +434,18 @@
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
 
+typedef octave_range octave_float_range;
+typedef octave_range octave_double_range;
+
+typedef octave_range octave_int8_range;
+typedef octave_range octave_int16_range;
+typedef octave_range octave_int32_range;
+typedef octave_range octave_int64_range;
+
+typedef octave_range octave_uint8_range;
+typedef octave_range octave_uint16_range;
+typedef octave_range octave_uint32_range;
+typedef octave_range octave_uint64_range;
+
+
 #endif
--- a/libinterp/octave-value/ov.cc	Thu Aug 06 16:28:30 2020 -0400
+++ b/libinterp/octave-value/ov.cc	Thu Aug 06 23:57:40 2020 -0400
@@ -1088,14 +1088,111 @@
   maybe_mutate ();
 }
 
+octave_value::octave_value (const octave::range<char>& r, char type,
+                            bool /*force_range*/)
+#if 0
+  : rep (force_range || ! Vdisable_range
+         ? dynamic_cast<octave_base_value *> (new octave_char_range (r, type))
+         : dynamic_cast<octave_base_value *> (type == '"'
+                                              ? new octave_char_matrix_dq_str (r.array_value ())
+                                              : new octave_char_matrix_sq_str (r.array_value ())))
+#else
+  : rep (type == '"'
+         ? new octave_char_matrix_dq_str (r.array_value ())
+         : new octave_char_matrix_sq_str (r.array_value ()))
+#endif
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const octave::range<float>& r, bool force_range)
+  : rep (force_range || ! Vdisable_range
+         ? dynamic_cast<octave_base_value *> (new octave_float_range (r))
+         : dynamic_cast<octave_base_value *> (new octave_float_matrix (r.array_value ())))
+{
+  maybe_mutate ();
+}
+
 octave_value::octave_value (const octave::range<double>& r, bool force_range)
   : rep (force_range || ! Vdisable_range
-         ? dynamic_cast<octave_base_value *> (new octave_range (r))
+         ? dynamic_cast<octave_base_value *> (new octave_double_range (r))
          : dynamic_cast<octave_base_value *> (new octave_matrix (r.array_value ())))
 {
   maybe_mutate ();
 }
 
+octave_value::octave_value (const octave::range<octave_int8>& r,
+                            bool force_range)
+  : rep (force_range || ! Vdisable_range
+         ? dynamic_cast<octave_base_value *> (new octave_int8_range (r))
+         : dynamic_cast<octave_base_value *> (new octave_int8_matrix (r.array_value ())))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const octave::range<octave_int16>& r,
+                            bool force_range)
+  : rep (force_range || ! Vdisable_range
+         ? dynamic_cast<octave_base_value *> (new octave_int16_range (r))
+         : dynamic_cast<octave_base_value *> (new octave_int16_matrix (r.array_value ())))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const octave::range<octave_int32>& r,
+                            bool force_range)
+  : rep (force_range || ! Vdisable_range
+         ? dynamic_cast<octave_base_value *> (new octave_int32_range (r))
+         : dynamic_cast<octave_base_value *> (new octave_int32_matrix (r.array_value ())))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const octave::range<octave_int64>& r,
+                            bool force_range)
+  : rep (force_range || ! Vdisable_range
+         ? dynamic_cast<octave_base_value *> (new octave_int64_range (r))
+         : dynamic_cast<octave_base_value *> (new octave_int64_matrix (r.array_value ())))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const octave::range<octave_uint8>& r,
+                            bool force_range)
+  : rep (force_range || ! Vdisable_range
+         ? dynamic_cast<octave_base_value *> (new octave_uint8_range (r))
+         : dynamic_cast<octave_base_value *> (new octave_uint8_matrix (r.array_value ())))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const octave::range<octave_uint16>& r,
+                            bool force_range)
+  : rep (force_range || ! Vdisable_range
+         ? dynamic_cast<octave_base_value *> (new octave_uint16_range (r))
+         : dynamic_cast<octave_base_value *> (new octave_uint16_matrix (r.array_value ())))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const octave::range<octave_uint32>& r,
+                            bool force_range)
+  : rep (force_range || ! Vdisable_range
+         ? dynamic_cast<octave_base_value *> (new octave_uint32_range (r))
+         : dynamic_cast<octave_base_value *> (new octave_uint32_matrix (r.array_value ())))
+{
+  maybe_mutate ();
+}
+
+octave_value::octave_value (const octave::range<octave_uint64>& r,
+                            bool force_range)
+  : rep (force_range || ! Vdisable_range
+         ? dynamic_cast<octave_base_value *> (new octave_uint64_range (r))
+         : dynamic_cast<octave_base_value *> (new octave_uint64_matrix (r.array_value ())))
+{
+  maybe_mutate ();
+}
+
 octave_value::octave_value (const octave_map& m)
   : rep (new octave_struct (m))
 {
@@ -2865,20 +2962,14 @@
   make_range (const octave_value& base, const octave_value& increment,
               const octave_value& limit, bool for_cmd_expr)
   {
-    // FIXME: ultimately we will eliminate these casts and create range
-    // objects that properly correspond to the type T instead of always
-    // returning range<double>.
-
     if (base.isempty () || increment.isempty () || limit.isempty ())
-      return octave_value (octave::range<double> (), for_cmd_expr);
+      return octave_value (octave::range<T> (), for_cmd_expr);
 
     T base_val = octave_value_extract<T> (base);
     T increment_val = octave_value_extract<T> (increment);
     T limit_val = octave_value_extract<T> (limit);
 
-    octave::range<double> r (static_cast<double> (base_val),
-                             static_cast<double> (increment_val),
-                             static_cast<double> (limit_val));
+    octave::range<T> r (base_val, increment_val, limit_val);
 
     return octave_value (r, for_cmd_expr);
   }
--- a/libinterp/octave-value/ov.h	Thu Aug 06 16:28:30 2020 -0400
+++ b/libinterp/octave-value/ov.h	Thu Aug 06 23:57:40 2020 -0400
@@ -277,7 +277,17 @@
   octave_value (double base, double limit, double inc);
   OCTAVE_DEPRECATED (7, "use 'octave_value (range<double>&)' instead")
   octave_value (const Range& r, bool force_range = false);
+  octave_value (const octave::range<char>& r, char type, bool force_range = false);
+  octave_value (const octave::range<float>& r, bool force_range = false);
   octave_value (const octave::range<double>& r, bool force_range = false);
+  octave_value (const octave::range<octave_int8>& r, bool force_range = false);
+  octave_value (const octave::range<octave_int16>& r, bool force_range = false);
+  octave_value (const octave::range<octave_int32>& r, bool force_range = false);
+  octave_value (const octave::range<octave_int64>& r, bool force_range = false);
+  octave_value (const octave::range<octave_uint8>& r, bool force_range = false);
+  octave_value (const octave::range<octave_uint16>& r, bool force_range = false);
+  octave_value (const octave::range<octave_uint32>& r, bool force_range = false);
+  octave_value (const octave::range<octave_uint64>& r, bool force_range = false);
   octave_value (const octave_map& m);
   octave_value (const octave_scalar_map& m);
   octave_value (const std::map<std::string, octave_value>&);
--- a/liboctave/array/Range.h	Thu Aug 06 16:28:30 2020 -0400
+++ b/liboctave/array/Range.h	Thu Aug 06 23:57:40 2020 -0400
@@ -109,6 +109,12 @@
         m_final (limit), m_numel (numel)
     { }
 
+    range (const T& base, const T& increment, const T& limit,
+           const T& final, octave_idx_type numel)
+      : m_base (base), m_increment (increment), m_limit (limit),
+        m_final (final), m_numel (numel)
+    { }
+
     // We don't use a constructor for this because it will conflict with
     // range<T> (base, limit) when T is octave_idx_type.