| 167 | |
| 168 | public: |
| 169 | explicit sliced_array(nd::array arr, icm::slice_vector_t<I> slices_vec) |
| 170 | : a_(std::move(arr)) |
| 171 | { |
| 172 | ASSERT(!a_.is_dynamic()); |
| 173 | std::vector<int64_t> new_shape; |
| 174 | auto shape = a_.shape(); |
| 175 | |
| 176 | if (shape.size() < slices_vec.size()) { |
| 177 | throw nd::shape_dimensions_do_not_match(shape.size(), slices_vec.size()); |
| 178 | } |
| 179 | |
| 180 | while (slices_vec.size() < shape.size()) { |
| 181 | slices_vec.push_back(icm::slice_t<I>::all()); |
| 182 | } |
| 183 | |
| 184 | new_shape.resize(shape.size()); |
| 185 | slices_.resize(shape.size()); |
| 186 | |
| 187 | bool should_reverse = false; |
| 188 | |
| 189 | for (size_t i = 0; i < shape.size(); ++i) { |
| 190 | auto& s = slices_vec[i]; |
| 191 | auto step = s.is_index() ? 1 : s.step(); |
| 192 | if (step == 0) { |
| 193 | throw nd::invalid_operation("slice step cannot be zero"); |
| 194 | } |
| 195 | |
| 196 | I start = s.is_start_known() ? s.start() : ((step > 0) ? 0 : (shape[i] - 1)); |
| 197 | if (start < 0) { |
| 198 | start += shape[i]; |
| 199 | } |
| 200 | int64_t dim = 0; |
| 201 | // hundle the following cases with the if statement: |
| 202 | // >>> x |
| 203 | // array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) |
| 204 | // >>> x[-100::-1] |
| 205 | // array([], dtype=int64) |
| 206 | // >>> x[100::1] |
| 207 | // array([], dtype=int64) |
| 208 | // >>> x[100::-1] |
| 209 | // array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0]) |
| 210 | // >>> x[-100::1] |
| 211 | // array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) |
| 212 | if (std::abs(start - shape[i]) < shape[i] || ((start * step) <= 0)) { |
| 213 | start = std::max(std::min(start, static_cast<I>(shape[i] - 1)), static_cast<I>(0)); |
| 214 | |
| 215 | auto stop = (!s.is_index() && s.is_known()) ? s.stop() : ((step > 0) ? shape[i] : (-shape[i] - 1)); |
| 216 | if (stop < 0) { |
| 217 | stop = shape[i] + stop; |
| 218 | } else { |
| 219 | stop = std::min(stop, shape[i]); |
| 220 | } |
| 221 | |
| 222 | if (step < 0) { |
| 223 | should_reverse = true; |
| 224 | } |
| 225 | dim = std::ceil((stop - start) / static_cast<float>(step)); |
| 226 | } |
nothing calls this directly
no test coverage detected