use crate::{axis::Axis, FillWith};
use super::fill::{Fill, FillWithWeighted};
pub(crate) type Values<'a, V> = Box<dyn Iterator<Item = &'a V> + 'a>;
pub(crate) type Iter<'a, A, V> =
Box<dyn Iterator<Item = Item<<A as Axis>::BinInterval, &'a V>> + 'a>;
pub(crate) type ValuesMut<'a, V> = Box<dyn Iterator<Item = &'a mut V> + 'a>;
pub(crate) type IterMut<'a, A, V> =
Box<dyn Iterator<Item = Item<<A as Axis>::BinInterval, &'a mut V>> + 'a>;
pub trait Histogram<A: Axis, V> {
fn axes(&self) -> &A;
fn value_at_index(&self, index: usize) -> Option<&V>;
fn value(&self, coordinate: &A::Coordinate) -> Option<&V> {
let index = self.axes().index(coordinate)?;
self.value_at_index(index)
}
fn values(&self) -> Values<'_, V>;
fn iter(&self) -> Iter<'_, A, V>;
fn value_at_index_mut(&mut self, index: usize) -> Option<&mut V>;
#[inline]
fn value_mut(&mut self, coordinate: &A::Coordinate) -> Option<&mut V> {
let index = self.axes().index(coordinate)?;
self.value_at_index_mut(index)
}
fn values_mut(&mut self) -> ValuesMut<'_, V>;
fn iter_mut(&mut self) -> IterMut<'_, A, V>;
#[inline]
fn fill(&mut self, coordinate: &A::Coordinate)
where
V: Fill,
{
if let Some(value) = self.value_mut(coordinate) {
value.fill()
}
}
#[inline]
fn fill_with<D>(&mut self, coordinate: &A::Coordinate, data: D)
where
V: FillWith<D>,
Self: Sized,
{
if let Some(value) = self.value_mut(coordinate) {
value.fill_with(data)
}
}
#[inline]
fn fill_with_weighted<D, W>(&mut self, coordinate: &A::Coordinate, data: D, weight: W)
where
V: FillWithWeighted<D, W>,
Self: Sized,
{
if let Some(value) = self.value_mut(coordinate) {
value.fill_with_weighted(data, weight)
}
}
}
#[derive(Copy, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Item<T, V> {
pub index: usize,
pub bin: T,
pub value: V,
}
impl<T, V> Item<T, V> {
pub fn new(index: usize, bin: T, value: V) -> Self {
Self { index, bin, value }
}
}