changeset 2409:47e5f57fb4bd

[project @ 1996-10-15 16:44:26 by jwe]
author jwe
date Tue, 15 Oct 1996 16:44:26 +0000
parents e22aae3ccfad
children 367485171742
files src/ov.cc src/ov.h src/pt-const.h
diffstat 3 files changed, 166 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/src/ov.cc
+++ b/src/ov.cc
@@ -258,14 +258,15 @@
   : rep (new octave_char_matrix_str (s)) { rep->count = 1; }
 
 octave_value::octave_value (const charMatrix& chm, bool is_string)
-  {
-    if (is_string)
-      rep = new octave_char_matrix_str (chm);
-    else
-      rep = new octave_char_matrix (chm);
+  : rep (0)
+{
+  if (is_string)
+    rep = new octave_char_matrix_str (chm);
+  else
+    rep = new octave_char_matrix (chm);
 
-    rep->count = 1;
-  }
+  rep->count = 1;
+}
 
 octave_value::octave_value (double base, double limit, double inc)
   : rep (new octave_range (base, limit, inc)) { rep->count = 1; }
@@ -299,6 +300,21 @@
     }
 }
 
+void
+octave_value::maybe_mutate (void)
+{
+  octave_value *tmp = rep->try_narrow_conversion ();
+
+  if (tmp && tmp != rep)
+    {
+      if (--rep->count == 0)
+	delete rep;
+
+      rep = tmp;
+      rep->count = 1;
+    }    
+}
+
 static void
 gripe_indexed_assignment (const string& tn1, const string& tn2)
 {
@@ -320,10 +336,110 @@
 	 tn2.c_str (), tn1.c_str ());
 }
 
-octave_value&
-octave_value::assign (const octave_value_list& idx, const octave_value& rhs)
+bool
+octave_value::convert_and_assign (const octave_value_list& idx,
+				  const octave_value& rhs)
+{
+  bool assignment_ok = false;
+
+  int t_lhs = type_id ();
+  int t_rhs = rhs.type_id ();
+
+  int t_result
+    = octave_value_typeinfo::lookup_pref_assign_conv (t_lhs, t_rhs);
+
+  if (t_result >= 0)
+    {
+      octave_value::type_conv_fcn cf
+	= octave_value_typeinfo::lookup_widening_op (t_lhs, t_result);
+
+      if (cf)
+	{
+	  octave_value *tmp = cf (*rep);
+
+	  if (tmp)
+	    {
+	      if (tmp != rep)
+		{
+		  if (--rep->count == 0)
+		    delete rep;
+
+		  rep = tmp;
+		  rep->count = 1;
+		}
+	      else
+		delete tmp;
+
+	      assignment_ok = try_assignment (idx, rhs);
+	    }
+	  else
+	    gripe_conversion_failed (type_name (), rhs.type_name ());
+	}
+      else
+	gripe_indexed_assignment (type_name (), rhs.type_name ());
+    }
+
+  return (assignment_ok && ! error_state);
+}
+
+bool
+octave_value::try_assignment_with_conversion (const octave_value_list& idx,
+					      const octave_value& rhs)
 {
-  make_unique ();
+  bool assignment_ok = convert_and_assign (idx, rhs);
+
+  if (! (error_state || assignment_ok))
+    {
+      octave_value tmp_rhs;
+      octave_value::type_conv_fcn cf_rhs = rhs.numeric_conversion_function ();
+
+      if (cf_rhs)
+	tmp_rhs = octave_value (cf_rhs (*rhs.rep));
+      else
+	tmp_rhs = rhs;
+
+      octave_value *old_rep = 0;
+      octave_value::type_conv_fcn cf_this = numeric_conversion_function ();
+
+      if (cf_this)
+	{
+	  old_rep = rep;
+	  rep = cf_this (*rep);
+	  rep->count = 1;
+	}
+
+      cerr << type_name () << "\n";
+      cerr << tmp_rhs.type_name () << "\n";
+
+      if (cf_this || cf_rhs)
+	{
+	  assignment_ok = try_assignment (idx, tmp_rhs);
+
+	  if (! (error_state || assignment_ok))
+	    assignment_ok = convert_and_assign (idx, tmp_rhs);
+	}
+
+      if (! assignment_ok && old_rep)
+	{
+	  if (--rep->count == 0)
+	    delete rep;
+
+	  rep = old_rep;
+	  old_rep = 0;
+	}
+
+      if (old_rep && --old_rep->count == 0)
+	delete old_rep;
+    }
+
+  return (assignment_ok && ! error_state);
+}
+
+bool
+octave_value::try_assignment (const octave_value_list& idx,
+			      const octave_value& rhs)
+{
+  bool retval = false;
 
   int t_lhs = type_id ();
   int t_rhs = rhs.type_id ();
@@ -332,48 +448,33 @@
     = octave_value_typeinfo::lookup_assign_op (t_lhs, t_rhs);
 
   if (f)
-    f (*(this->rep), idx, *(rhs.rep));
-  else
     {
-      int t_result
-	= octave_value_typeinfo::lookup_pref_assign_conv (t_lhs, t_rhs);
+      f (*rep, idx, *(rhs.rep));
 
-      if (t_result >= 0)
-	{
-	  octave_value::widening_op_fcn wf
-	    = octave_value_typeinfo::lookup_widening_op (t_lhs, t_result);
+      retval = (! error_state);
+    }
 
-	  if (wf)
-	    {
-	      octave_value *tmp = wf (*(this->rep));
-
-	      if (tmp && tmp != rep)
-		{
-		  if (--rep->count == 0)
-		    delete rep;
+  return retval;
+}
 
-		  rep = tmp;
-		  rep->count = 1;
-
-		  t_lhs = type_id ();
-
-		  f = octave_value_typeinfo::lookup_assign_op (t_lhs, t_rhs);
+octave_value&
+octave_value::assign (const octave_value_list& idx, const octave_value& rhs)
+{
+  make_unique ();
 
-		  if (f)
-		    f (*(this->rep), idx, *(rhs.rep));
-		  else
-		    gripe_indexed_assignment (type_name (), rhs.type_name ());
-		}
-	      else
-		gripe_conversion_failed (type_name (), rhs.type_name ());
-	    }
-	  else
-	    gripe_indexed_assignment (type_name (), rhs.type_name ());
-	}
-      else
+  bool assignment_ok = try_assignment (idx, rhs);
+
+  if (! (error_state || assignment_ok))
+    {
+      assignment_ok = try_assignment_with_conversion (idx, rhs);
+
+      if (! (error_state || assignment_ok))
 	gripe_no_conversion (type_name (), rhs.type_name ());
     }
 
+  if (! error_state)
+    maybe_mutate ();
+
   return *this;
 }
 
@@ -549,7 +650,7 @@
   else
     {
       octave_value tv1;
-      octave_value::numeric_conv_fcn cf1 = v1.numeric_conversion_function ();
+      octave_value::type_conv_fcn cf1 = v1.numeric_conversion_function ();
 
       if (cf1)
 	{
@@ -560,7 +661,7 @@
 	tv1 = v1;
 
       octave_value tv2;
-      octave_value::numeric_conv_fcn cf2 = v2.numeric_conversion_function ();
+      octave_value::type_conv_fcn cf2 = v2.numeric_conversion_function ();
 
       if (cf2)
 	{
--- a/src/ov.h
+++ b/src/ov.h
@@ -70,9 +70,7 @@
   typedef octave_value (*assign_op_fcn)
     (octave_value&, const octave_value_list&, const octave_value&);
 
-  typedef octave_value * (*widening_op_fcn) (const octave_value&);
-
-  typedef octave_value * (*numeric_conv_fcn) (const octave_value&);
+  typedef octave_value * (*type_conv_fcn) (const octave_value&);
 
   enum binary_op
   {
@@ -175,12 +173,26 @@
       return *this;
     }
 
-  virtual numeric_conv_fcn numeric_conversion_function (void) const
+  virtual type_conv_fcn numeric_conversion_function (void) const
     { return rep->numeric_conversion_function (); }
 
+  void maybe_mutate (void);
+
+  virtual octave_value *try_narrow_conversion (void)
+    { return rep->try_narrow_conversion (); }
+
   virtual octave_value index (const octave_value_list& idx) const
     { return rep->index (idx); }
 
+  bool convert_and_assign (const octave_value_list& idx,
+			   const octave_value& rhs);
+
+  bool try_assignment_with_conversion (const octave_value_list& idx,
+				       const octave_value& rhs);
+
+  bool try_assignment (const octave_value_list& idx,
+		       const octave_value& rhs);
+
   octave_value& assign (const octave_value_list& idx, const octave_value& rhs);
 
   virtual idx_vector index_vector (void) const
--- a/src/pt-const.h
+++ b/src/pt-const.h
@@ -326,6 +326,9 @@
   void convert_to_row_or_column_vector (void)
     { val.convert_to_row_or_column_vector (); }
 
+  void maybe_mutate (void)
+    { val.maybe_mutate (); }
+
   // Increment or decrement this constant.
 
   void increment (void) { val.increment (); }