orx_iterable::obj_safe

Trait IterableObj

Source
pub trait IterableObj {
    type Item;

    // Required method
    fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_>;
}
Expand description

An IterableObj is any type which can return a new boxed iterator that yields elements of the associated type Item every time boxed_iter method is called.

It is the object safe counterpart of Iterable trait which can conveniently be made into a trait object.

Instead of iter, it implements boxed_iter which returns the same iterator in a box.

Note that for collections and cloneable iterators, IterableObj is implicitly implemented and readily available. Please refer to Iterable documentation for details of automatic implementations.

In order to use object safe iterables and collections please add --features std and use use orx_iterable::{*, obj_safe::*} to import dependencies rather than use orx_iterable::*.

§Examples

use orx_iterable::{*, obj_safe::*};
use arrayvec::ArrayVec;
use smallvec::{smallvec, SmallVec};
use std::collections::{BTreeSet, BinaryHeap, HashSet, LinkedList, VecDeque};

struct Stats {
    count: usize,
    mean: i64,
    std_dev: i64,
}

/// we need multiple iterations over numbers to compute the stats
fn statistics<'a>(numbers: Box<dyn IterableObj<Item = i64> + 'a>) -> Stats {
    let count = numbers.boxed_iter().count() as i64;
    let sum = numbers.boxed_iter().sum::<i64>();
    let mean = sum / count;
    let sum_sq_errors: i64 = numbers.boxed_iter().map(|x| (x - mean) * (x - mean)).sum();
    let std_dev = f64::sqrt(sum_sq_errors as f64 / (count - 1) as f64) as i64;
    Stats {
        count: count as usize,
        mean,
        std_dev,
    }
}

// collections as IterableObj

let x = [3, 5, 7];
statistics(Box::new(x.copied()));
// see IterableObj's transformation methods such as copied, mapped, etc.

let x = vec![3, 5, 7];
statistics(Box::new(x.copied()));

let x = LinkedList::from_iter([3, 5, 7]);
statistics(Box::new(x.copied()));

let x = VecDeque::from_iter([3, 5, 7]);
statistics(Box::new(x.copied()));

let x = HashSet::<_>::from_iter([3, 5, 7]);
statistics(Box::new(x.copied()));

let x = BTreeSet::from_iter([3, 5, 7]);
statistics(Box::new(x.copied()));

let x = BinaryHeap::from_iter([3, 5, 7]);
statistics(Box::new(x.copied()));

let x: SmallVec<[_; 128]> = smallvec![3, 5, 7];
statistics(Box::new(x.copied()));

let mut x = ArrayVec::<_, 16>::new();
x.extend([3, 5, 7]);
statistics(Box::new(x.copied()));

// cloneable iterators as IterableObj

let x = Box::new((0..10).map(|x| x * 2).into_iterable());
statistics(x);

let x = vec![1, 2, 3];
let y = Box::new(x
    .iter()
    .copied()
    .filter(|x| x % 2 == 1)
    .flat_map(|x| [-x, x])
    .into_iterable());
statistics(y);

// lazy generators as IterableObj

statistics(Box::new(7..21i64));

The following example represents an explicit implementation of the Iterable trait for a lazy generator, which generates a sequence of Fibonacci numbers up to a set bound.

use orx_iterable::*;
use orx_iterable::obj_safe::*;

struct FibUntilIter {
    curr: u32,
    next: u32,
    until: u32,
}

impl Iterator for FibUntilIter {
    type Item = u32;

    fn next(&mut self) -> Option<Self::Item> {
        let current = self.curr;
        self.curr = self.next;
        self.next = current + self.next;
        match current > self.until {
            false => Some(current),
            true => None,
        }
    }
}

struct FibUntil(u32);

impl IterableObj for FibUntil {
    type Item = u32;

    fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_> {
        Box::new(FibUntilIter { curr: 0, next: 1, until: self.0 })
    }
}

let fib = FibUntil(10); // IterableObj

assert_eq!(fib.boxed_iter().count(), 7);
assert_eq!(fib.boxed_iter().max(), Some(8));
assert_eq!(fib.boxed_iter().collect::<Vec<_>>(), [0, 1, 1, 2, 3, 5, 8]);

Required Associated Types§

Source

type Item

Type of the item that the iterators created by the boxed_iter method yields.

Required Methods§

Source

fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_>

Creates a new iterator in a box from this iterable yielding elements of type IterableObj::Item.

Implementations on Foreign Types§

Source§

impl IterableObj for Range<i8>

Source§

type Item = i8

Source§

fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_>

Source§

impl IterableObj for Range<i16>

Source§

type Item = i16

Source§

fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_>

Source§

impl IterableObj for Range<i32>

Source§

type Item = i32

Source§

fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_>

Source§

impl IterableObj for Range<i64>

Source§

type Item = i64

Source§

fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_>

Source§

impl IterableObj for Range<i128>

Source§

type Item = i128

Source§

fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_>

Source§

impl IterableObj for Range<isize>

Source§

type Item = isize

Source§

fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_>

Source§

impl IterableObj for Range<u8>

Source§

type Item = u8

Source§

fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_>

Source§

impl IterableObj for Range<u16>

Source§

type Item = u16

Source§

fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_>

Source§

impl IterableObj for Range<u32>

Source§

type Item = u32

Source§

fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_>

Source§

impl IterableObj for Range<u64>

Source§

type Item = u64

Source§

fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_>

Source§

impl IterableObj for Range<u128>

Source§

type Item = u128

Source§

fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_>

Source§

impl IterableObj for Range<usize>

Source§

type Item = usize

Source§

fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_>

Source§

impl<'a, X> IterableObj for &'a [X]

Source§

type Item = &'a X

Source§

fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_>

Source§

impl<'a, X> IterableObj for &'a X

Source§

type Item = <&'a X as IntoIterator>::Item

Source§

fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_>

Source§

impl<T> IterableObj for Empty<T>

Source§

type Item = T

Source§

fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_>

Source§

impl<T> IterableObj for Once<T>
where T: Clone,

Source§

type Item = T

Source§

fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_>

Source§

impl<T> IterableObj for Repeat<T>
where T: Clone,

Source§

type Item = T

Source§

fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_>

Source§

impl<T> IterableObj for RepeatN<T>
where T: Clone,

Source§

type Item = T

Source§

fn boxed_iter(&self) -> Box<dyn Iterator<Item = Self::Item> + '_>

Implementors§

Source§

impl<'a, I1, I2, E1, E2> IterableObj for &'a ChainedCol<I1, I2, E1, E2>
where I1: Collection, I2: Collection<Item = <I1 as Collection>::Item>, E1: SoM<I1>, E2: SoM<I2>,

Source§

type Item = &'a <I1 as Collection>::Item

Source§

impl<'a, I, E> IterableObj for &'a FlattenedCol<I, E>
where I: Collection, I::Item: IntoIterator, for<'i> &'i I::Item: IntoIterator<Item = &'i <I::Item as IntoIterator>::Item>, E: SoM<I>,

Source§

type Item = &'a <<I as Collection>::Item as IntoIterator>::Item

Source§

impl<'a, I, E> IterableObj for &'a FusedCol<I, E>
where I: Collection, E: SoM<I>,

Source§

type Item = &'a <I as Collection>::Item

Source§

impl<'a, I, E> IterableObj for &'a ReversedCol<I, E>
where I: Collection, E: SoM<I>, for<'b> <I::Iterable<'b> as Iterable>::Iter: DoubleEndedIterator,

Source§

type Item = &'a <I as Collection>::Item

Source§

impl<'a, I, E> IterableObj for &'a SkippedCol<I, E>
where I: Collection, E: SoM<I>,

Source§

type Item = &'a <I as Collection>::Item

Source§

impl<'a, I, E> IterableObj for &'a SteppedByCol<I, E>
where I: Collection, E: SoM<I>,

Source§

type Item = &'a <I as Collection>::Item

Source§

impl<'a, I, E> IterableObj for &'a TakenCol<I, E>
where I: Collection, E: SoM<I>,

Source§

type Item = &'a <I as Collection>::Item

Source§

impl<'a, I, E, P> IterableObj for &'a FilteredCol<I, E, P>
where I: Collection, E: SoM<I>, P: Fn(&I::Item) -> bool + Copy,

Source§

type Item = &'a <I as Collection>::Item

Source§

impl<'a, I, E, P> IterableObj for &'a SkippedWhileCol<I, E, P>
where I: Collection, E: SoM<I>, P: Fn(&I::Item) -> bool + Copy,

Source§

type Item = &'a <I as Collection>::Item

Source§

impl<'a, I, E, P> IterableObj for &'a TakenWhileCol<I, E, P>
where I: Collection, E: SoM<I>, P: Fn(&I::Item) -> bool + Copy,

Source§

type Item = &'a <I as Collection>::Item

Source§

impl<'a, T> IterableObj for &'a EmptyCol<T>

Source§

impl<'a, T> IterableObj for &'a OnceCol<T>

Source§

impl<'a, T, I> IterableObj for Cloned<'a, T, I>
where I: Iterable<Item = &'a T>, T: Clone + 'a,

Source§

type Item = T

Source§

impl<'a, T, I> IterableObj for Copied<'a, T, I>
where I: Iterable<Item = &'a T>, T: Copy + 'a,

Source§

type Item = T

Source§

impl<I1, I2> IterableObj for Chained<I1, I2>
where I1: Iterable, I2: Iterable<Item = I1::Item>,

Source§

type Item = <I1 as Iterable>::Item

Source§

impl<I1, I2> IterableObj for Zipped<I1, I2>
where I1: Iterable, I2: Iterable,

Source§

type Item = (<I1 as Iterable>::Item, <I2 as Iterable>::Item)

Source§

impl<I> IterableObj for CloningIterable<I>
where I: Iterator + Clone,

Source§

type Item = <I as Iterator>::Item

Source§

impl<I> IterableObj for Enumerated<I>
where I: Iterable,

Source§

type Item = (usize, <I as Iterable>::Item)

Source§

impl<I> IterableObj for Flattened<I>
where I: Iterable, I::Item: IntoIterator,

Source§

impl<I> IterableObj for Fused<I>
where I: Iterable,

Source§

type Item = <I as Iterable>::Item

Source§

impl<I> IterableObj for Reversed<I>

Source§

type Item = <I as Iterable>::Item

Source§

impl<I> IterableObj for Skipped<I>
where I: Iterable,

Source§

type Item = <I as Iterable>::Item

Source§

impl<I> IterableObj for SteppedBy<I>
where I: Iterable,

Source§

type Item = <I as Iterable>::Item

Source§

impl<I> IterableObj for Taken<I>
where I: Iterable,

Source§

type Item = <I as Iterable>::Item

Source§

impl<I, M, U> IterableObj for FilterMapped<I, M, U>
where I: Iterable, M: Fn(I::Item) -> Option<U> + Copy,

Source§

type Item = U

Source§

impl<I, M, U> IterableObj for FlatMapped<I, M, U>
where I: Iterable, U: IntoIterator, M: Fn(I::Item) -> U + Copy,

Source§

impl<I, M, U> IterableObj for Mapped<I, M, U>
where I: Iterable, M: Fn(I::Item) -> U + Copy,

Source§

type Item = U

Source§

impl<I, M, U> IterableObj for MappedWhile<I, M, U>
where I: Iterable, M: Fn(I::Item) -> Option<U> + Copy,

Source§

type Item = U

Source§

impl<I, P> IterableObj for Filtered<I, P>
where I: Iterable, P: Fn(&I::Item) -> bool + Copy,

Source§

type Item = <I as Iterable>::Item

Source§

impl<I, P> IterableObj for SkippedWhile<I, P>
where I: Iterable, P: Fn(&I::Item) -> bool + Copy,

Source§

type Item = <I as Iterable>::Item

Source§

impl<I, P> IterableObj for TakenWhile<I, P>
where I: Iterable, P: Fn(&I::Item) -> bool + Copy,

Source§

type Item = <I as Iterable>::Item

Source§

impl<T> IterableObj for orx_iterable::sources::Empty<T>

Source§

type Item = T

Source§

impl<T> IterableObj for orx_iterable::sources::Once<T>
where T: Clone,

Source§

type Item = T

Source§

impl<T> IterableObj for orx_iterable::sources::Repeat<T>
where T: Clone,

Source§

type Item = T

Source§

impl<T> IterableObj for orx_iterable::sources::RepeatN<T>
where T: Clone,

Source§

type Item = T