use std::cmp::Ordering;
use crate::Measurable;
#[inline(always)]
pub fn measure_of<M: Measurable>(slice: &[M]) -> M::Measure {
slice
.iter()
.map(|measurable| measurable.measure())
.fold(M::Measure::default(), |accum, measure| accum + measure)
}
#[inline(always)]
pub fn index_to_measure<M: Measurable>(slice: &[M], index: usize) -> M::Measure {
slice
.iter()
.take(index)
.map(|measurable| measurable.measure())
.fold(M::Measure::default(), |accum, measure| accum + measure)
}
#[inline(always)]
pub fn start_measure_to_index<M: Measurable>(
slice: &[M],
start: M::Measure,
cmp: impl Fn(&M::Measure, &M::Measure) -> Ordering,
) -> usize {
let mut index = 0;
let mut accum = M::Measure::default();
for measurable in slice {
let measure = measurable.measure();
let next_accum = accum + measure;
if cmp(&next_accum, &start).is_gt()
|| (cmp(&measure, &M::Measure::default()).is_eq() && cmp(&start, &next_accum).is_eq())
{
break;
}
accum = next_accum;
index += 1;
}
index
}
#[inline(always)]
pub fn end_measure_to_index<M: Measurable>(
slice: &[M],
end: M::Measure,
cmp: impl Fn(&M::Measure, &M::Measure) -> Ordering,
) -> usize {
let mut index = 0;
let mut accum = M::Measure::default();
for measurable in slice {
let measure = measurable.measure();
if cmp(&accum, &end).is_gt()
|| (cmp(&measure, &M::Measure::default()).is_ne() && cmp(&end, &accum).is_eq())
{
break;
}
accum = accum + measure;
index += 1;
}
index
}