mod bininterval;
use std::iter::FusedIterator;
pub use bininterval::bininterval::BinInterval;
pub use bininterval::singlevaluebininterval::SingleValueBinInterval;
mod uniformcyclic;
pub use uniformcyclic::UniformCyclic;
mod variablecyclic;
pub use variablecyclic::VariableCyclic;
mod uniform;
pub use uniform::Uniform;
mod uniformnoflow;
pub use uniformnoflow::UniformNoFlow;
mod category;
pub use category::Category;
mod categorynoflow;
pub use categorynoflow::CategoryNoFlow;
mod variable;
pub use variable::Variable;
mod variablenoflow;
pub use variablenoflow::VariableNoFlow;
pub trait Axis {
type Coordinate;
type BinInterval;
type Iter<'a>: Iterator<Item = (usize, Self::BinInterval)>
where
Self: 'a;
fn index(&self, coordinate: &Self::Coordinate) -> Option<usize>;
fn num_bins(&self) -> usize;
fn bin(&self, index: usize) -> Option<Self::BinInterval>;
fn indices(&self) -> impl Iterator<Item = usize> {
self.iter().map(|(it, _)| it)
}
fn iter(&self) -> Self::Iter<'_>;
fn bins(&self) -> impl Iterator<Item = Self::BinInterval> {
self.iter().map(|(_, it)| it)
}
fn num_dim(&self) -> usize {
1
}
}
#[derive(Debug)]
pub struct AxisIter<'a, A: Axis> {
axis: &'a A,
range: std::ops::Range<usize>,
}
impl<'a, A: Axis> AxisIter<'a, A> {
pub fn new(axis: &'a A) -> Self {
Self {
axis,
range: 0..axis.num_bins(),
}
}
}
impl<'a, A: Axis> Iterator for AxisIter<'a, A> {
type Item = (usize, A::BinInterval);
fn next(&mut self) -> Option<Self::Item> {
if let Some(index) = self.range.next() {
Some((
index,
self.axis
.bin(index)
.expect("indices() should only produce valid indices"),
))
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.range.size_hint()
}
}
impl<'a, A: Axis> ExactSizeIterator for AxisIter<'a, A> {
fn len(&self) -> usize {
self.range.len()
}
}
impl<'a, A: Axis> FusedIterator for AxisIter<'a, A> {}