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 }