Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r62963 - trunk/boost/multi_array
From: garcia_at_[hidden]
Date: 2010-06-14 21:40:31


Author: garcia
Date: 2010-06-14 21:40:31 EDT (Mon, 14 Jun 2010)
New Revision: 62963
URL: http://svn.boost.org/trac/boost/changeset/62963

Log:
Fixed an assertion error...resize needs to account for starting with
an empty array when considering legal ranges.
Some small housecleaning (renaming variables, moving asserts).

Text files modified:
   trunk/boost/multi_array/base.hpp | 49 +++++++++++++++++++++++++++++----------
   1 files changed, 36 insertions(+), 13 deletions(-)

Modified: trunk/boost/multi_array/base.hpp
==============================================================================
--- trunk/boost/multi_array/base.hpp (original)
+++ trunk/boost/multi_array/base.hpp 2010-06-14 21:40:31 EDT (Mon, 14 Jun 2010)
@@ -431,29 +431,52 @@
     index offset = 0;
     size_type dim = 0;
     for (size_type n = 0; n != NumDims; ++n) {
+
+ // Use array specs and input specs to produce real specs.
       const index default_start = index_bases[n];
       const index default_finish = default_start+extents[n];
       const index_range& current_range = indices.ranges_[n];
       index start = current_range.get_start(default_start);
       index finish = current_range.get_finish(default_finish);
- index factor = current_range.stride();
+ index stride = current_range.stride();
+ BOOST_ASSERT(stride != 0);
 
- // integral trick for ceiling((finish-start) / factor)
- index shrinkage = factor > 0 ? 1 : -1;
- index len = (finish - start + (factor - shrinkage)) / factor;
+ // An index range indicates a half-open strided interval
+ // [start,finish) (with stride) which faces upward when stride
+ // is positive and downward when stride is negative,
+
+ // RG: The following code for calculating length suffers from
+ // some representation issues: if finish-start cannot be represented as
+ // by type index, then overflow may result.
+
+ index len;
+ if ((finish - start) / stride < 0) {
+ // [start,finish) is empty according to the direction imposed by
+ // the stride.
+ len = 0;
+ } else {
+ // integral trick for ceiling((finish-start) / stride)
+ // taking into account signs.
+ index shrinkage = stride > 0 ? 1 : -1;
+ len = (finish - start + (stride - shrinkage)) / stride;
+ }
 
+ // start marks the closed side of the range, so it must lie
+ // exactly in the set of legal indices
+ // with a special case for empty arrays
       BOOST_ASSERT(index_bases[n] <= start &&
- start < index_bases[n]+index(extents[n]));
+ ((start <= index_bases[n]+index(extents[n])) ||
+ (start == index_bases[n] && extents[n] == 0)));
 
 #ifndef BOOST_DISABLE_ASSERTS
- // The legal values of finish depends on the sign of the factor
- index lb_adjustment = factor < 0 ? 1 : 0;
- index ub_adjustment = factor > 0 ? 1 : 0;
- BOOST_ASSERT(index_bases[n] - lb_adjustment <= finish &&
- finish < index_bases[n]+index(extents[n]) + ub_adjustment);
+ // finish marks the open side of the range, so it can go one past
+ // the "far side" of the range (the top if stride is positive, the bottom
+ // if stride is negative).
+ index bound_adjustment = stride < 0 ? 1 : 0;
+ BOOST_ASSERT(((index_bases[n] - bound_adjustment) <= finish) &&
+ (finish <= (index_bases[n] + index(extents[n]) - bound_adjustment)));
 #endif // BOOST_DISABLE_ASSERTS
 
- BOOST_ASSERT(factor != 0);
 
       // the array data pointer is modified to account for non-zero
       // bases during slicing (see [Garcia] for the math involved)
@@ -461,9 +484,9 @@
 
       if (!current_range.is_degenerate()) {
 
- // The factor for each dimension is included into the
+ // The stride for each dimension is included into the
         // strides for the array_view (see [Garcia] for the math involved).
- new_strides[dim] = factor * strides[n];
+ new_strides[dim] = stride * strides[n];
         
         // calculate new extents
         new_extents[dim] = len;


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk