#include "tensorstore/index_interval.h"
Result<std::pair<OptionallyImplicitIndexInterval, Index>>
tensorstore::ExtractHalfOpenStridedSlice(
    
OptionallyImplicitIndexInterval orig,
    
Index start,
    
Index stop,
    
Index stride);

Extracts a strided half-open interval from a containing interval.

This function is primarily for use by DimExpression::HalfOpenInterval.

The precise definition is as follows:

If start == kImplicit:

  • Sets adjusted_start to orig.interval.inclusive_min() if stride > 0, or orig.interval.inclusive_max() otherwise.

  • Sets implicit_lower = orig.implicit_lower().

Otherwise (if start != kImplicit):

  • Sets adjusted_start = start.

  • Sets implicit_lower = false.

If stop == kImplicit:

  • Sets adjusted_stop to orig.interval.inclusive_min() if stride < 0, or orig.interval.inclusive_max() otherwise.

  • Sets implicit_upper = orig.implicit_upper().

Otherwise (stop != kImplicit):

  • Sets adjusted_stop = stop - sign(stride).

  • Sets implicit_upper = false.

If stride > 0:

  • Sets adjusted_interval to [adjusted_start, adjusted_stop].

Otherwise (if stride < 0):

  • Sets adjusted_interval to [adjusted_stop, adjusted_start].

  • Swaps implicit_lower and implicit_upper.

Sets new_inclusive_min = adjusted_start / stride (rounding towards zero).

If adjusted_stop * sign(stride) == kInfIndex:

  • Sets new_size = kInfIndex + 1 - new_inclusive_min.

Otherwise:

  • Sets new_size to the maximum positive integer such that adjusted_start + stride * (new_size - 1) is contained in adjusted_interval.

Sets new_interval to be the interval starting at new_inclusive_min with a size of new_size.

Examples:

If orig = [5, 10], start = 6, stop = 9, and stride = 1, returns [6, 8] with adjusted_start = 6.

If orig = [5*, 10], start = 4, stop = 9, and stride = 1, returns [4, 8] with adjusted_start = 4.

If orig = [5*, 10], start = kImplicit, stop = 9, and stride = 1, returns [5*, 8] with adjusted_start = 5.

If orig = [5, 10], start = 9, stop = 7, and stride = -2, returns [-4, -4] with adjusted_start = 9.

Parameters:
OptionallyImplicitIndexInterval orig

The original interval from which to extract a strided slice.

Index start

The index in orig corresponding to the inclusive_min value in the result interval. If equal to kImplicit, the lower (if stride > 0) or upper (if stride < 0) bound of orig is used.

Index stop

Specifies the exclusive stop index in orig. If equal to kImplicit, the upper (if stride > 0) or lower (if stride < 0) bound of orig is used.

Index stride

Specifies the stride value.

Returns:

{{new_interval, implicit_lower, implicit_upper}, adjusted_start}.

Error absl::StatusCode::kInvalidArgument:

if stride == 0 or stride == std::numeric_limits<Index>::min().

Error absl::StatusCode::kInvalidArgument:

if adjusted_interval is not a valid interval.

Error absl::StatusCode::kOutOfRange:

if adjusted_interval is not contained within orig (implicit bounds of orig do not constrain adjusted_interval).