* This function negates any strides in the iterator * which are negative. When iterating more than one * object, it only flips strides when they are all * negative or zero. */
| 2153 | * negative or zero. |
| 2154 | */ |
| 2155 | static void |
| 2156 | npyiter_flip_negative_strides(NpyIter *iter) |
| 2157 | { |
| 2158 | npy_uint32 itflags = NIT_ITFLAGS(iter); |
| 2159 | int idim, ndim = NIT_NDIM(iter); |
| 2160 | int iop, nop = NIT_NOP(iter); |
| 2161 | |
| 2162 | npy_intp istrides, nstrides = NAD_NSTRIDES(); |
| 2163 | NpyIter_AxisData *axisdata, *axisdata0; |
| 2164 | npy_intp *baseoffsets; |
| 2165 | npy_intp sizeof_axisdata = NIT_AXISDATA_SIZEOF(itflags, ndim, nop); |
| 2166 | int any_flipped = 0; |
| 2167 | |
| 2168 | axisdata0 = axisdata = NIT_AXISDATA(iter); |
| 2169 | baseoffsets = NIT_BASEOFFSETS(iter); |
| 2170 | for (idim = 0; idim < ndim; ++idim, NIT_ADVANCE_AXISDATA(axisdata, 1)) { |
| 2171 | npy_intp *strides = NAD_STRIDES(axisdata); |
| 2172 | int any_negative = 0; |
| 2173 | |
| 2174 | /* |
| 2175 | * Check the signs of all the operand strides. |
| 2176 | */ |
| 2177 | for (iop = 0; iop < nop; ++iop) { |
| 2178 | if (strides[iop] < 0) { |
| 2179 | any_negative = 1; |
| 2180 | } |
| 2181 | else if (strides[iop] != 0) { |
| 2182 | break; |
| 2183 | } |
| 2184 | } |
| 2185 | /* |
| 2186 | * If at least one stride is negative and none are positive, |
| 2187 | * flip all the strides for this dimension. |
| 2188 | */ |
| 2189 | if (any_negative && iop == nop) { |
| 2190 | npy_intp shapem1 = NAD_SHAPE(axisdata) - 1; |
| 2191 | |
| 2192 | for (istrides = 0; istrides < nstrides; ++istrides) { |
| 2193 | npy_intp stride = strides[istrides]; |
| 2194 | |
| 2195 | /* Adjust the base pointers to start at the end */ |
| 2196 | baseoffsets[istrides] += shapem1 * stride; |
| 2197 | /* Flip the stride */ |
| 2198 | strides[istrides] = -stride; |
| 2199 | } |
| 2200 | /* |
| 2201 | * Make the perm entry negative so get_multi_index |
| 2202 | * knows it's flipped |
| 2203 | */ |
| 2204 | NIT_PERM(iter)[idim] = -1-NIT_PERM(iter)[idim]; |
| 2205 | |
| 2206 | any_flipped = 1; |
| 2207 | } |
| 2208 | } |
| 2209 | |
| 2210 | /* |
| 2211 | * If any strides were flipped, the base pointers were adjusted |
| 2212 | * in the first AXISDATA, and need to be copied to all the rest |
no outgoing calls
no test coverage detected