changeset 9691:318e0cdd31bd

improve OOP subsref handling
author Jaroslav Hajek <highegg@gmail.com>
date Mon, 05 Oct 2009 10:20:18 +0200
parents f42f0d707e8e
children 126b49caba0d
files src/ChangeLog src/ov-class.cc src/pt-misc.cc
diffstat 3 files changed, 54 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@
+2009-10-05  Jaroslav Hajek  <highegg@gmail.com>
+
+	* pt-misc.cc (tree_argument_list::convert_to_const_vector):
+	Return more than nargout arguments only unless undefined elements
+	occur.
+	* ov-class.cc (octave_class::subsref): Pack return list from
+	overloaded method into first value.
+
 2009-10-05  Jaroslav Hajek  <highegg@gmail.com>
 
 	* ov-ch-mat.h (octave_char_matrix): Don't declare allocator and
--- a/src/ov-class.cc
+++ b/src/ov-class.cc
@@ -464,27 +464,32 @@
 	  count++;
 	  args(0) = octave_value (this);
 
+          // FIXME: for Matlab compatibility, let us attempt to set up a proper
+          // value for nargout at least in the simple case where the
+          // cs-list-type expression - i.e., {} or ().x, is the leading one.
+          // Note that Octave does not actually need this, since it will
+          // be able to properly react to varargout a posteriori.
           bool maybe_cs_list_query = (type[0] == '.' || type[0] == '{'
                                       || (type.length () > 1 && type[0] == '('
                                           && type[1] == '.'));
 
-          if (nargout == 1 && maybe_cs_list_query)
+          int true_nargout = nargout;
+
+          if (maybe_cs_list_query)
             {
               // Set up a proper nargout for the subsref call by calling numel.
               octave_value_list tmp;
               if (type[0] != '.') tmp = idx.front ();
-              octave_idx_type true_nargout = numel (tmp);
-              if (! error_state)
-                {
-                  tmp = feval (meth.function_value (), args, true_nargout);
-                  if (true_nargout != 1)
-                    retval(0) = octave_value (tmp, true);
-                  else
-                    retval = tmp;
-                }
+              true_nargout = numel (tmp);
             }
-          else
-            retval = feval (meth.function_value (), args, nargout);
+
+          retval = feval (meth.function_value (), args, true_nargout);
+
+          // Since we're handling subsref, return the list in the first value
+          // if it has more than one element, to be able to pass through
+          // rvalue1 calls. 
+          if (retval.length () > 1)
+            retval = octave_value (retval, true);
 	}
       else
 	{
--- a/src/pt-misc.cc
+++ b/src/pt-misc.cc
@@ -208,34 +208,45 @@
                                               const Cell& varargout)
 {
   octave_idx_type vlen = varargout.numel ();
+  int len = length ();
 
   // Special case. Will do a shallow copy.
-  if (length () == 0 && vlen == nargout)
+  if (len == 0)
     return varargout;
+  else if (nargout <= len)
+    {
+      octave_value_list retval (nargout);
+
+      int i = 0;
 
-  // We want always at least one return value.
-  int nout = std::max (nargout, 1);
-  octave_value_list retval (nout);
-
-  int i = 0;
-
-  for (iterator p = begin (); p != end () && i < nout; p++)
-    {
-      tree_decl_elt *elt = *p;
+      for (iterator p = begin (); p != end (); p++)
+        {
+          tree_decl_elt *elt = *p;
+          if (elt->is_defined ())
+            retval(i++) = elt->rvalue1 ();
+          else
+            break;
+        }
 
-      retval(i++) = elt->is_defined () ? elt->rvalue1 () : octave_value ();
+      return retval;
     }
+  else
+    {
+      octave_value_list retval (len + vlen);
 
-  vlen = std::min (vlen, nout - i);
+      int i = 0;
 
-  for (octave_idx_type j = 0; j < vlen; j++)
-    retval(i++) = varargout(j);
+      for (iterator p = begin (); p != end (); p++)
+        {
+          tree_decl_elt *elt = *p;
+          retval(i++) = elt->rvalue1 ();
+        }
 
-  // If there was zero outputs requested, and nothing is defined, don't return anything.
-  if (nargout == 0 && retval(0).is_undefined ())
-    retval = octave_value_list ();
+      for (octave_idx_type j = 0; j < vlen; j++)
+        retval(i++) = varargout(j);
 
-  return retval;
+      return retval;
+    }
 }
 
 bool