Mercurial > hg > octave-nkf
diff liboctave/Array.cc @ 8523:ad3afaaa19c1
implement non-copying contiguous range indexing
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Thu, 15 Jan 2009 07:22:24 +0100 |
parents | 124dd27bedae |
children | 937921654627 |
line wrap: on
line diff
--- a/liboctave/Array.cc +++ b/liboctave/Array.cc @@ -3,7 +3,7 @@ Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, 2005, 2006, 2007 John W. Eaton -Copyright (C) 2008 Jaroslav Hajek <highegg@gmail.com> +Copyright (C) 2008, 2009 Jaroslav Hajek <highegg@gmail.com> This file is part of Octave. @@ -47,7 +47,8 @@ template <class T> Array<T>::Array (const Array<T>& a, const dim_vector& dv) - : rep (a.rep), dimensions (dv) + : rep (a.rep), dimensions (dv), + slice_data (a.slice_data), slice_len (a.slice_len) { rep->count++; @@ -76,6 +77,8 @@ rep->count++; dimensions = a.dimensions; + slice_data = a.slice_data; + slice_len = a.slice_len; } return *this; @@ -680,6 +683,11 @@ template <class T> void fill (const T& val, T *dest) const { do_fill (val, dest, top); } + bool is_cont_range (octave_idx_type& l, + octave_idx_type& u) const + { + return top == 0 && idx[0].is_cont_range (dim[0], l, u); + } }; // Helper class for multi-d recursive resizing @@ -758,9 +766,7 @@ if (i.is_colon ()) { // A(:) produces a shallow copy as a column vector. - retval.dimensions = dim_vector (n, 1); - rep->count++; - retval.rep = rep; + retval = Array<T> (*this, dim_vector (n, 1)); } else if (i.extent (n) != n) { @@ -797,12 +803,19 @@ rd = dim_vector (1, il); } - // Don't use resize here to avoid useless initialization for POD - // types. - retval = Array<T> (rd); + octave_idx_type l, u; + if (il != 0 && i.is_cont_range (n, l, u)) + // If suitable, produce a shallow slice. + retval = Array<T> (*this, rd, l, u); + else + { + // Don't use resize here to avoid useless initialization for POD + // types. + retval = Array<T> (rd); - if (il != 0) - i.index (data (), n, retval.fortran_vec ()); + if (il != 0) + i.index (data (), n, retval.fortran_vec ()); + } } return retval; @@ -830,18 +843,30 @@ { octave_idx_type n = numel (), il = i.length (r), jl = j.length (c); - // Don't use resize here to avoid useless initialization for POD types. - retval = Array<T> (dim_vector (il, jl)); - idx_vector ii (i); - const T* src = data (); - T *dest = retval.fortran_vec (); + if (ii.maybe_reduce (r, j, c)) + { + octave_idx_type l, u; + if (ii.length () > 0 && ii.is_cont_range (n, l, u)) + // If suitable, produce a shallow slice. + retval = Array<T> (*this, dim_vector (il, jl), l, u); + else + { + // Don't use resize here to avoid useless initialization for POD types. + retval = Array<T> (dim_vector (il, jl)); - if (ii.maybe_reduce (r, j, c)) - ii.index (src, n, dest); + ii.index (data (), n, retval.fortran_vec ()); + } + } else { + // Don't use resize here to avoid useless initialization for POD types. + retval = Array<T> (dim_vector (il, jl)); + + const T* src = data (); + T *dest = retval.fortran_vec (); + for (octave_idx_type k = 0; k < jl; k++) dest += i.index (src + r * j.xelem (k), r, dest); } @@ -898,14 +923,21 @@ for (int i = 0; i < ial; i++) rdv(i) = ia(i).length (dv(i)); rdv.chop_trailing_singletons (); - // Don't use resize here to avoid useless initialization for POD types. - retval = Array<T> (rdv); - // Prepare for recursive indexing rec_index_helper rh (dv, ia); - // Do it. - rh.index (data (), retval.fortran_vec ()); + octave_idx_type l, u; + if (rh.is_cont_range (l, u)) + // If suitable, produce a shallow slice. + retval = Array<T> (*this, rdv, l, u); + else + { + // Don't use resize here to avoid useless initialization for POD types. + retval = Array<T> (rdv); + + // Do it. + rh.index (data (), retval.fortran_vec ()); + } } } @@ -1842,7 +1874,7 @@ { make_unique (); - return rep->data; + return slice_data; } template <class T> @@ -2174,10 +2206,12 @@ void Array<T>::print_info (std::ostream& os, const std::string& prefix) const { - os << prefix << "rep address: " << rep << "\n" - << prefix << "rep->len: " << rep->len << "\n" - << prefix << "rep->data: " << static_cast<void *> (rep->data) << "\n" - << prefix << "rep->count: " << rep->count << "\n"; + os << prefix << "rep address: " << rep << '\n' + << prefix << "rep->len: " << rep->len << '\n' + << prefix << "rep->data: " << static_cast<void *> (rep->data) << '\n' + << prefix << "rep->count: " << rep->count << '\n' + << prefix << "slice_data: " << static_cast<void *> (slice_data) << '\n' + << prefix << "slice_len: " << slice_len << '\n'; // 2D info: //