| 2173 | // index BIndex in the array). |
| 2174 | template <size_t... Index, size_t... VIndex, size_t... BIndex> |
| 2175 | object run(typename vectorize_arg<Args>::type &...args, |
| 2176 | index_sequence<Index...> i_seq, |
| 2177 | index_sequence<VIndex...> vi_seq, |
| 2178 | index_sequence<BIndex...> bi_seq) { |
| 2179 | |
| 2180 | // Pointers to values the function was called with; the vectorized ones set here will start |
| 2181 | // out as array_t<T> pointers, but they will be changed them to T pointers before we make |
| 2182 | // call the wrapped function. Non-vectorized pointers are left as-is. |
| 2183 | std::array<void *, N> params{{reinterpret_cast<void *>(&args)...}}; |
| 2184 | |
| 2185 | // The array of `buffer_info`s of vectorized arguments: |
| 2186 | std::array<buffer_info, NVectorized> buffers{ |
| 2187 | {reinterpret_cast<array *>(params[VIndex])->request()...}}; |
| 2188 | |
| 2189 | /* Determine dimensions parameters of output array */ |
| 2190 | ssize_t nd = 0; |
| 2191 | std::vector<ssize_t> shape(0); |
| 2192 | auto trivial = broadcast(buffers, nd, shape); |
| 2193 | auto ndim = (size_t) nd; |
| 2194 | |
| 2195 | size_t size |
| 2196 | = std::accumulate(shape.begin(), shape.end(), (size_t) 1, std::multiplies<size_t>()); |
| 2197 | |
| 2198 | // If all arguments are 0-dimension arrays (i.e. single values) return a plain value (i.e. |
| 2199 | // not wrapped in an array). |
| 2200 | if (size == 1 && ndim == 0) { |
| 2201 | PYBIND11_EXPAND_SIDE_EFFECTS(params[VIndex] = buffers[BIndex].ptr); |
| 2202 | return cast( |
| 2203 | returned_array::call(f, *reinterpret_cast<param_n_t<Index> *>(params[Index])...)); |
| 2204 | } |
| 2205 | |
| 2206 | auto result = returned_array::create(trivial, shape); |
| 2207 | |
| 2208 | PYBIND11_WARNING_PUSH |
| 2209 | #ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING |
| 2210 | PYBIND11_WARNING_DISABLE_CLANG("-Wreturn-std-move") |
| 2211 | #endif |
| 2212 | |
| 2213 | if (size == 0) { |
| 2214 | return result; |
| 2215 | } |
| 2216 | |
| 2217 | /* Call the function */ |
| 2218 | auto *mutable_data = returned_array::mutable_data(result); |
| 2219 | if (trivial == broadcast_trivial::non_trivial) { |
| 2220 | apply_broadcast(buffers, params, mutable_data, size, shape, i_seq, vi_seq, bi_seq); |
| 2221 | } else { |
| 2222 | apply_trivial(buffers, params, mutable_data, size, i_seq, vi_seq, bi_seq); |
| 2223 | } |
| 2224 | |
| 2225 | return result; |
| 2226 | PYBIND11_WARNING_POP |
| 2227 | } |
| 2228 | |
| 2229 | template <size_t... Index, size_t... VIndex, size_t... BIndex> |
| 2230 | void apply_trivial(std::array<buffer_info, NVectorized> &buffers, |