use super::{CpuCapabilities, OptimizationLevel, OptimizationProvider};
use std::error::Error as StdError;
use std::fmt::Debug;
pub trait AlgorithmFactory<T> {
type Error: StdError + Debug + Send + Sync + 'static;
fn create_with_optimization(
&self,
level: OptimizationLevel,
capabilities: &CpuCapabilities,
) -> Result<T, Self::Error>;
fn create_reference(&self) -> Result<T, Self::Error>;
fn create_optimized(&self, capabilities: &CpuCapabilities) -> Result<T, Self::Error>;
}
pub struct DefaultAlgorithmFactory<P> {
provider: P,
}
impl<P> DefaultAlgorithmFactory<P> {
pub fn new(provider: P) -> Self {
Self { provider }
}
}
impl<P, T> AlgorithmFactory<T> for DefaultAlgorithmFactory<P>
where
P: OptimizationProvider<Output = T>,
P::Error: StdError + Debug + Send + Sync + 'static,
{
type Error = P::Error;
fn create_with_optimization(
&self,
level: OptimizationLevel,
capabilities: &CpuCapabilities,
) -> Result<T, Self::Error> {
match level {
OptimizationLevel::Reference => self.create_reference(),
OptimizationLevel::Optimized | OptimizationLevel::Aggressive => {
self.create_optimized(capabilities)
}
}
}
fn create_reference(&self) -> Result<T, Self::Error> {
self.provider.create_reference()
}
fn create_optimized(&self, capabilities: &CpuCapabilities) -> Result<T, Self::Error> {
self.provider.create_optimized(capabilities)
}
}