use std::rc::Rc;
use impl_tools::autoimpl;
use super::{labels::SequentialLabeling, lenders::NodeLabelsLender};
#[autoimpl(for<S: trait + ?Sized> &S, &mut S, Rc<S>)]
pub trait SplitLabeling: SequentialLabeling {
type SplitLender<'a>: for<'next> NodeLabelsLender<'next, Label = <Self as SequentialLabeling>::Label>
+ Send
+ Sync
where
Self: 'a;
type IntoIterator<'a>: IntoIterator<Item = Self::SplitLender<'a>, IntoIter: ExactSizeIterator>
where
Self: 'a;
fn split_iter(&self, n: usize) -> Self::IntoIterator<'_>;
}
pub mod seq {
use crate::prelude::SequentialLabeling;
pub struct Iter<L> {
lender: L,
nodes_per_iter: usize,
how_many: usize,
remaining: usize,
current_node: usize,
}
impl<L: lender::Lender> Iter<L> {
pub fn new(lender: L, number_of_nodes: usize, how_many: usize) -> Self {
let nodes_per_iter = number_of_nodes.div_ceil(how_many);
Self {
lender,
nodes_per_iter,
how_many,
remaining: how_many,
current_node: 0,
}
}
}
impl<L: lender::Lender + Clone> Iterator for Iter<L> {
type Item = lender::Take<L>;
fn next(&mut self) -> Option<Self::Item> {
if self.remaining == 0 {
return None;
}
if self.remaining != self.how_many {
self.lender.advance_by(self.nodes_per_iter).ok()?;
}
self.current_node += self.nodes_per_iter;
self.remaining -= 1;
Some(self.lender.clone().take(self.nodes_per_iter))
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.remaining, Some(self.remaining))
}
}
impl<L: lender::Lender + Clone> ExactSizeIterator for Iter<L> {
fn len(&self) -> usize {
self.remaining
}
}
pub type Lender<'a, S> = lender::Take<<S as SequentialLabeling>::Lender<'a>>;
pub type IntoIterator<'a, S> = Iter<<S as SequentialLabeling>::Lender<'a>>;
}
pub mod ra {
use crate::prelude::{RandomAccessLabeling, SequentialLabeling};
pub struct Iter<'a, R: RandomAccessLabeling> {
labeling: &'a R,
nodes_per_iter: usize,
how_many: usize,
i: usize,
}
impl<'a, R: RandomAccessLabeling> Iter<'a, R> {
pub fn new(labeling: &'a R, how_many: usize) -> Self {
let nodes_per_iter = labeling.num_nodes().div_ceil(how_many);
Self {
labeling,
nodes_per_iter,
how_many,
i: 0,
}
}
}
impl<'a, R: RandomAccessLabeling> Iterator for Iter<'a, R> {
type Item = Lender<'a, R>;
fn next(&mut self) -> Option<Self::Item> {
use lender::Lender;
if self.i == self.how_many {
return None;
}
let start_node = self.i * self.nodes_per_iter;
self.i += 1;
Some(
self.labeling
.iter_from(start_node)
.take(self.nodes_per_iter),
)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.how_many - self.i;
(len, Some(len))
}
}
impl<R: RandomAccessLabeling> ExactSizeIterator for Iter<'_, R> {
fn len(&self) -> usize {
self.how_many - self.i
}
}
pub type Lender<'a, R> = lender::Take<<R as SequentialLabeling>::Lender<'a>>;
pub type IntoIterator<'a, R> = Iter<'a, R>;
}