#include "tensorstore/index_space/dim_expression.h"
template <typename... IndexArray>
auto tensorstore::DimExpression<Op...>::IndexArraySlice(
    
const IndexArray&... index_arrays) const;
auto tensorstore::DimExpression<Op...>::IndexArraySlice(
    
span<const SharedArrayView<const Index>> index_arrays) const;

Jointly slices the selected dimensions using index arrays.

The k = sizeof...(IndexArray) index arrays, corresponding to the k selected_dimensions, must all be of the same rank n and have broadcast-compatible shapes. Given an existing_transform with input rank m, the new index transform maps input vectors of size m + n - k to:

existing_transform(interleave(input[n:], selected_dimensions,
                              {broadcast(index_array)(input[:n])...}))

The selected dimensions are removed from the new index space, and the dimensions of the index arrays (which must all have the same rank and broadcast-compatible shapes) are added as the first dimensions of the new index space with origins of 0 and empty labels. The new dimension selection corresponds to these added dimensions; they can be labeled and reordered relative to the existing dimensions by chaining the Label and MoveTo methods.

The behavior is similar to that of NumPy integer array indexing, except that the added dimensions corresponding to the index arrays are always added as the first dimensions.

For example:

Dims(0, 2).IndexArraySlice(MakeArray<Index>({{1, 2, 3}, {4, 5, 6}}),
                           MakeArray<Index>({{7, 8, 9}, {0, 1, 2}}))

has the following effects:

Before

After

Dimension selection

{0, 2}

{0, 1}

Input domain

[0, 6], [2, 5], [0, 9]

[0, 1], [0, 2], [2, 5]

Labels

{"x", "y", "z"}

{"", "", "y"}

Equivalent input indices

{1, y, 7}

{0, 0, y}

Equivalent input indices

{2, y, 8}

{0, 1, y}

Equivalent input indices

{3, y, 9}

{0, 2, y}

Equivalent input indices

{6, y, 2}

{1, 2, y}

Equivalent input indices

{xi(a, b), y, zi(a, b)}

{a, b, y}

where y is any index in [2, 5], a is any index in [0, 1], b is any index in [0, 2], xi = MakeArray<Index>({{1, 2, 3}, {4, 5, 6}}) and zi = MakeArray<Index>({{7, 8, 9}, {0, 1, 2}}).

Requires:

The IndexArray types satisfy IsIndexArray and have compatible static ranks.

Requires:

For the variadic overload, sizeof...(IndexArray) must be compatible with the static rank of the dimension selection.

Parameters:
const IndexArray&... index_arrays
span<const SharedArrayView<const Index>> index_arrays

The index arrays used to index into each selected dimension. The new transform may share ownership of the supplied index arrays. The index arrays should not be modified after being passed to this function. The index values contained in the index arrays may be bounds-checked lazily.

Error absl::StatusCode::kInvalidArgument:

if sizeof...(IndexArray) is not equal to the number of selected dimensions.

Error absl::StatusCode::kInvalidArgument:

if the shapes of the index arrays cannot be broadcast to a common shape.

Error absl::StatusCode::kOutOfRange:

if an out-of-bounds index is detected. error absl::StatusCode::kInvalidArgument if integer overflow occurs when computing the resultant transform.