changeset 32145:00740c1f8e82

new function to get for loop value from octave_value object * ov.h (octave_value::vm_extract_forloop_value, octave_value::vm_extract_forloop_double): New functions. * ov-base-mat.h, ov-base-mat.cc (octave_base_matrix<MT>::vm_extract_forloop_value): New function. * ov-base-scalar.h, ov-base-scalar.cc (octave_base_scalar<ST>::vm_extract_forloop_value): New function. * ov-base.h, ov-base.cc (octave_base_value::vm_extract_forloop_value, octave_base_value::vm_extract_forloop_double): New virtual functions. * ov-range.h, ov-range.cc (octave_trivial_range::vm_extract_forloop_value, octave_trivial_range::vm_extract_forloop_double): New functions. (ov_range::octave_trivial_range::vm_extract_forloop_value): New function. * ov-struct.h, ov-struct.cc (octave_struct::vm_extract_forloop_value): New function.
author Petter T. <petter.vilhelm@gmail.com>
date Mon, 19 Jun 2023 15:28:32 -0400
parents a36ba266f4eb
children 18c6b6997055
files libinterp/octave-value/ov-base-mat.cc libinterp/octave-value/ov-base-mat.h libinterp/octave-value/ov-base-scalar.cc libinterp/octave-value/ov-base-scalar.h libinterp/octave-value/ov-base.cc libinterp/octave-value/ov-base.h libinterp/octave-value/ov-range.cc libinterp/octave-value/ov-range.h libinterp/octave-value/ov-struct.cc libinterp/octave-value/ov-struct.h libinterp/octave-value/ov.h
diffstat 11 files changed, 152 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/octave-value/ov-base-mat.cc	Mon Jun 19 14:16:39 2023 -0400
+++ b/libinterp/octave-value/ov-base-mat.cc	Mon Jun 19 15:28:32 2023 -0400
@@ -39,6 +39,7 @@
 #include "ov-base.h"
 #include "ov-base-mat.h"
 #include "ov-base-scalar.h"
+#include "ov-inline.h"
 #include "pr-output.h"
 
 template <typename MT>
@@ -587,6 +588,40 @@
 }
 
 template <typename MT>
+octave_value
+octave_base_matrix<MT>::vm_extract_forloop_value (octave_idx_type counter)
+{
+  // TODO: Maybe this is slow? Should preferably be done once per loop
+  octave_value_list idx;
+  octave_value arg = octave_value_factory::make_copy (this);
+
+  dim_vector dv = arg.dims ().redim (2);
+  octave_idx_type nrows = dv(0);
+
+  if (arg.ndims () > 2)
+    arg = arg.reshape (dv);
+
+  octave_idx_type iidx;
+
+  // for row vectors, use single index to speed things up.
+  if (nrows == 1)
+    {
+      idx.resize (1);
+      iidx = 0;
+    }
+  else
+    {
+      idx.resize (2);
+      idx(0) = octave_value::magic_colon_t;
+      iidx = 1;
+    }
+
+  // One based indexing
+  idx(iidx) = counter + 1;
+  return arg.index_op (idx).storable_value ();
+}
+
+template <typename MT>
 bool
 octave_base_matrix<MT>::fast_elem_insert (octave_idx_type n,
     const octave_value& x)
--- a/libinterp/octave-value/ov-base-mat.h	Mon Jun 19 14:16:39 2023 -0400
+++ b/libinterp/octave-value/ov-base-mat.h	Mon Jun 19 15:28:32 2023 -0400
@@ -209,6 +209,9 @@
   // You should not use it anywhere else.
   const void * mex_get_data () const { return m_matrix.data (); }
 
+  OCTINTERP_API octave_value
+  vm_extract_forloop_value (octave_idx_type idx);
+
   octave_value
   checked_full_matrix_elem (octave_idx_type i) const;
 
--- a/libinterp/octave-value/ov-base-scalar.cc	Mon Jun 19 14:16:39 2023 -0400
+++ b/libinterp/octave-value/ov-base-scalar.cc	Mon Jun 19 15:28:32 2023 -0400
@@ -69,6 +69,14 @@
 
 template <typename ST>
 octave_value
+octave_base_scalar<ST>::vm_extract_forloop_value (octave_idx_type)
+{
+  return octave_value (scalar);
+}
+
+
+template <typename ST>
+octave_value
 octave_base_scalar<ST>::subsasgn (const std::string& type,
                                   const std::list<octave_value_list>& idx,
                                   const octave_value& rhs)
--- a/libinterp/octave-value/ov-base-scalar.h	Mon Jun 19 14:16:39 2023 -0400
+++ b/libinterp/octave-value/ov-base-scalar.h	Mon Jun 19 15:28:32 2023 -0400
@@ -169,6 +169,9 @@
 
   OCTINTERP_API octave_value fast_elem_extract (octave_idx_type n) const;
 
+  OCTINTERP_API octave_value
+  vm_extract_forloop_value (octave_idx_type idx);
+
   OCTINTERP_API bool
   fast_elem_insert_self (void *where, builtin_type_t btyp) const;
 
--- a/libinterp/octave-value/ov-base.cc	Mon Jun 19 14:16:39 2023 -0400
+++ b/libinterp/octave-value/ov-base.cc	Mon Jun 19 15:28:32 2023 -0400
@@ -282,6 +282,18 @@
   octave::err_invalid_index (nm.c_str ());
 }
 
+octave_value
+octave_base_value::vm_extract_forloop_value (octave_idx_type idx)
+{
+  return fast_elem_extract (idx).as_double_or_copy ();
+}
+
+double
+octave_base_value::vm_extract_forloop_double (octave_idx_type)
+{
+  error ("Type error extracting for loop iterator double value for VM");
+}
+
 bool 
 octave_base_value::maybe_update_double (double)
 {
--- a/libinterp/octave-value/ov-base.h	Mon Jun 19 14:16:39 2023 -0400
+++ b/libinterp/octave-value/ov-base.h	Mon Jun 19 15:28:32 2023 -0400
@@ -812,6 +812,12 @@
 
   virtual octave_value_ref * ref_rep ();
 
+  virtual octave_value
+  vm_extract_forloop_value (octave_idx_type idx);
+
+  virtual double
+  vm_extract_forloop_double (octave_idx_type idx);
+
   virtual bool maybe_update_double (double d);
 
   virtual bool is_trivial_range () const { return false; };
--- a/libinterp/octave-value/ov-range.cc	Mon Jun 19 14:16:39 2023 -0400
+++ b/libinterp/octave-value/ov-range.cc	Mon Jun 19 15:28:32 2023 -0400
@@ -1035,6 +1035,24 @@
   return m_range;
 }
 
+template <typename T>
+octave_value
+ov_range<T>::vm_extract_forloop_value (octave_idx_type n)
+{
+  octave_value ov = octave_value_factory::make (m_range.elem (n));
+
+  return ov.as_double_or_copy ();
+}
+
+template <>
+octave_value
+ov_range<double>::vm_extract_forloop_value (octave_idx_type n)
+{
+  octave_value ov = octave_value_factory::make (m_range.elem (n));
+
+  return ov;
+}
+
 // For now, enable only ov_range<double>.
 
 template <>
--- a/libinterp/octave-value/ov-range.h	Mon Jun 19 14:16:39 2023 -0400
+++ b/libinterp/octave-value/ov-range.h	Mon Jun 19 15:28:32 2023 -0400
@@ -63,6 +63,22 @@
 
   octave_trivial_range (const octave_trivial_range&) = default;
 
+  OCTINTERP_API octave_value
+  vm_extract_forloop_value (octave_idx_type i)
+  {
+    if (i < m_numel - 1)
+      return m_base + static_cast<int> (i) * m_increment;
+    return m_base + (m_numel - 1) * m_increment;
+  }
+
+  double
+  vm_extract_forloop_double (octave_idx_type i)
+  {
+    if (i < m_numel - 1)
+      return m_base + static_cast<int> (i) * m_increment;
+    return m_base + (m_numel - 1) * m_increment;    
+  }
+
   bool is_trivial_range () const { return true; };
 
 private:
@@ -155,6 +171,9 @@
   OCTINTERP_API octave_value as_trivial_range ();
   OCTINTERP_API bool could_be_trivial_range ();
 
+  OCTINTERP_API octave_value
+  vm_extract_forloop_value (octave_idx_type idx);
+
   octave_idx_type numel () const { return m_range.numel (); }
 
   octave_idx_type nnz () const
--- a/libinterp/octave-value/ov-struct.cc	Mon Jun 19 14:16:39 2023 -0400
+++ b/libinterp/octave-value/ov-struct.cc	Mon Jun 19 15:28:32 2023 -0400
@@ -52,6 +52,7 @@
 #include "ls-hdf5.h"
 #include "ls-utils.h"
 #include "pr-output.h"
+#include "ov-inline.h"
 
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(octave_struct, "struct", "struct");
@@ -1095,6 +1096,39 @@
   return retval;
 }
 
+octave_value 
+octave_struct::vm_extract_forloop_value (octave_idx_type counter)
+{
+  // TODO: Maybe this is slow? Should preferably be done once per loop
+  octave_value_list idx;
+  octave_value arg = octave_value_factory::make_copy (this);
+
+  dim_vector dv = arg.dims ().redim (2);
+  octave_idx_type nrows = dv(0);
+
+  if (arg.ndims () > 2)
+    arg = arg.reshape (dv);
+
+  octave_idx_type iidx;
+
+  // for row vectors, use single index to speed things up.
+  if (nrows == 1)
+    {
+      idx.resize (1);
+      iidx = 0;
+    }
+  else
+    {
+      idx.resize (2);
+      idx(0) = octave_value::magic_colon_t;
+      iidx = 1;
+    }
+
+  // One based indexing
+  idx(iidx) = counter + 1;
+  return arg.index_op (idx).storable_value (); 
+}
+
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(octave_scalar_struct, "scalar struct",
                                     "struct");
 
--- a/libinterp/octave-value/ov-struct.h	Mon Jun 19 14:16:39 2023 -0400
+++ b/libinterp/octave-value/ov-struct.h	Mon Jun 19 15:28:32 2023 -0400
@@ -101,6 +101,8 @@
 
   dim_vector dims () const { return m_map.dims (); }
 
+  octave_value vm_extract_forloop_value (octave_idx_type idx);
+
   std::size_t byte_size () const;
 
   // This is the number of elements in each field.  The total number
--- a/libinterp/octave-value/ov.h	Mon Jun 19 14:16:39 2023 -0400
+++ b/libinterp/octave-value/ov.h	Mon Jun 19 15:28:32 2023 -0400
@@ -1580,6 +1580,18 @@
   checked_full_matrix_elem (octave_idx_type i, octave_idx_type j) const
   { return m_rep->checked_full_matrix_elem (i, j); }
 
+  octave_value
+  vm_extract_forloop_value (octave_idx_type idx)
+  {
+    return m_rep->vm_extract_forloop_value (idx);
+  }
+
+  double
+  vm_extract_forloop_double (octave_idx_type idx)
+  {
+    return m_rep->vm_extract_forloop_double (idx);
+  }
+
   bool
   maybe_update_double (double d)
   {