changeset 32127:408aa8a98b58

new simple_numeric_assign function to handle simple case This new function allows std::list and std::string ctors to be avoided when they are not needed. * ov-base.h, ov-base.cc (octave_base_value::simple_numeric_assign): New function.
author Petter T. <petter.vilhelm@gmail.com>
date Thu, 15 Jun 2023 12:26:25 -0400
parents b1e1830e2cff
children d3023141b792
files libinterp/octave-value/ov-base.cc libinterp/octave-value/ov-base.h
diffstat 2 files changed, 126 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/octave-value/ov-base.cc	Thu Jun 15 11:28:16 2023 -0400
+++ b/libinterp/octave-value/ov-base.cc	Thu Jun 15 12:26:25 2023 -0400
@@ -1208,6 +1208,128 @@
 }
 
 octave_value
+octave_base_value::simple_numeric_assign (char type, octave_value_list& idx,
+                                          const octave_value& rhs)
+{
+  octave_value retval;
+
+  if (idx.empty ())
+    error ("missing index in indexed assignment");
+
+  int t_lhs = type_id ();
+  int t_rhs = rhs.type_id ();
+
+  octave::type_info& ti = octave::__get_type_info__ ();
+
+  octave::type_info::assign_op_fcn f
+    = ti.lookup_assign_op (octave_value::op_asn_eq, t_lhs, t_rhs);
+
+  bool done = false;
+
+  if (f)
+    {
+      f (*this, idx, rhs.get_rep ());
+
+      done = true;
+    }
+
+  if (done)
+    {
+      m_count++;
+      retval = octave_value (this);
+    }
+  else
+    {
+      int t_result = ti.lookup_pref_assign_conv (t_lhs, t_rhs);
+
+      if (t_result >= 0)
+        {
+          octave_base_value::type_conv_fcn cf
+            = ti.lookup_widening_op (t_lhs, t_result);
+
+          if (! cf)
+            err_indexed_assignment (type_name (), rhs.type_name ());
+
+          octave_base_value *tmp = cf (*this);
+
+          if (! tmp)
+            err_assign_conversion_failed (type_name (), rhs.type_name ());
+
+          octave_value val (tmp);
+
+          retval = val.simple_subsasgn (type, idx, rhs);
+
+          done = true;
+        }
+
+      if (! done)
+        {
+          octave_value tmp_rhs;
+
+          octave_base_value::type_conv_info cf_rhs
+            = rhs.numeric_conversion_function ();
+
+          octave_base_value::type_conv_info cf_this
+            = numeric_conversion_function ();
+
+          // Try biased (one-sided) conversions first.
+          if (cf_rhs.type_id () >= 0
+              && (ti.lookup_assign_op (octave_value::op_asn_eq,
+                                       t_lhs, cf_rhs.type_id ())
+                  || ti.lookup_pref_assign_conv (t_lhs,
+                                                 cf_rhs.type_id ()) >= 0))
+            cf_this = nullptr;
+          else if (cf_this.type_id () >= 0
+                   && (ti.lookup_assign_op (octave_value::op_asn_eq,
+                                            cf_this.type_id (), t_rhs)
+                       || ti.lookup_pref_assign_conv (cf_this.type_id (),
+                                                      t_rhs) >= 0))
+            cf_rhs = nullptr;
+
+          if (cf_rhs)
+            {
+              octave_base_value *tmp = cf_rhs (rhs.get_rep ());
+
+              if (! tmp)
+                err_assign_conversion_failed (type_name (), rhs.type_name ());
+
+              tmp_rhs = octave_value (tmp);
+            }
+          else
+            tmp_rhs = rhs;
+
+          m_count++;
+          octave_value tmp_lhs = octave_value (this);
+
+          if (cf_this)
+            {
+              octave_base_value *tmp = cf_this (*this);
+
+              if (! tmp)
+                err_assign_conversion_failed (type_name (), rhs.type_name ());
+
+              tmp_lhs = octave_value (tmp);
+            }
+
+          if (! cf_this && ! cf_rhs)
+            err_no_conversion (octave_value::assign_op_as_string
+                               (octave_value::op_asn_eq),
+                               type_name (), rhs.type_name ());
+
+          retval = tmp_lhs.simple_subsasgn (type, idx, tmp_rhs);
+
+          done = true;
+        }
+    }
+
+  // The assignment may have converted to a type that is wider than necessary.
+
+  retval.maybe_mutate ();
+
+  return retval;
+}
+
+octave_value
 octave_base_value::numeric_assign (const std::string& type,
                                    const std::list<octave_value_list>& idx,
                                    const octave_value& rhs)
--- a/libinterp/octave-value/ov-base.h	Thu Jun 15 11:28:16 2023 -0400
+++ b/libinterp/octave-value/ov-base.h	Thu Jun 15 12:26:25 2023 -0400
@@ -876,6 +876,10 @@
                   const std::list<octave_value_list>& idx,
                   const octave_value& rhs);
 
+  OCTINTERP_API octave_value
+  simple_numeric_assign (char type, octave_value_list& idx,
+                         const octave_value& rhs);
+
   void reset_indent_level () const
   { s_curr_print_indent_level = 0; }