# HG changeset patch # User Jaroslav Hajek # Date 1222259600 -7200 # Node ID e53aee152c56531a63b2e67e724df20810f10870 # Parent 45b534558b2276b9fc85c5f1871102e199942acf * * * * * * add missing null matrix checks * * * use static member instead of bool flag to mark null matrices * * * fix argument types order in OPERATORS/op-fm-fm.cc diff --git a/liboctave/Array-i.cc b/liboctave/Array-i.cc --- a/liboctave/Array-i.cc +++ b/liboctave/Array-i.cc @@ -68,6 +68,98 @@ INSTANTIATE_ARRAY_AND_ASSIGN (octave_uint32, OCTAVE_API); INSTANTIATE_ARRAY_AND_ASSIGN (octave_uint64, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int8, float, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int16, float, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int32, float, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int64, float, OCTAVE_API); + +INSTANTIATE_ARRAY_ASSIGN (octave_uint8, float, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint16, float, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint32, float, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint64, float, OCTAVE_API); + +INSTANTIATE_ARRAY_ASSIGN (octave_int8, double, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int16, double, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int32, double, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int64, double, OCTAVE_API); + +INSTANTIATE_ARRAY_ASSIGN (octave_uint8, double, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint16, double, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint32, double, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint64, double, OCTAVE_API); + +INSTANTIATE_ARRAY_ASSIGN (octave_int8, octave_int16, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int8, octave_int32, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int8, octave_int64, OCTAVE_API); + +INSTANTIATE_ARRAY_ASSIGN (octave_int8, octave_uint8, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int8, octave_uint16, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int8, octave_uint32, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int8, octave_uint64, OCTAVE_API); + +INSTANTIATE_ARRAY_ASSIGN (octave_int16, octave_int8, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int16, octave_int32, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int16, octave_int64, OCTAVE_API); + +INSTANTIATE_ARRAY_ASSIGN (octave_int16, octave_uint8, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int16, octave_uint16, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int16, octave_uint32, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int16, octave_uint64, OCTAVE_API); + +INSTANTIATE_ARRAY_ASSIGN (octave_int32, octave_int8, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int32, octave_int16, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int32, octave_int64, OCTAVE_API); + +INSTANTIATE_ARRAY_ASSIGN (octave_int32, octave_uint8, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int32, octave_uint16, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int32, octave_uint32, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int32, octave_uint64, OCTAVE_API); + +INSTANTIATE_ARRAY_ASSIGN (octave_int64, octave_int8, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int64, octave_int16, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int64, octave_int32, OCTAVE_API); + +INSTANTIATE_ARRAY_ASSIGN (octave_int64, octave_uint8, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int64, octave_uint16, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int64, octave_uint32, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_int64, octave_uint64, OCTAVE_API); + +INSTANTIATE_ARRAY_ASSIGN (octave_uint8, octave_int8, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint8, octave_int16, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint8, octave_int32, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint8, octave_int64, OCTAVE_API); + +INSTANTIATE_ARRAY_ASSIGN (octave_uint8, octave_uint16, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint8, octave_uint32, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint8, octave_uint64, OCTAVE_API); + +INSTANTIATE_ARRAY_ASSIGN (octave_uint16, octave_int8, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint16, octave_int16, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint16, octave_int32, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint16, octave_int64, OCTAVE_API); + +INSTANTIATE_ARRAY_ASSIGN (octave_uint16, octave_uint8, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint16, octave_uint32, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint16, octave_uint64, OCTAVE_API); + +INSTANTIATE_ARRAY_ASSIGN (octave_uint32, octave_int8, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint32, octave_int16, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint32, octave_int32, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint32, octave_int64, OCTAVE_API); + +INSTANTIATE_ARRAY_ASSIGN (octave_uint32, octave_uint8, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint32, octave_uint16, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint32, octave_uint64, OCTAVE_API); + +INSTANTIATE_ARRAY_ASSIGN (octave_uint64, octave_int8, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint64, octave_int16, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint64, octave_int32, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint64, octave_int64, OCTAVE_API); + +INSTANTIATE_ARRAY_ASSIGN (octave_uint64, octave_uint8, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint64, octave_uint16, OCTAVE_API); +INSTANTIATE_ARRAY_ASSIGN (octave_uint64, octave_uint32, OCTAVE_API); + #include "Array2.h" template class OCTAVE_API Array2; diff --git a/liboctave/Array.cc b/liboctave/Array.cc --- a/liboctave/Array.cc +++ b/liboctave/Array.cc @@ -38,6 +38,8 @@ #include "Array-util.h" #include "idx-vector.h" #include "lo-error.h" + +template const Array Array::null_matrix (dim_vector (0, 0)); // One dimensional array class. Handles the reference counting for // all the derived classes. @@ -3104,7 +3106,7 @@ if (idx_i && idx_j) { - if (rhs_nr == 0 && rhs_nc == 0) + if (rhs.is_null_matrix ()) { lhs.maybe_delete_elements (idx_i, idx_j); } @@ -3213,7 +3215,7 @@ if (idx_i) { - if (rhs_nr == 0 && rhs_nc == 0) + if (rhs.is_null_matrix ()) { lhs.maybe_delete_elements (idx_i); } @@ -3263,7 +3265,7 @@ if (idx_i) { - if (rhs_nr == 0 && rhs_nc == 0) + if (rhs.is_null_matrix ()) lhs.maybe_delete_elements (idx_i); else { @@ -3281,7 +3283,7 @@ if (idx_i) { - if (rhs_nr == 0 && rhs_nc == 0) + if (rhs.is_null_matrix ()) lhs.maybe_delete_elements (idx_i); else { @@ -3303,7 +3305,7 @@ if (idx_i) { - if (rhs_nr == 0 && rhs_nc == 0) + if (rhs.is_null_matrix ()) lhs.maybe_delete_elements (idx_i); else if (len == 0) { @@ -3391,7 +3393,7 @@ Array idx = conv_to_array (idx_vex, n_idx); - if (rhs_dims_len == 2 && rhs_dims(0) == 0 && rhs_dims(1) == 0) + if (rhs.is_null_matrix ()) { lhs.maybe_delete_elements (idx, rfv); } diff --git a/liboctave/Array.h b/liboctave/Array.h --- a/liboctave/Array.h +++ b/liboctave/Array.h @@ -65,11 +65,14 @@ octave_idx_type len; int count; - ArrayRep (T *d, octave_idx_type l) : data (d), len (l), count (1) { } + ArrayRep (T *d, octave_idx_type l) + : data (d), len (l), count (1) { } - ArrayRep (void) : data (0), len (0), count (1) { } + ArrayRep (void) + : data (0), len (0), count (1) { } - explicit ArrayRep (octave_idx_type n) : data (new T [n]), len (n), count (1) { } + explicit ArrayRep (octave_idx_type n) + : data (new T [n]), len (n), count (1) { } explicit ArrayRep (octave_idx_type n, const T& val) : data (new T [n]), len (n), count (1) @@ -197,12 +200,27 @@ fill (val); } + static const Array null_matrix; + + bool is_null_matrix (void) const { return rep == null_matrix.rep; } + + void mark_as_null_matrix (void) { *this = null_matrix; } + + void maybe_unmark_null_matrix (void) + { + if (is_null_matrix ()) + *this = Array (); + } + // Type conversion case. + // Preserves null matrices template Array (const Array& a) : rep (new typename Array::ArrayRep (coerce (a.data (), a.length ()), a.length ())), dimensions (a.dimensions), idx (0), idx_count (0) { + if (a.is_null_matrix ()) + mark_as_null_matrix (); } // No type conversion case. diff --git a/liboctave/CMatrix.cc b/liboctave/CMatrix.cc --- a/liboctave/CMatrix.cc +++ b/liboctave/CMatrix.cc @@ -248,12 +248,8 @@ // Complex Matrix class ComplexMatrix::ComplexMatrix (const Matrix& a) - : MArray2 (a.rows (), a.cols ()) -{ - for (octave_idx_type j = 0; j < cols (); j++) - for (octave_idx_type i = 0; i < rows (); i++) - elem (i, j) = a.elem (i, j); -} + : MArray2 (a) +{ } ComplexMatrix::ComplexMatrix (const RowVector& rv) : MArray2 (1, rv.length (), 0.0) diff --git a/liboctave/Sparse.cc b/liboctave/Sparse.cc --- a/liboctave/Sparse.cc +++ b/liboctave/Sparse.cc @@ -43,6 +43,8 @@ #include "Sparse.h" #include "sparse-sort.h" #include "oct-spparms.h" + +template const Sparse Sparse::null_matrix (dim_vector (0, 0)); template T& @@ -218,6 +220,9 @@ for (octave_idx_type i = 0; i < nc + 1; i++) xcidx (i) = a.cidx (i); } + + if (a.is_null_matrix ()) + mark_as_null_matrix (); } template @@ -567,6 +572,9 @@ } xcidx(j+1) = ii; } + + if (a.is_null_matrix ()) + mark_as_null_matrix (); } template @@ -603,6 +611,9 @@ xcidx(j+1) = ii; } } + + if (a.is_null_matrix ()) + mark_as_null_matrix (); } template @@ -2866,7 +2877,7 @@ if (idx_i && idx_j) { - if (rhs_nr == 0 && rhs_nc == 0) + if (rhs.is_null_matrix ()) { lhs.maybe_delete_elements (idx_i, idx_j); } @@ -3227,7 +3238,7 @@ if (idx_i) { - if (rhs_nr == 0 && rhs_nc == 0) + if (rhs.is_null_matrix ()) { if (n != 0 && (lhs_nr != 0 || lhs_nc != 0)) lhs.maybe_delete_elements (idx_i); @@ -3265,7 +3276,7 @@ if (idx_i) { - if (rhs_nr == 0 && rhs_nc == 0) + if (rhs.is_null_matrix ()) lhs.maybe_delete_elements (idx_i); else if (! assign1 (lhs, rhs)) retval = 0; @@ -3278,7 +3289,7 @@ if (idx_i) { - if (rhs_nr == 0 && rhs_nc == 0) + if (rhs.is_null_matrix ()) lhs.maybe_delete_elements (idx_i); else if (! assign1 (lhs, rhs)) retval = 0; @@ -3297,7 +3308,7 @@ if (idx_i) { - if (rhs_nr == 0 && rhs_nc == 0) + if (rhs.is_null_matrix ()) lhs.maybe_delete_elements (idx_i); else if (len == 0) { diff --git a/liboctave/Sparse.h b/liboctave/Sparse.h --- a/liboctave/Sparse.h +++ b/liboctave/Sparse.h @@ -193,6 +193,18 @@ Sparse (octave_idx_type nr, octave_idx_type nc, octave_idx_type nz) : rep (new typename Sparse::SparseRep (nr, nc, nz)), dimensions (dim_vector (nr, nc)), idx (0), idx_count (0) { } + + static const Sparse null_matrix; + + bool is_null_matrix (void) const { return rep == null_matrix.rep; } + + void mark_as_null_matrix (void) { *this = null_matrix; } + + void maybe_unmark_null_matrix (void) + { + if (is_null_matrix ()) + *this = Sparse (); + } // Type conversion case. template Sparse (const Sparse& a); diff --git a/src/OPERATORS/op-str-m.cc b/src/OPERATORS/op-str-m.cc --- a/src/OPERATORS/op-str-m.cc +++ b/src/OPERATORS/op-str-m.cc @@ -36,12 +36,18 @@ { CAST_BINOP_ARGS (octave_char_matrix_str&, const octave_matrix&); - octave_value tmp - = v2.convert_to_str_internal (false, false, - a1.is_sq_string () ? '\'' : '"'); + if (v2.is_null_matrix ()) + // FIXME: why the explicit constructor? + v1.assign (idx, MArray2 (charMatrix::null_matrix)); + else + { + octave_value tmp + = v2.convert_to_str_internal (false, false, + a1.is_sq_string () ? '\'' : '"'); - if (! error_state) - v1.assign (idx, tmp.char_matrix_value ()); + if (! error_state) + v1.assign (idx, tmp.char_matrix_value ()); + } return octave_value (); } diff --git a/src/oct-map.cc b/src/oct-map.cc --- a/src/oct-map.cc +++ b/src/oct-map.cc @@ -290,7 +290,7 @@ { std::string k = t_keys[i]; - map[k] = contents(k).assign (idx, Cell()); + map[k] = contents(k).assign (idx, Cell::null_matrix); if (error_state) break; diff --git a/src/ov-base-mat.cc b/src/ov-base-mat.cc --- a/src/ov-base-mat.cc +++ b/src/ov-base-mat.cc @@ -190,22 +190,6 @@ } template -void -octave_base_matrix::assign (const octave_value_list& idx, const MT& rhs) -{ - octave_idx_type len = idx.length (); - - for (octave_idx_type i = 0; i < len; i++) - matrix.set_index (idx(i).index_vector ()); - - ::assign (matrix, rhs, MT::resize_fill_value ()); - - - // Invalidate the matrix type - typ.invalidate_type (); -} - -template octave_value octave_base_matrix::resize (const dim_vector& dv, bool fill) const { diff --git a/src/ov-base-mat.h b/src/ov-base-mat.h --- a/src/ov-base-mat.h +++ b/src/ov-base-mat.h @@ -86,7 +86,19 @@ octave_value do_index_op (const octave_value_list& idx, bool resize_ok = false); - void assign (const octave_value_list& idx, const MT& rhs); + template + void assign (const octave_value_list& idx, const RT& rhs) + { + octave_idx_type len = idx.length (); + + for (octave_idx_type i = 0; i < len; i++) + matrix.set_index (idx(i).index_vector ()); + + ::assign (matrix, rhs, MT::resize_fill_value ()); + + // Invalidate the matrix type + typ.invalidate_type (); + } dim_vector dims (void) const { return matrix.dims (); } @@ -124,9 +136,13 @@ bool is_constant (void) const { return true; } + bool is_null_matrix (void) const { return matrix.is_null_matrix (); } + bool is_true (void) const; bool print_as_scalar (void) const; + + void maybe_unmark_null_matrix (void) { matrix.maybe_unmark_null_matrix (); }; void print (std::ostream& os, bool pr_as_read_syntax = false) const; diff --git a/src/ov-base.cc b/src/ov-base.cc --- a/src/ov-base.cc +++ b/src/ov-base.cc @@ -1106,7 +1106,10 @@ if (f) { - f (*this, idx.front (), rhs.get_rep ()); + octave_value_list t1 = idx.front (); + const octave_base_value& t2 = rhs.get_rep (); + // f (*this, idx.front (), rhs.get_rep ()); + f (*this, t1, t2); done = (! error_state); } diff --git a/src/ov-base.h b/src/ov-base.h --- a/src/ov-base.h +++ b/src/ov-base.h @@ -233,6 +233,8 @@ virtual bool is_list (void) const { return false; } virtual bool is_magic_colon (void) const { return false; } + + virtual bool is_null_matrix (void) const { return false; } virtual bool is_all_va_args (void) const { return false; } @@ -433,6 +435,8 @@ virtual octave_value convert_to_str_internal (bool pad, bool force, char type) const; + virtual void maybe_unmark_null_matrix (void) { }; + virtual void convert_to_row_or_column_vector (void); virtual bool print_as_scalar (void) const { return false; } diff --git a/src/ov-cell.cc b/src/ov-cell.cc --- a/src/ov-cell.cc +++ b/src/ov-cell.cc @@ -229,11 +229,10 @@ if (t_rhs.is_cell ()) octave_base_matrix::assign (i, t_rhs.cell_value ()); - else - if (t_rhs.is_empty ()) - octave_base_matrix::assign (i, Cell()); - else - octave_base_matrix::assign (i, Cell (t_rhs)); + else if (t_rhs.is_null_matrix ()) + octave_base_matrix::assign (i, Cell::null_matrix); + else + octave_base_matrix::assign (i, Cell (t_rhs)); if (! error_state) { @@ -263,7 +262,7 @@ octave_base_matrix::assign (i, tmp_cell); } else - octave_base_matrix::assign (i, Cell (t_rhs)); + octave_base_matrix::assign (i, Cell (t_rhs.non_null_matrix_value ())); if (! error_state) { diff --git a/src/ov-re-mat.h b/src/ov-re-mat.h --- a/src/ov-re-mat.h +++ b/src/ov-re-mat.h @@ -99,6 +99,8 @@ bool is_double_type (void) const { return true; } bool is_float_type (void) const { return true; } + + bool is_null_matrix (void) const { return matrix.is_null_matrix (); } bool valid_as_scalar_index (void) const; diff --git a/src/ov-struct.cc b/src/ov-struct.cc --- a/src/ov-struct.cc +++ b/src/ov-struct.cc @@ -344,7 +344,7 @@ } else { - if (t_rhs.is_empty()) + if (t_rhs.is_null_matrix ()) { map.maybe_delete_elements (idx.front()); @@ -385,7 +385,7 @@ map.assign (key, tmp_cell); } else - map.assign (key, t_rhs); + map.assign (key, t_rhs.non_null_matrix_value ()); if (! error_state) { diff --git a/src/ov.cc b/src/ov.cc --- a/src/ov.cc +++ b/src/ov.cc @@ -1153,7 +1153,20 @@ octave_value::assign (assign_op op, const octave_value& rhs) { if (op == op_asn_eq) - operator = (rhs); + { + // We have a special case for null matrix values here so that + // + // x(idx) = []; + // + // will delete elements, but + // + // rhs = []; + // x(idx) = rhs; + // + // will not. + + operator = (rhs.non_null_matrix_value ()); + } else { // FIXME -- only do the following stuff if we can't find @@ -1294,6 +1307,14 @@ octave_value::list_value (void) const { return rep->list_value (); +} + +octave_value +octave_value::non_null_matrix_value (void) const +{ + octave_value ret = *this; + ret.rep -> maybe_unmark_null_matrix (); + return ret; } static dim_vector diff --git a/src/ov.h b/src/ov.h --- a/src/ov.h +++ b/src/ov.h @@ -489,6 +489,9 @@ bool is_magic_colon (void) const { return rep->is_magic_colon (); } + bool is_null_matrix (void) const + { return rep->is_null_matrix (); } + // Are any or all of the elements in this constant nonzero? octave_value all (int dim = 0) const @@ -786,6 +789,8 @@ octave_fcn_inline *fcn_inline_value (bool silent = false); octave_value_list list_value (void) const; + + octave_value non_null_matrix_value (void) const; ColumnVector column_vector_value (bool frc_str_conv = false, bool frc_vec_conv = false) const; diff --git a/src/parse.y b/src/parse.y --- a/src/parse.y +++ b/src/parse.y @@ -161,6 +161,10 @@ // Build a constant. static tree_constant * make_constant (int op, token *tok_val); + +// Build a null matrix constant. +static tree_constant * +make_null_matrix (void); // Build a function handle. static tree_fcn_handle * @@ -576,17 +580,11 @@ ; matrix : '[' ']' - { - $$ = new tree_constant (octave_value (Matrix ())); - lexer_flags.looking_at_matrix_or_assign_lhs = false; - lexer_flags.pending_local_variables.clear (); - } + { $$ = make_null_matrix (); } + | '[' ',' ']' + { $$ = make_null_matrix (); } | '[' ';' ']' - { - $$ = new tree_constant (octave_value (Matrix ())); - lexer_flags.looking_at_matrix_or_assign_lhs = false; - lexer_flags.pending_local_variables.clear (); - } + { $$ = make_null_matrix (); } | '[' matrix_rows ']' { $$ = finish_matrix ($2); @@ -1719,11 +1717,16 @@ case DQ_STRING: case SQ_STRING: { - std::string txt = tok_val->text (); + std::string txt = tok_val->text (); + + charMatrix chm (txt); + + if (chm.is_empty ()) + chm.mark_as_null_matrix (); char delim = op == DQ_STRING ? '"' : '\''; - octave_value tmp (txt, delim); + octave_value tmp (chm, true, delim); retval = new tree_constant (tmp, l, c); if (op == DQ_STRING) @@ -1741,6 +1744,20 @@ } return retval; +} + +// Make a null matrix constant. + +tree_constant * +make_null_matrix (void) +{ + lexer_flags.looking_at_matrix_or_assign_lhs = false; + lexer_flags.pending_local_variables.clear (); + + Matrix m; + m.mark_as_null_matrix (); + + return new tree_constant (m); } // Make a function handle.