diff src/ov.cc @ 8345:c777f3ce02d8

smarter conversion lookup
author Jaroslav Hajek <highegg@gmail.com>
date Tue, 25 Nov 2008 14:04:55 +0100
parents 283989f2da9b
children 8302788f09db
line wrap: on
line diff
--- a/src/ov.cc
+++ b/src/ov.cc
@@ -1614,7 +1614,18 @@
       else
 	{
 	  octave_value tv1;
-	  octave_base_value::type_conv_fcn cf1 = v1.numeric_conversion_function ();
+	  octave_base_value::type_conv_info cf1 = v1.numeric_conversion_function ();
+
+	  octave_value tv2;
+	  octave_base_value::type_conv_info cf2 = v2.numeric_conversion_function ();
+
+          // Try biased (one-sided) conversions first.
+          if (cf2.type_id () >= 0 &&
+              octave_value_typeinfo::lookup_binary_op (op, t1, cf2.type_id ()))
+            cf1 = 0;
+          else if (cf1.type_id () >= 0 &&
+                   octave_value_typeinfo::lookup_binary_op (op, cf1.type_id (), t2))
+            cf2 = 0;
 
 	  if (cf1)
 	    {
@@ -1634,9 +1645,6 @@
 	  else
 	    tv1 = v1;
 
-	  octave_value tv2;
-	  octave_base_value::type_conv_fcn cf2 = v2.numeric_conversion_function ();
-
 	  if (cf2)
 	    {
 	      octave_base_value *tmp = cf2 (*v2.rep);
@@ -1657,87 +1665,23 @@
 
 	  if (cf1 || cf2)
 	    {
-	      f = octave_value_typeinfo::lookup_binary_op (op, t1, t2);
-
-	      if (f)
-		{
-		  try
-		    {
-		      retval = f (*tv1.rep, *tv2.rep);
-		    }
-		  catch (octave_execution_exception)
-		    {
-		      gripe_library_execution_error ();
-		    }
-		}
-	      else
-		{
-		  //demote double -> single and try again
-		  cf1 = tv1.numeric_demotion_function ();
-
-		  if (cf1)
-		    {
-		      octave_base_value *tmp = cf1 (*tv1.rep);
-
-		      if (tmp)
-			{
-			  tv1 = octave_value (tmp);
-			  t1 = tv1.type_id ();
-			}
-		      else
-			{
-			  gripe_binary_op_conv (octave_value::binary_op_as_string (op));
-			  return retval;
-			}
-		    }
-
-		  cf2 = tv2.numeric_demotion_function ();
-
-		  if (cf2)
-		    {
-		      octave_base_value *tmp = cf2 (*tv2.rep);
-
-		      if (tmp)
-			{
-			  tv2 = octave_value (tmp);
-			  t2 = tv2.type_id ();
-			}
-		      else
-			{
-			  gripe_binary_op_conv (octave_value::binary_op_as_string (op));
-			  return retval;
-			}
-		    }
-
-		  if (cf1 || cf2)
-		    {
-		      f = octave_value_typeinfo::lookup_binary_op (op, t1, t2);
-
-		      if (f)
-			{
-			  try
-			    {
-			      retval = f (*tv1.rep, *tv2.rep);
-			    }
-			  catch (octave_execution_exception)
-			    {
-			      gripe_library_execution_error ();
-			    }
-			}
-		      else
-			gripe_binary_op (octave_value::binary_op_as_string (op),
-					 v1.type_name (), v2.type_name ());
-		    }
-		  else
-		    gripe_binary_op (octave_value::binary_op_as_string (op),
-				     v1.type_name (), v2.type_name ());
-		}
+              retval = do_binary_op (op, tv1, tv2);
 	    }
 	  else
 	    {
 	      //demote double -> single and try again
 	      cf1 = tv1.numeric_demotion_function ();
 
+	      cf2 = tv2.numeric_demotion_function ();
+
+              // Try biased (one-sided) conversions first.
+              if (cf2.type_id () >= 0
+                  && octave_value_typeinfo::lookup_binary_op (op, t1, cf2.type_id ()))
+                cf1 = 0;
+              else if (cf1.type_id () >= 0
+                       && octave_value_typeinfo::lookup_binary_op (op, cf1.type_id (), t2))
+                cf2 = 0;
+
 	      if (cf1)
 		{
 		  octave_base_value *tmp = cf1 (*tv1.rep);
@@ -1754,8 +1698,6 @@
 		    }
 		}
 
-	      cf2 = tv2.numeric_demotion_function ();
-
 	      if (cf2)
 		{
 		  octave_base_value *tmp = cf2 (*tv2.rep);
@@ -1931,7 +1873,18 @@
   else
     {
       octave_value tv1;
-      octave_base_value::type_conv_fcn cf1 = v1.numeric_conversion_function ();
+      octave_base_value::type_conv_info cf1 = v1.numeric_conversion_function ();
+
+      octave_value tv2;
+      octave_base_value::type_conv_info cf2 = v2.numeric_conversion_function ();
+
+      // Try biased (one-sided) conversions first.
+      if (cf2.type_id () >= 0
+          && octave_value_typeinfo::lookup_cat_op (t1, cf2.type_id ()))
+        cf1 = 0;
+      else if (cf1.type_id () >= 0
+               && octave_value_typeinfo::lookup_cat_op (cf1.type_id (), t2))
+        cf2 = 0;
 
       if (cf1)
 	{
@@ -1951,9 +1904,6 @@
       else
 	tv1 = v1;
 
-      octave_value tv2;
-      octave_base_value::type_conv_fcn cf2 = v2.numeric_conversion_function ();
-
       if (cf2)
 	{
 	  octave_base_value *tmp = cf2 (*v2.rep);
@@ -1974,21 +1924,7 @@
 
       if (cf1 || cf2)
 	{
-	  f = octave_value_typeinfo::lookup_cat_op (t1, t2);
-
-	  if (f)
-	    {
-	      try
-		{
-		  retval = f (*tv1.rep, *tv2.rep, ra_idx);
-		}
-	      catch (octave_execution_exception)
-		{
-		  gripe_library_execution_error ();
-		}
-	    }
-	  else
-	    gripe_cat_op (v1.type_name (), v2.type_name ());
+          retval = do_cat_op (tv1, tv2, ra_idx);
 	}
       else
 	gripe_cat_op (v1.type_name (), v2.type_name ());
@@ -2079,24 +2015,7 @@
 	      if (tmp)
 		{
 		  tv = octave_value (tmp);
-		  t = tv.type_id ();
-
-		  f = octave_value_typeinfo::lookup_unary_op (op, t);
-
-		  if (f)
-		    {
-		      try
-			{
-			  retval = f (*tv.rep);
-			}
-		      catch (octave_execution_exception)
-			{
-			  gripe_library_execution_error ();
-			}
-		    }
-		  else
-		    gripe_unary_op (octave_value::unary_op_as_string (op),
-				    v.type_name ());
+                  retval = do_unary_op (op, tv);
 		}
 	      else
 		gripe_unary_op_conv (octave_value::unary_op_as_string (op));