use crate::{Accelerator, Domain1dError, InterpolationError};
pub trait BuildInterpolator: Interpolation + Sized {
#[doc(alias = "gsl_interp_min_size")]
const MIN_SIZE: usize;
#[doc(alias = "gsl_interp_init")]
#[expect(clippy::missing_errors_doc, reason = "documented on the implementors")]
fn build(xa: &[f64], ya: &[f64]) -> Result<Self, InterpolationError>;
}
#[expect(private_bounds, reason = "needed to make Box<dyn Interpolation> Clone")]
pub trait Interpolation: DynInterpolationClone + Send + Sync + 'static {
#[doc(alias = "gsl_interp_eval")]
#[doc(alias = "gsl_interp_eval_e")]
fn eval(
&self,
xa: &[f64],
ya: &[f64],
x: f64,
acc: &mut Accelerator,
) -> Result<f64, Domain1dError>;
#[doc(alias = "gsl_interp_eval_deriv")]
#[doc(alias = "gsl_interp_eval_deriv_e")]
fn eval_deriv(
&self,
xa: &[f64],
ya: &[f64],
x: f64,
acc: &mut Accelerator,
) -> Result<f64, Domain1dError>;
#[doc(alias = "gsl_interp_eval_deriv2")]
#[doc(alias = "gsl_interp_eval_deriv2_e")]
fn eval_deriv2(
&self,
xa: &[f64],
ya: &[f64],
x: f64,
acc: &mut Accelerator,
) -> Result<f64, Domain1dError>;
#[doc(alias = "gsl_interp_eval_integ")]
#[doc(alias = "gsl_interp_eval_integ_e")]
fn eval_integ(
&self,
xa: &[f64],
ya: &[f64],
a: f64,
b: f64,
acc: &mut Accelerator,
) -> Result<f64, Domain1dError>;
}
trait DynInterpolationClone {
fn clone_box(&self) -> Box<dyn Interpolation>;
}
impl<T> DynInterpolationClone for T
where
T: 'static + Interpolation + Clone,
{
fn clone_box(&self) -> Box<dyn Interpolation> {
Box::new(self.clone())
}
}
impl Clone for Box<dyn Interpolation> {
fn clone(&self) -> Self {
self.clone_box()
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::*;
#[test]
fn dyn_clone() {
let xa = [0.0, 1.0, 2.0, 3.0, 4.0];
let ya = [0.0, 2.0, 4.0, 6.0, 8.0];
let interp: Box<dyn Interpolation> = Box::new(CubicInterpolator::build(&xa, &ya).unwrap());
let _ = interp.clone();
}
}