pub(crate) fn triangular_for<Item>(
iterable: impl Iterator<Item = Item> + Clone,
mut f: impl FnMut(&Item, Item),
) {
let mut outer_iter = iterable.into_iter();
while let Some(outer_value) = outer_iter.next() {
let mut inner_iter = outer_iter.clone();
while let Some(inner_value) = inner_iter.next() {
f(&outer_value, inner_value);
}
}
}
pub(crate) struct Minimum<T: Clone, F: Fn(&T, &T) -> std::cmp::Ordering> {
value: Option<T>,
#[allow(unused)]
f: F,
}
impl<T: Clone, F: Fn(&T, &T) -> std::cmp::Ordering> Minimum<T, F> {
#[allow(unused)]
pub(crate) fn new(f: F) -> Self {
Self { value: None, f }
}
#[allow(unused)]
pub(crate) fn consider(&mut self, other: &T) -> bool {
if let Some(value) = &self.value {
if std::cmp::Ordering::Less == (self.f)(other, value) {
self.value = Some(other.clone());
return true;
}
} else {
self.value = Some(other.clone());
return true;
}
return false;
}
#[allow(unused)]
pub(crate) fn consider_take(&mut self, other: T) -> bool {
if let Some(value) = &self.value {
if std::cmp::Ordering::Less == (self.f)(&other, value) {
self.value = Some(other);
return true;
}
} else {
self.value = Some(other);
return true;
}
return false;
}
#[allow(unused)]
pub(crate) fn result(self) -> Option<T> {
self.value
}
#[allow(unused)]
pub(crate) fn has_value(&self) -> bool {
self.value.is_some()
}
}
pub enum ForkIter<L, R> {
Left(L),
Right(R),
}
impl<L: Iterator, R: Iterator<Item = L::Item>> Iterator for ForkIter<L, R> {
type Item = L::Item;
fn next(&mut self) -> Option<Self::Item> {
match self {
Self::Left(left) => left.next(),
Self::Right(right) => right.next(),
}
}
}
pub fn wrap_to_pi(mut value: f64) -> f64 {
while std::f64::consts::PI < value {
value -= 2.0 * std::f64::consts::PI;
}
while value < -std::f64::consts::PI {
value += 2.0 * std::f64::consts::PI;
}
value
}
pub struct IterError<T, E> {
error: Option<E>,
_ignore: std::marker::PhantomData<fn(T)>,
}
impl<T, E> IterError<T, E> {
pub fn new(error: E) -> Self {
Self {
error: Some(error),
_ignore: Default::default(),
}
}
}
impl<T, E> Iterator for IterError<T, E> {
type Item = Result<T, E>;
fn next(&mut self) -> Option<Self::Item> {
self.error.take().map(Err)
}
}