#include "tensorstore/index_space/index_transform.h"
template <DimensionIndex InputRank,
         
 DimensionIndex OutputRank,
         
 ContainerKind CKind>
Result<IndexTransform<InputRank, OutputRank>>
tensorstore::PropagateBoundsToTransform(
    
std::type_identity_t<BoxView<OutputRank>> b_domain,
    
DimensionSet b_implicit_lower_bounds,
    
DimensionSet b_implicit_upper_bounds,
    
IndexTransform<InputRank, OutputRank, CKind> a_to_b);
template <DimensionIndex InputRank,
         
 DimensionIndex OutputRank,
         
 ContainerKind CKind>
Result<IndexTransform<InputRank, OutputRank>>
tensorstore::PropagateBoundsToTransform(
    
std::type_identity_t<IndexDomainView<OutputRank>> b_domain,
    
IndexTransform<InputRank, OutputRank, CKind> a_to_b);

Returns a new transform that represents the same mapping as a_to_b but may have a reduced input domain:

  1. Any implicit bounds are replaced with inferred values propagated from b_domain. Bounds are only inferred from OutputIndexMethod::single_input_dimension output index maps. If any explicit input dimension bounds would result in an output range not contained within b_domain, then this function returns an error.

  2. The index_range intervals of any index array output index maps are also restricted as needed to ensure the output range is contained within b_domain. Note that only the index_range intervals are adjusted; the actual index values contained in any index arrays are not checked (but any subsequent attempt to use them will cause them to be checked against the reduced index_range intervals). Implicit bounds of “b” are not propagated to the index_range intervals.

Additionally, this function returns an error, rather than a new transform, if constant output index maps produce output indices outside b_domain (implicit bounds of b are ignored).

If this function does not return an error, it is guaranteed that any output index vector computed by the returned transform will be contained within b_domain.

The IndexTransform::implicit_lower_bounds and IndexTransform::implicit_upper_bounds vectors for the input space a of the returned transform are computed based on the implicit bound state of the input a_to_b transform and the specified b_implicit_lower_bounds and b_implicit_upper_bounds:

Each propagated lower/upper bound for a is implicit iff:

  1. The original bound specified in a_to_b is implicit; and

  2. All contributing (by way of a OutputIndexMethod::single_input_dimension map) bounds of b are implicit.

Parameters:
std::type_identity_t<BoxView<OutputRank>> b_domain
std::type_identity_t<IndexDomainView<OutputRank>> b_domain

The bounds in the “b” index space.

DimensionSet b_implicit_lower_bounds

Implicit indicator for each lower bound of b.

DimensionSet b_implicit_upper_bounds

Implicit indicator for each upper bound of b.

IndexTransform<InputRank, OutputRank, CKind> a_to_b

The transform from a to b. May be null, which implies an identity transform over b_domain.

Returns:

A new index transform that specifies the same transform as a_to_b but with a restricted input domain as computed by the PropagateBounds overload defined above, and with the index_range values of any OutputIndexMethod::array output index maps also restricted.

Error absl::StatusCode::kInvalidArgument:

if integer overflow occurs when propagating bounds.

Error absl::StatusCode::kOutOfRange:

if the existing input domain or constant index maps of a_to_b are incompatible with b_domain