changeset 13695:348857854c52

correctly handle multidimensional objects in num2cell * cellfun.cc (get_object_dims, do_object2cell): New functions. (Fnum2cell): Call do_object2cell to handle class objects. * ov-class.cc (octave_class::size): Return dims when size method is not available. * test_classes.m: Delete tests for concatenation and num2cell.
author John W. Eaton <jwe@octave.org>
date Wed, 12 Oct 2011 22:25:01 -0400
parents 441af0aa125a
children d6118a2c0644
files src/DLD-FUNCTIONS/cellfun.cc src/ov-class.cc test/classes/test_classes.m
diffstat 3 files changed, 75 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/src/DLD-FUNCTIONS/cellfun.cc	Wed Oct 12 21:28:30 2011 -0400
+++ b/src/DLD-FUNCTIONS/cellfun.cc	Wed Oct 12 22:25:01 2011 -0400
@@ -1712,6 +1712,66 @@
     }
 }
 
+// FIXME -- this is a mess, but if a size method for the object exists,
+// we have to call it to get the size of the object instead of using the
+// internal dims method.
+
+static dim_vector
+get_object_dims (octave_value& obj)
+{
+  dim_vector retval;
+
+  Matrix m = obj.size ();
+
+  int n = m.numel ();
+
+  retval.resize (n);
+
+  for (int i = 0; i < n; i++)
+    retval(i) = m(i);
+
+  return retval;
+}
+
+static Cell
+do_object2cell (const octave_value& obj, const Array<int>& dimv)
+{
+  Cell retval;
+
+  // FIXME -- this copy is only needed because the octave_value::size
+  // method is not const.
+  octave_value array = obj;
+
+  if (dimv.is_empty ())
+    {
+      dim_vector dv = get_object_dims (array);
+
+      if (! error_state)
+        {
+          retval.resize (dv);
+
+          octave_value_list idx (1);
+
+          for (octave_idx_type i = 0; i < dv.numel (); i++)
+            {
+              octave_quit ();
+
+              idx(0) = double (i+1);
+
+              retval.xelem(i) = array.single_subsref ("(", idx);
+
+              if (error_state)
+                break;
+            }
+        }
+    }
+  else
+    {
+      error ("num2cell (A, dim) not implemented for class objects");
+    }
+
+  return retval;
+}
 
 DEFUN_DLD (num2cell, args, ,
   "-*- texinfo -*-\n\
@@ -1801,22 +1861,10 @@
                 retval = do_num2cell (array.array_value (), dimv);
             }
         }
-      else if (array.is_map () || array.is_object ())
-        {
-          Cell tmp = do_num2cell (array.map_value (), dimv);
-
-          if (array.is_object ())
-            {
-              std::string cname = array.class_name ();
-              std::list<std::string> parents = array.parent_class_name_list ();
-
-              for (octave_idx_type i = 0; i < tmp.numel (); i++)
-                tmp(i) = octave_value (new octave_class (tmp(i).map_value (),
-                                                         cname, parents));
-            }
-
-          retval = tmp;
-        }
+      else if (array.is_object ())
+        retval = do_object2cell (array, dimv);
+      else if (array.is_map ())
+        retval = do_num2cell (array.map_value (), dimv);
       else if (array.is_cell ())
         retval = do_num2cell (array.cell_value (), dimv);
       else if (array.is_object ())
--- a/src/ov-class.cc	Wed Oct 12 21:28:30 2011 -0400
+++ b/src/ov-class.cc	Wed Oct 12 22:25:01 2011 -0400
@@ -322,6 +322,17 @@
       else
         error ("@%s/size: invalid return value", class_name ().c_str ());
     }
+  else
+    {
+      dim_vector dv = dims ();
+
+      int nel = dv.numel ();
+
+      retval.resize (1, nel);
+
+      for (int i = 0; i < nel; i++)
+        retval(i) = dv(i);
+    }
 
   return retval;
 }
--- a/test/classes/test_classes.m	Wed Oct 12 21:28:30 2011 -0400
+++ b/test/classes/test_classes.m	Wed Oct 12 22:25:01 2011 -0400
@@ -199,14 +199,3 @@
 %!  assert(isa(grk,'Blork'))
 %!  assert(isa(grk,'Snork'))
 %!  assert(isa(grk,'Spork'))
-
-%!test
-%! d = Dork ();
-%! x = [d,d];
-%! assert (size (x), [1, 2])
-%! assert (class (x), "Dork")
-
-%!test
-%! d = Dork ();
-%! x = [d,d];
-%! assert (num2cell (x), {d, d});