use std::iter::FromIterator;
use super::Spawner;
pub mod all_any;
pub mod collect;
pub mod fold;
mod cost_mul;
mod enumerate;
mod filter;
mod flat_map;
mod map;
mod vec;
mod zip;
pub use self::collect::Combine;
pub trait Spliterator: Sized {
type Item;
type Base: Split;
type Consumer: Consumer<Self::Base, Item=Self::Item>;
fn destructure(self) -> (Self::Base, Self::Consumer);
fn cloned<'a, T: 'a + Clone>(self) -> Cloned<Self> where Self: Spliterator<Item=&'a T> {
Cloned {
parent: self,
}
}
fn enumerate(self) -> Enumerate<Self> {
Enumerate {
parent: self,
off: 0,
}
}
fn filter<F: Sync>(self, pred: F) -> Filter<Self, F> where F: Fn(&Self::Item) -> bool {
Filter {
parent: self,
pred: pred,
}
}
fn flat_map<U, F: Sync>(self, flat_map: F) -> FlatMap<Self, F>
where U: IntoIterator, F: Fn(Self::Item) -> U {
FlatMap {
parent: self,
flat_map: flat_map
}
}
fn map<F: Sync, U>(self, map: F) -> Map<Self, F> where F: Fn(Self::Item) -> U {
Map {
parent: self,
map: map,
}
}
fn zip<B: IntoSpliterator>(self, other: B) -> Zip<Self, B::SplitIter> {
Zip {
a: self,
b: other.into_split_iter(),
}
}
fn any<P: Sync>(self, spawner: &Spawner, pred: P) -> bool
where P: Fn(Self::Item) -> bool {
all_any::any(self, spawner, pred)
}
fn all<P: Sync>(self, spawner: &Spawner, pred: P) -> bool
where P: Fn(Self::Item) -> bool {
all_any::all(self, spawner, pred)
}
fn for_each<F>(self, spawner: &Spawner, f: F) where F: Sync + Fn(Self::Item) {
let (base, consumer) = self.destructure();
for_each_helper::<Self, F>(base, &consumer, spawner, &f);
}
fn collect<T: Send>(self, spawner: &Spawner) -> T
where Self::Item: Send, T: FromIterator<Self::Item> + Combine + Send {
collect::collect(self, spawner)
}
fn fold<F: Sync>(self, spawner: &Spawner, initial: Self::Item, folder: F) -> Self::Item
where F: fold::Folder<Self::Item>, Self::Item: Send {
fold::fold(self, spawner, initial, folder)
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
fn with_cost_mul(self, mul: f32) -> CostMul<Self> {
let mul = if mul < 0.0 { -mul } else { mul };
CostMul {
parent: self,
mul: mul,
}
}
}
fn for_each_helper<T, F>(base: T::Base, consumer: &T::Consumer, spawner: &Spawner, f: &F)
where T: Spliterator, F: Sync + Fn(T::Item) {
if let Some(idx) = base.should_split(1.0) {
let (b1, b2) = base.split(idx);
spawner.join(
move |inner| for_each_helper::<T, F>(b1, consumer, inner, f),
move |inner| for_each_helper::<T, F>(b2, consumer, inner, f),
);
} else {
consumer.consume(base, f);
}
}
pub trait ExactSizeSpliterator: Spliterator {
fn size(&self) -> usize;
}
#[derive(Clone)]
pub struct Cloned<T> {
parent: T,
}
#[derive(Clone)]
pub struct Enumerate<T> {
parent: T,
off: usize,
}
#[derive(Clone)]
pub struct Filter<T, F> {
parent: T,
pred: F,
}
#[derive(Clone)]
pub struct FlatMap<T, F> {
parent: T,
flat_map: F,
}
#[derive(Clone)]
pub struct Map<T, F> {
parent: T,
map: F,
}
#[derive(Clone)]
pub struct Zip<A, B> {
a: A,
b: B,
}
#[derive(Clone)]
pub struct CostMul<T> {
parent: T,
mul: f32,
}
pub trait Split: Sized + Send + IntoIterator {
fn should_split(&self, mul: f32) -> Option<usize>;
fn split(self, usize) -> (Self, Self);
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
}
impl<T: Split> Spliterator for T {
type Item = T::Item;
type Base = Self;
type Consumer = ();
fn destructure(self) -> (Self, ()) {
(self, ())
}
fn size_hint(&self) -> (usize, Option<usize>) {
Split::size_hint(self)
}
}
pub trait IntoSpliterator {
type Item;
type SplitIter: Spliterator<Item=Self::Item>;
fn into_split_iter(self) -> Self::SplitIter;
}
impl<T: Spliterator> IntoSpliterator for T {
type Item = <Self as Spliterator>::Item;
type SplitIter = Self;
fn into_split_iter(self) -> Self::SplitIter {
self
}
}
pub trait BorrowSpliterator<'a> {
type Item: 'a;
type SplitIter: 'a + Spliterator<Item=Self::Item>;
fn split_iter(&'a self) -> Self::SplitIter;
}
pub trait BorrowSpliteratorMut<'a> {
type Item: 'a;
type SplitIter: 'a + Spliterator<Item=Self::Item>;
fn split_iter_mut(&'a mut self) -> Self::SplitIter;
}
impl<'a, T: 'a + Sync> IntoSpliterator for &'a [T] {
type Item = &'a T;
type SplitIter = SliceSplit<'a, T>;
fn into_split_iter(self) -> Self::SplitIter {
SliceSplit(self)
}
}
impl<'a, T: 'a + Sync + Send> IntoSpliterator for &'a mut [T] {
type Item = &'a mut T;
type SplitIter = SliceSplitMut<'a, T>;
fn into_split_iter(self) -> Self::SplitIter {
SliceSplitMut(self)
}
}
impl<'a, T: 'a + Sync> IntoSpliterator for &'a Vec<T> {
type Item = &'a T;
type SplitIter = SliceSplit<'a, T>;
fn into_split_iter(self) -> Self::SplitIter {
SliceSplit(&self)
}
}
impl<'a, T: 'a + Sync + Send> IntoSpliterator for &'a mut Vec<T> {
type Item = &'a mut T;
type SplitIter = SliceSplitMut<'a, T>;
fn into_split_iter(self) -> Self::SplitIter {
SliceSplitMut(self)
}
}
impl<'a, T: 'a + Sync> BorrowSpliterator<'a> for Vec<T> {
type Item = &'a T;
type SplitIter = SliceSplit<'a, T>;
fn split_iter(&'a self) -> Self::SplitIter {
SliceSplit(&*self)
}
}
impl<'a, T: 'a + Sync + Send> BorrowSpliteratorMut<'a> for Vec<T> {
type Item = &'a mut T;
type SplitIter = SliceSplitMut<'a, T>;
fn split_iter_mut(&'a mut self) -> Self::SplitIter {
SliceSplitMut(&mut *self)
}
}
pub struct Hide<T>(T);
pub struct SliceSplit<'a, T: 'a>(&'a [T]);
pub struct SliceSplitMut<'a, T: 'a>(&'a mut [T]);
impl<'a, T: 'a> Clone for SliceSplit<'a, T> {
fn clone(&self) -> Self {
SliceSplit(self.0)
}
}
impl<'a, T: 'a> IntoIterator for SliceSplit<'a, T> {
type Item = <&'a [T] as IntoIterator>::Item;
type IntoIter = <&'a [T] as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter { self.0.into_iter() }
}
impl<'a, T: 'a> IntoIterator for SliceSplitMut<'a, T> {
type Item = <&'a mut [T] as IntoIterator>::Item;
type IntoIter = <&'a mut [T] as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter { self.0.into_iter() }
}
impl<'a, T: 'a + Sync> Split for SliceSplit<'a, T> {
fn should_split(&self, mul: f32) -> Option<usize> {
let len = self.0.len();
if len > 1 && (len as f32 *mul) > 4096.0 { Some(len / 2) }
else { None }
}
fn split(self, idx: usize) -> (Self, Self) {
let (a, b) = self.0.split_at(idx);
(
SliceSplit(a),
SliceSplit(b),
)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.0.len();
(len, Some(len))
}
}
impl<'a, T: 'a + Sync + Send> Split for SliceSplitMut<'a, T> {
fn should_split(&self, mul: f32) -> Option<usize> {
let len = self.0.len();
if len > 1 && (len as f32 * mul) > 4096.0 { Some(len / 2) }
else { None }
}
fn split(self, idx: usize) -> (Self, Self) {
let (a, b) = self.0.split_at_mut(idx);
(
SliceSplitMut(a),
SliceSplitMut(b),
)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.0.len();
(len, Some(len))
}
}
impl<'a, T: 'a + Sync> ExactSizeSpliterator for SliceSplit<'a, T> {
fn size(&self) -> usize {
self.0.len()
}
}
impl<'a, T: 'a + Sync + Send> ExactSizeSpliterator for SliceSplitMut<'a, T> {
fn size(&self) -> usize {
self.0.len()
}
}
pub trait Callback<T>: Sized {
type Out;
fn call<I: Iterator<Item=T>>(self, I) -> Self::Out;
}
impl<F, T> Callback<T> for F where F: FnMut(T) {
type Out = ();
fn call<I: Iterator<Item=T>>(mut self, iter: I) {
for i in iter {
(self)(i)
}
}
}
pub trait Consumer<In: IntoIterator>: Sync {
type Item;
fn consume<C: Callback<Self::Item>>(&self, i: In, cb: C) -> C::Out;
}
impl<In: IntoIterator> Consumer<In> for () {
type Item = In::Item;
fn consume<C: Callback<Self::Item>>(&self, i: In, cb: C) -> C::Out {
cb.call(i.into_iter())
}
}
#[cfg(test)]
mod tests {
use ::{pool_harness, IntoSpliterator, Spliterator};
#[test]
fn doubling() {
let v: Vec<_> = (0..5000).collect();
pool_harness(|pool| {
let mut v1 = v.clone();
(&mut v1).into_split_iter().for_each(&pool.spawner(), |x| *x *= 2);
assert_eq!(v1, (0..5000).map(|x| x * 2).collect::<Vec<_>>());
});
}
}