def make_clamp(
input_domain: VectorDomain[AtomDomain[TA]],
input_metric: M,
bounds: tuple[TA, TA]
): input_domain.element_domain.assert_non_null()
output_row_domain = input_domain.element_domain.clone()
output_row_domain.bounds = Bounds.new_closed(bounds)
def clamper(value: TA) -> TA: return value.total_clamp(bounds[0], bounds[1])
return make_row_by_row_fallible( input_domain,
input_metric,
output_row_domain,
clamper
)