#[cfg(feature = "ffi")]
mod ffi;
use opendp_derive::bootstrap;
use crate::core::{MetricSpace, Transformation};
use crate::domains::{AtomDomain, Bounds, VectorDomain};
use crate::error::Fallible;
use crate::metrics::EventLevelMetric;
use crate::traits::{CheckAtom, ProductOrd};
use crate::transformations::make_row_by_row_fallible;
#[bootstrap(
features("contrib"),
arguments(
input_domain(c_type = "AnyDomain *", hint = "Domain"),
input_metric(c_type = "AnyMetric *", hint = "Metric", rust_type = b"null")
),
generics(TA(suppress), M(suppress)),
derived_types(TA = "$get_atom(get_type(input_domain))")
)]
pub fn make_clamp<TA: 'static + Clone + ProductOrd + PartialOrd + CheckAtom, M: EventLevelMetric>(
input_domain: VectorDomain<AtomDomain<TA>>,
input_metric: M,
bounds: (TA, TA),
) -> Fallible<Transformation<VectorDomain<AtomDomain<TA>>, M, VectorDomain<AtomDomain<TA>>, M>>
where
(VectorDomain<AtomDomain<TA>>, M): MetricSpace,
{
input_domain.element_domain.assert_non_nan()?;
let mut output_row_domain = input_domain.element_domain.clone();
output_row_domain.bounds = Some(Bounds::<TA>::new_closed(bounds.clone())?);
make_row_by_row_fallible(
input_domain,
input_metric,
output_row_domain,
move |arg: &TA| arg.clone().total_clamp(bounds.0.clone(), bounds.1.clone()),
)
}
#[cfg(all(test, feature = "partials"))]
mod test;