# HG changeset patch # User John W. Eaton # Date 1318472701 14400 # Node ID 348857854c5231edbf122a0a3e128d93b542e8fa # Parent 441af0aa125afea36aa51bb410f48261a4cd53e5 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. diff -r 441af0aa125a -r 348857854c52 src/DLD-FUNCTIONS/cellfun.cc --- 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& 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 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 ()) diff -r 441af0aa125a -r 348857854c52 src/ov-class.cc --- 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; } diff -r 441af0aa125a -r 348857854c52 test/classes/test_classes.m --- 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});