| 2065 | } |
| 2066 | |
| 2067 | static std::size_t adjust_strided_shape(shape& s, std::size_t n) |
| 2068 | { |
| 2069 | auto lens = s.lens(); |
| 2070 | auto strides = s.strides(); |
| 2071 | |
| 2072 | // Insert a dim of 1 so it can be used to handle steps |
| 2073 | if(std::none_of(strides.begin(), strides.end(), [](auto stride) { return stride == 1; }) and |
| 2074 | std::any_of(strides.begin(), strides.end(), [](auto stride) { return stride != 0; })) |
| 2075 | { |
| 2076 | lens.push_back(1); |
| 2077 | strides.push_back(1); |
| 2078 | } |
| 2079 | |
| 2080 | auto last_axis = std::max_element(strides.begin(), strides.end()) - strides.begin(); |
| 2081 | auto total_elements = std::max<std::size_t>(1, strides[last_axis] * lens[last_axis]); |
| 2082 | // Add a dim of 1 to the front so it can handle extra elements |
| 2083 | auto extra = n / total_elements; |
| 2084 | if(extra > 1) |
| 2085 | { |
| 2086 | strides.insert(strides.begin(), total_elements); |
| 2087 | lens.insert(lens.begin(), 1); |
| 2088 | } |
| 2089 | s = shape(s.type(), lens, strides); |
| 2090 | return std::max<std::size_t>(1, extra); |
| 2091 | } |
| 2092 | |
| 2093 | template <class Range> |
| 2094 | static std::vector<std::size_t> select_mask(const std::vector<std::size_t>& slice_mask, |