# HG changeset patch # User Jaroslav Hajek # Date 1232701039 -3600 # Node ID 7e0f36dfefbe6c10c08fc5d12ca56be1a8c7a85d # Parent 4b6558abe67591c74d10f75e115609f45dbb654b implement octave_value_list using Array diff --git a/liboctave/Array2.h b/liboctave/Array2.h --- a/liboctave/Array2.h +++ b/liboctave/Array2.h @@ -116,14 +116,14 @@ return Array2 (tmp, tmp.rows (), tmp.columns ()); } - Array2 index (const idx_vector& i, int resize_ok = 0, + Array2 index (const idx_vector& i, bool resize_ok = false, const T& rfv = Array::resize_fill_value ()) const { Array tmp = Array::index (i, resize_ok, rfv); return Array2 (tmp, tmp.rows (), tmp.columns ()); } - Array2 index (const idx_vector& i, const idx_vector& j, int resize_ok = 0, + Array2 index (const idx_vector& i, const idx_vector& j, bool resize_ok = false, const T& rfv = Array::resize_fill_value ()) const { Array tmp = Array::index (i, j, resize_ok, rfv); diff --git a/liboctave/ArrayN.h b/liboctave/ArrayN.h --- a/liboctave/ArrayN.h +++ b/liboctave/ArrayN.h @@ -110,21 +110,21 @@ return *this; } - ArrayN index (idx_vector& i, int resize_ok = 0, + ArrayN index (const idx_vector& i, bool resize_ok = false, const T& rfv = Array::resize_fill_value ()) const { Array tmp = Array::index (i, resize_ok, rfv); return ArrayN (tmp, tmp.dims ()); } - ArrayN index (idx_vector& i, idx_vector& j, int resize_ok = 0, + ArrayN index (const idx_vector& i, const idx_vector& j, bool resize_ok = false, const T& rfv = Array::resize_fill_value ()) const { Array tmp = Array::index (i, j, resize_ok, rfv); return ArrayN (tmp, tmp.dims ()); } - ArrayN index (Array& ra_idx, int resize_ok = 0, + ArrayN index (const Array& ra_idx, bool resize_ok = false, const T& rfv = Array::resize_fill_value ()) const { Array tmp = Array::index (ra_idx, resize_ok, rfv); diff --git a/liboctave/ChangeLog b/liboctave/ChangeLog --- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,9 @@ +2009-01-22 Jaroslav Hajek + + * Array2.h (Array2::index): Declare resize_ok as bool. + * ArrayN.h (ArrayN::index): Dtto. Declare index vectors as const + refs. + 2009-01-22 Jaroslav Hajek * Range.cc (sort_internal): Add missing test. diff --git a/src/Cell.cc b/src/Cell.cc --- a/src/Cell.cc +++ b/src/Cell.cc @@ -29,6 +29,12 @@ #include "Cell.h" #include "error.h" #include "gripes.h" +#include "oct-obj.h" + +Cell::Cell (const octave_value_list& ovl) + : ArrayN (ovl.cell_value ()) +{ +} Cell::Cell (const string_vector& sv, bool trim) : ArrayN () diff --git a/src/Cell.h b/src/Cell.h --- a/src/Cell.h +++ b/src/Cell.h @@ -28,8 +28,9 @@ #include "ArrayN.h" #include "oct-alloc.h" #include "str-vec.h" +#include "ov.h" -#include "oct-obj.h" +class octave_value_list; class OCTINTERP_API @@ -43,12 +44,7 @@ Cell (const octave_value& val) : ArrayN (dim_vector (1, 1), val) { } - Cell (const octave_value_list& ovl) - : ArrayN (dim_vector (1, ovl.length ())) - { - for (octave_idx_type i = 0; i < ovl.length (); i++) - elem (i) = ovl (i); - } + Cell (const octave_value_list& ovl); Cell (octave_idx_type n, octave_idx_type m, const octave_value& val = resize_fill_value ()) @@ -77,15 +73,15 @@ Cell index (const octave_value_list& idx, bool resize_ok = false) const; - Cell index (idx_vector& i, int resize_ok = 0, + Cell index (const idx_vector& i, bool resize_ok = 0, const octave_value& rfv = resize_fill_value ()) const { return Cell (ArrayN::index (i, resize_ok, rfv)); } - Cell index (idx_vector& i, idx_vector& j, int resize_ok = 0, + Cell index (const idx_vector& i, idx_vector& j, bool resize_ok = 0, const octave_value& rfv = resize_fill_value ()) const { return Cell (ArrayN::index (i, j, resize_ok, rfv)); } - Cell index (Array& ra_idx, int resize_ok = 0, + Cell index (const Array& ra_idx, bool resize_ok = 0, const octave_value& rfv = resize_fill_value ()) const { return Cell (ArrayN::index (ra_idx, resize_ok, rfv)); } diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,22 @@ +2009-01-23 Jaroslav Hajek + + * gripes.cc (gripe_indexed_cs_list, gripe_invalid_inquiry_subscript): + New functions. + * gripes.h: Declare them. + * pt-idx.cc: Remove definitions of the above funcs. + * ov-cell.cc (octave_cell::subsasgn): Remove dead branch. + * ov-struct.cc (octave_struct::subsasgn): Remove dead branch. + * ov-cs-list.cc (octave_cs_list::octave_cs_list (const Cell&)): + Optimize. + +2009-01-22 Jaroslav Hajek + + * Cell.h (Cell::Cell (octave_value_list)): Only declare. + (Cell::index (*)): Change resize_ok type to bool. + * Cell.cc (Cell::Cell (octave_value_list)): Redefine. + * oct-obj.h, oct-obj.cc: Change octave_value_list::data to + Cell variable, reflect changes. + 2009-01-22 John W. Eaton * help.cc (do_which (std::ostream&, const std::string&), Fwhich): diff --git a/src/gripes.cc b/src/gripes.cc --- a/src/gripes.cc +++ b/src/gripes.cc @@ -251,6 +251,18 @@ srctype, desttype); } +void +gripe_invalid_inquiry_subscript (void) +{ + error ("invalid dimension inquiry of a non-existent value"); +} + +void +gripe_indexed_cs_list (void) +{ + error ("a cs-list cannot be further indexed"); +} + /* ;;; Local Variables: *** ;;; mode: C++ *** diff --git a/src/gripes.h b/src/gripes.h --- a/src/gripes.h +++ b/src/gripes.h @@ -131,6 +131,12 @@ extern OCTINTERP_API void gripe_library_execution_error (void); +extern OCTINTERP_API void +gripe_invalid_inquiry_subscript (void); + +extern OCTINTERP_API void +gripe_indexed_cs_list (void); + #endif /* diff --git a/src/oct-obj.cc b/src/oct-obj.cc --- a/src/oct-obj.cc +++ b/src/oct-obj.cc @@ -29,32 +29,9 @@ #include "oct-obj.h" #include "Cell.h" -octave_value_list::octave_value_list (const Cell& tc) - : data (tc.numel ()) -{ - for (octave_idx_type i = 0; i < tc.numel (); i++) - data[i] = tc(i); -} - octave_allocator octave_value_list::allocator (sizeof (octave_value_list)); -void -octave_value_list::resize (octave_idx_type n, const octave_value& val) -{ - octave_idx_type len = length (); - - if (n > len) - { - data.resize (n); - - for (octave_idx_type i = len; i < n; i++) - data[i] = val; - } - else if (n < len) - data.resize (n); -} - octave_value_list& octave_value_list::prepend (const octave_value& val) { @@ -247,8 +224,15 @@ octave_value_list::make_storable_values (void) { octave_idx_type len = length (); + const Array& cdata = data; + for (octave_idx_type i = 0; i < len; i++) - data[i].make_storable_value (); + { + // This is optimized so that we don't force a copy unless necessary. + octave_value tmp = cdata(i).storable_value (); + if (! tmp.is_copy_of (cdata (i))) + data(i) = tmp; + } } /* diff --git a/src/oct-obj.h b/src/oct-obj.h --- a/src/oct-obj.h +++ b/src/oct-obj.h @@ -29,9 +29,10 @@ #include "oct-alloc.h" #include "str-vec.h" +#include "Array.h" #include "ov.h" -class Cell; +#include "Cell.h" class OCTINTERP_API @@ -43,12 +44,16 @@ : data () { } octave_value_list (octave_idx_type n, const octave_value& val) - : data (n, val) { } + : data (dim_vector (1, n), val) { } octave_value_list (const octave_value& tc) : data (1, tc) { } - octave_value_list (const Cell& tc); + octave_value_list (const Array& d) + : data (d.reshape (dim_vector (1, d.numel ()))) { } + + octave_value_list (const Cell& tc) + : data (tc.reshape (dim_vector (1, tc.numel ()))) { } octave_value_list (const octave_value_list& obj) : data (obj.data), names (obj.names) { } @@ -86,19 +91,24 @@ return *this; } + Array array_value (void) const { return data; } + + Cell cell_value (void) const { return array_value (); } + // Assignment will resize on range errors. octave_value& operator () (octave_idx_type n) { return elem (n); } octave_value operator () (octave_idx_type n) const { return elem (n); } - octave_idx_type length (void) const { return data.size (); } + octave_idx_type length (void) const { return data.length (); } bool empty (void) const { return length () == 0; } void resize (octave_idx_type n) { data.resize (n); } - void resize (octave_idx_type n, const octave_value& val); + void resize (octave_idx_type n, const octave_value& val) + { data.resize (n, val); } octave_value_list& prepend (const octave_value& val); @@ -109,6 +119,10 @@ octave_value_list& reverse (void); octave_value_list + slice (octave_idx_type offset, octave_idx_type len) const + { return data.index (idx_vector (offset, offset + len)); } + + octave_value_list splice (octave_idx_type offset, octave_idx_type len, const octave_value_list& lst = octave_value_list ()) const; @@ -130,7 +144,7 @@ static octave_allocator allocator; - std::vector data; + Array data; // This list of strings can be used to tag each element of data with // a name. By default, it is empty. @@ -152,26 +166,16 @@ octave_value_list (octave_idx_type n); - octave_value_list (const Array& d); - octave_value& elem (octave_idx_type n) { - static Matrix empty_matrix; + if (n >= length ()) + resize (n + 1); - if (n >= length ()) - resize (n+1, empty_matrix); - - return data[n]; + return data(n); } octave_value elem (octave_idx_type n) const - { -#if defined (BOUNDS_CHECKING) - return data.at (n); -#else - return data[n]; -#endif - } + { return data(n); } }; #endif diff --git a/src/ov-cell.cc b/src/ov-cell.cc --- a/src/ov-cell.cc +++ b/src/ov-cell.cc @@ -48,6 +48,7 @@ #include "ov-scalar.h" #include "pr-output.h" #include "ov-scalar.h" +#include "gripes.h" #include "ls-oct-ascii.h" #include "ls-oct-binary.h" @@ -140,7 +141,7 @@ if (tcell.length () == 1) retval = tcell(0,0); else - retval = octave_value (octave_value_list (tcell), auto_add); + retval = octave_value (octave_value_list (tcell), true); } } break; @@ -227,40 +228,12 @@ std::string next_type = type.substr (1); - if (rhs.is_cs_list ()) - { - const octave_value_list rhsl = rhs.list_value (); - if (tmpc.numel () == rhsl.length ()) - { - for (octave_idx_type k = 0; k < tmpc.numel () && ! error_state; k++) - { - octave_value tmp = tmpc (k); - if (! tmp.is_defined () || tmp.is_zero_by_zero ()) - { - tmp = octave_value::empty_conv (next_type, rhs); - tmp.make_unique (); // probably a no-op. - } - else - // optimization: ignore the copy still stored inside our array and in tmpc. - tmp.make_unique (2); - - tmpc(k) = tmp.subsasgn (next_type, next_idx, rhsl(k)); - } - - t_rhs = octave_value (octave_value_list (tmpc), true); - } - else - error ("invalid cs-list length in assignment"); - } - else if (tmpc.numel () == 1) + if (tmpc.numel () == 1) { octave_value tmp = tmpc(0); if (! tmp.is_defined () || tmp.is_zero_by_zero ()) - { - tmp = octave_value::empty_conv (type.substr (1), rhs); - tmp.make_unique (); // probably a no-op. - } + tmp = octave_value::empty_conv (type.substr (1), rhs); else // optimization: ignore the copy still stored inside our array and in tmpc. tmp.make_unique (2); @@ -269,7 +242,7 @@ t_rhs = tmp.subsasgn (next_type, next_idx, rhs); } else - error ("invalid assignment to cs-list outside multiple assignment."); + gripe_indexed_cs_list (); } } break; diff --git a/src/ov-cs-list.cc b/src/ov-cs-list.cc --- a/src/ov-cs-list.cc +++ b/src/ov-cs-list.cc @@ -39,14 +39,8 @@ DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_cs_list, "cs-list", "cs-list"); octave_cs_list::octave_cs_list (const Cell& c) - : octave_base_value (), lst () + : octave_base_value (), lst (c) { - octave_idx_type n = c.length (); - - lst.resize (n); - - for (octave_idx_type i = 0; i < n; i++) - lst(i) = c(i); } /* diff --git a/src/ov-struct.cc b/src/ov-struct.cc --- a/src/ov-struct.cc +++ b/src/ov-struct.cc @@ -301,32 +301,7 @@ // FIXME: better code reuse? cf. octave_cell::subsasgn and the case below. if (! error_state) { - if (rhs.is_cs_list ()) - { - octave_value_list rhsl = rhs.list_value (); - if (tmpc.numel () == rhsl.length ()) - { - for (octave_idx_type k = 0; k < tmpc.numel () && ! error_state; k++) - { - octave_value tmp = tmpc (k); - if (! tmp.is_defined () || tmp.is_zero_by_zero ()) - { - tmp = octave_value::empty_conv (next_type, rhs); - tmp.make_unique (); // probably a no-op. - } - else - // optimization: ignore the copy still stored inside our map and in tmpc. - tmp.make_unique (2); - - tmpc(k) = tmp.subsasgn (next_type, next_idx, rhsl(k)); - } - - t_rhs = octave_value (octave_value_list (tmpc), true); - } - else - error ("invalid cs-list length in assignment"); - } - else if (tmpc.numel () == 1) + if (tmpc.numel () == 1) { octave_value tmp = tmpc(0); @@ -343,7 +318,7 @@ t_rhs = tmp.subsasgn (next_type, next_idx, rhs); } else - error ("invalid assignment to cs-list outside multiple assignment."); + gripe_indexed_cs_list (); } } else @@ -373,32 +348,7 @@ // FIXME: better code reuse? if (! error_state) { - if (rhs.is_cs_list ()) - { - octave_value_list rhsl = rhs.list_value (); - if (tmpc.numel () == rhsl.length ()) - { - for (octave_idx_type k = 0; k < tmpc.numel () && ! error_state; k++) - { - octave_value tmp = tmpc (k); - if (! tmp.is_defined () || tmp.is_zero_by_zero ()) - { - tmp = octave_value::empty_conv (next_type, rhs); - tmp.make_unique (); // probably a no-op. - } - else - // optimization: ignore the copy still stored inside our map. - tmp.make_unique (1); - - tmpc(k) = tmp.subsasgn (next_type, next_idx, rhsl(k)); - } - - t_rhs = octave_value (octave_value_list (tmpc), true); - } - else - error ("invalid cs-list length in assignment"); - } - else if (tmpc.numel () == 1) + if (tmpc.numel () == 1) { octave_value tmp = tmpc(0); @@ -415,7 +365,7 @@ t_rhs = tmp.subsasgn (next_type, next_idx, rhs); } else - error ("invalid assignment to cs-list outside multiple assignment."); + gripe_indexed_cs_list (); } } break; diff --git a/src/pt-idx.cc b/src/pt-idx.cc --- a/src/pt-idx.cc +++ b/src/pt-idx.cc @@ -39,6 +39,7 @@ #include "pt-walk.h" #include "utils.h" #include "variables.h" +#include "gripes.h" // Index expressions. @@ -263,18 +264,6 @@ return m; } -static void -gripe_invalid_inquiry_subscript (void) -{ - error ("invalid dimension inquiry of a non-existent value"); -} - -static void -gripe_indexed_cs_list (void) -{ - error ("a cs-list cannot be further indexed"); -} - octave_value_list tree_index_expression::rvalue (int nargout) {