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
)