Mercurial > octave-dspies
comparison liboctave/array/Array.h @ 19009:8d47ce2053f2 draft
Added safety checks to Array::xelem
There's no reason to have a method which never checks invariants, ever. Added
debugging checks to Array::xelem to help catch and debug out-of-bounds errors
and reference overlap
* configure.ac: Added configuration option for uniqueness-checking with xelem
* jit-typeinfo.cc (octave_jit_paren_scalar): Call const Array::xelem rather
than Array::xelem
* Array-util.h, Array-util.cc (check_out_of_range): Extract common pattern to
method
(check_index): Methods to check index is in-bounds
(compute_index): Added bool parameter check. does not check bounds when check
is false and BOUNDS_CHECKING is off
* Array.h, Array.cc (xelem): Use methods from Array-util.h to compute indices
(is_unique): Check if this is the only reference to data
* CmplxQR.cc, dbleQR.cc, fCmplxQR.cc, floatQR.cc
(form): Move second assignment to after the call to xelem
* lo-array-gripes.h, lo-array-gripes.cc (gripe_modifying_nonunique): Added
error message for when non-const xelem is called on non-unique array
author | David Spies <dnspies@gmail.com> |
---|---|
date | Mon, 14 Jul 2014 13:07:59 -0600 |
parents | 2e0613dadfee |
children | 3fb030666878 |
comparison
equal
deleted
inserted
replaced
19008:80ca3b05d77c | 19009:8d47ce2053f2 |
---|---|
30 #include <cstddef> | 30 #include <cstddef> |
31 | 31 |
32 #include <algorithm> | 32 #include <algorithm> |
33 #include <iosfwd> | 33 #include <iosfwd> |
34 | 34 |
35 #include "Array-util.h" | |
35 #include "dim-vector.h" | 36 #include "dim-vector.h" |
36 #include "idx-vector.h" | 37 #include "idx-vector.h" |
37 #include "lo-traits.h" | 38 #include "lo-traits.h" |
38 #include "lo-utils.h" | 39 #include "lo-utils.h" |
39 #include "oct-sort.h" | 40 #include "oct-sort.h" |
339 | 340 |
340 octave_idx_type compute_index_unchecked (const Array<octave_idx_type>& ra_idx) | 341 octave_idx_type compute_index_unchecked (const Array<octave_idx_type>& ra_idx) |
341 const | 342 const |
342 { return dimensions.compute_index (ra_idx.data (), ra_idx.length ()); } | 343 { return dimensions.compute_index (ra_idx.data (), ra_idx.length ()); } |
343 | 344 |
344 // No checking, even for multiple references, ever. | 345 // Check for multiple references only if uniqueness-checking is enabled |
345 | 346 // Check for out-of-range only if bounds-checking is enabled |
346 T& xelem (octave_idx_type n) { return slice_data[n]; } | 347 // Otherwise no checking |
347 crefT xelem (octave_idx_type n) const { return slice_data[n]; } | 348 |
349 T& | |
350 xelem (octave_idx_type n) | |
351 { | |
352 #if defined (UNIQUENESS_CHECKING) | |
353 if (!is_unique ()) | |
354 gripe_modifying_nonunique (); | |
355 #endif | |
356 #if defined (BOUNDS_CHECKING) | |
357 check_index_bounds (1, 0, n, slice_len); | |
358 #endif | |
359 return slice_data[n]; | |
360 } | |
361 crefT | |
362 xelem (octave_idx_type n) const | |
363 { | |
364 #if defined (BOUNDS_CHECKING) | |
365 check_index_bounds (1, 0, n, slice_len); | |
366 #endif | |
367 return slice_data[n]; | |
368 } | |
348 | 369 |
349 T& xelem (octave_idx_type i, octave_idx_type j) | 370 T& xelem (octave_idx_type i, octave_idx_type j) |
350 { return xelem (dim1 ()*j+i); } | 371 { return xelem (::compute_index(i, j, dims (), false)); } |
351 crefT xelem (octave_idx_type i, octave_idx_type j) const | 372 crefT xelem (octave_idx_type i, octave_idx_type j) const |
352 { return xelem (dim1 ()*j+i); } | 373 { return xelem (::compute_index(i, j, dims (), false)); } |
353 | 374 |
354 T& xelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) | 375 T& xelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) |
355 { return xelem (i, dim2 ()*k+j); } | 376 { return xelem (::compute_index(i, j, k, dims (), false)); } |
356 crefT xelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) const | 377 crefT xelem (octave_idx_type i, octave_idx_type j, octave_idx_type k) const |
357 { return xelem (i, dim2 ()*k+j); } | 378 { return xelem (::compute_index(i, j, k, dims (), false)); } |
358 | 379 |
359 T& xelem (const Array<octave_idx_type>& ra_idx) | 380 T& xelem (const Array<octave_idx_type>& ra_idx) |
360 { return xelem (compute_index_unchecked (ra_idx)); } | 381 { return xelem (::compute_index(ra_idx, dims (), false)); } |
361 | 382 |
362 crefT xelem (const Array<octave_idx_type>& ra_idx) const | 383 crefT xelem (const Array<octave_idx_type>& ra_idx) const |
363 { return xelem (compute_index_unchecked (ra_idx)); } | 384 { return xelem (::compute_index(ra_idx, dims (), false)); } |
364 | 385 |
365 // FIXME: would be nice to fix this so that we don't unnecessarily force | 386 // FIXME: would be nice to fix this so that we don't unnecessarily force |
366 // a copy, but that is not so easy, and I see no clean way to do it. | 387 // a copy, but that is not so easy, and I see no clean way to do it. |
367 | 388 |
368 T& checkelem (octave_idx_type n); | 389 T& checkelem (octave_idx_type n); |
719 | 740 |
720 void *jit_array_rep (void) const { return rep; } | 741 void *jit_array_rep (void) const { return rep; } |
721 | 742 |
722 private: | 743 private: |
723 | 744 |
745 bool is_unique (void) const { return rep->count == 1; } | |
746 | |
724 void resize2 (octave_idx_type nr, octave_idx_type nc, const T& rfv); | 747 void resize2 (octave_idx_type nr, octave_idx_type nc, const T& rfv); |
725 void resize2 (octave_idx_type nr, octave_idx_type nc) | 748 void resize2 (octave_idx_type nr, octave_idx_type nc) |
726 { | 749 { |
727 resize2 (nr, nc, resize_fill_value ()); | 750 resize2 (nr, nc, resize_fill_value ()); |
728 } | 751 } |