konst::iter

Trait ConstIntoIter

Source
pub trait ConstIntoIter {
    type Kind;
    type Item;
    type IntoIter: ConstIntoIter<Item = Self::Item>;
}
Expand description

Const analog of the IntoIterator trait.

§Implementor

Implementors are expected to be one of these:

§IsIntoIterKind

These are user-defined types convertible to const iterators.

These implement ConstIntoIter<Kind = IsIntoIterKind> and are expected to define this inherent method for converting to a const iterator:

const fn const_into_iter(self) -> SomeIterator {

full example below

§IsIteratorKind

These are const iterator types.

These implement ConstIntoIter<Kind = IsIteratorKind> and are expected to define this inherent method:

// Equivalent to `Iterator::next`
const fn next(self) -> Option<(Item, Self)> {

Where Item can be any type.

These are other methods that you can optionaly define, which most iterators from the konst crate define:

// equivalent to `DoubleEndedÌterator::mext_back`
const fn next_back(self) -> Option<(Item, Self)> {
    // ... some code...
}

// Reverses the iterator, equivalent to `Iterator::rev`
const fn rev(self) -> SomeIteratorRev {
    // ... some code...
}

// Clones the iterator, equivalent to `Clone::clone`
const fn copy(&self) -> Self {
    // ... some code...
}

Where SomeIteratorRev should be a ConstIntoIter<Kind = IsIteratorKind> which has the same inherent methods for iteration, and returns the same Item type.

full example below

§Examples

§Implementing for an into-iterator

use konst::{iter, slice};

struct GetSlice<'a, T>{
    slice: &'a [T],
    up_to: usize,
}

impl<'a, T> iter::ConstIntoIter for GetSlice<'a, T> {
    type Kind = iter::IsIntoIterKind;
    type IntoIter = konst::slice::Iter<'a, T>;
    type Item = &'a T;
}

impl<'a, T> GetSlice<'a, T> {
    const fn const_into_iter(self) -> konst::slice::Iter<'a, T> {
        slice::iter(slice::slice_up_to(self.slice, self.up_to))
    }
}

const fn sum_powers(up_to: usize) -> u64 {
    let gs = GetSlice{slice: &[1, 2, 4, 8, 16, 32, 64, 128], up_to};

    iter::eval!(gs,fold(0, |l, &r| l + r))
}

assert_eq!(sum_powers(0), 0);
assert_eq!(sum_powers(1), 1);
assert_eq!(sum_powers(2), 3);
assert_eq!(sum_powers(3), 7);
assert_eq!(sum_powers(4), 15);
assert_eq!(sum_powers(5), 31);

§Implementing for an iterator

use konst::iter::{self, ConstIntoIter};

struct Countdown(u8);

impl ConstIntoIter for Countdown {
    type Kind = iter::IsIteratorKind;
    type IntoIter = Self;
    type Item = u8;
}

impl Countdown {
    const fn next(mut self) -> Option<(u8, Self)> {
        konst::option::map!(self.0.checked_sub(1), |ret| {
            self.0 = ret;
            (ret, self)
        })
    }
}

const fn sum(initial: u8) -> u16 {
    iter::eval!(Countdown(initial),fold(0u16, |accum, elem| accum + elem as u16))
}

assert_eq!(sum(0), 0);
assert_eq!(sum(1), 0);
assert_eq!(sum(2), 1);
assert_eq!(sum(3), 3);
assert_eq!(sum(4), 6);
assert_eq!(sum(5), 10);

§Implementing for a double-ended iterator

use konst::iter;

assert_eq!(HOURS, [1, 2, 3, 4, 5, 6, 12, 11, 10, 9, 8, 7]);

const HOURS: [u8; 12] = {
    let mut arr = [0; 12];
    let hours = Hours::new();

    iter::for_each!{(i, hour) in 0..6,zip(hours.copy()) =>
        arr[i] = hour;
    }
    iter::for_each!{(i, hour) in 6..12,zip(hours.rev()) =>
        arr[i] = hour;
    }

    arr
};


struct Hours{
    start: u8,
    end: u8,
}

impl iter::ConstIntoIter for Hours {
    type Kind = iter::IsIteratorKind;
    type IntoIter = Self;
    type Item = u8;
}

impl Hours {
    const fn new() -> Self {
        Self {start: 1, end: 13}
    }

    const fn next(mut self) -> Option<(u8, Self)> {
        if self.start == self.end {
            None
        } else {
            let ret = self.start;
            self.start += 1;
            Some((ret, self))
        }
    }

    const fn next_back(mut self) -> Option<(u8, Self)> {
        if self.start == self.end {
            None
        } else {
            self.end -= 1;
            Some((self.end, self))
        }
    }

    const fn rev(self) -> HoursRev {
        HoursRev(self)
    }

    /// Since `Clone::clone` isn't const callable on stable,
    /// clonable iterators must define an inherent method to be cloned
    const fn copy(&self) -> Self {
        let Self{start, end} = *self;
        Self{start, end}
    }
}

struct HoursRev(Hours);

impl iter::ConstIntoIter for HoursRev {
    type Kind = iter::IsIteratorKind;
    type IntoIter = Self;
    type Item = u8;
}

impl HoursRev {
    const fn next(self) -> Option<(u8, Self)> {
        konst::option::map!(self.0.next_back(), |(a, h)| (a, HoursRev(h)))
    }

    const fn next_back(self) -> Option<(u8, Self)> {
        konst::option::map!(self.0.next(), |(a, h)| (a, HoursRev(h)))
    }

    const fn rev(self) -> Hours {
        self.0
    }

    const fn copy(&self) -> Self {
        Self(self.0.copy())
    }
}

Required Associated Types§

Source

type Kind

What kind of type this is:

Source

type Item

The item that Self::IntoIter yields on .next()

Source

type IntoIter: ConstIntoIter<Item = Self::Item>

The iterator that this can be converted into.

Implementations on Foreign Types§

Source§

impl<'a, T> ConstIntoIter for &&'a [T]

Source§

impl<'a, T> ConstIntoIter for &'a [T]

Source§

impl<'a, T, const N: usize> ConstIntoIter for &&'a [T; N]

Source§

impl<'a, T, const N: usize> ConstIntoIter for &'a [T; N]

Source§

impl<T> ConstIntoIter for &Range<T>
where T: Step,

Source§

impl<T> ConstIntoIter for &RangeFrom<T>
where T: Step,

Source§

impl<T> ConstIntoIter for &RangeInclusive<T>
where T: Step,

Source§

impl<T> ConstIntoIter for Range<T>
where T: Step,

Source§

impl<T> ConstIntoIter for RangeFrom<T>
where T: Step,

Source§

impl<T> ConstIntoIter for RangeInclusive<T>
where T: Step,

Implementors§

Source§

impl ConstIntoIter for CharIndices<'_>

Source§

impl ConstIntoIter for Chars<'_>

Source§

impl ConstIntoIter for RCharIndices<'_>

Source§

impl ConstIntoIter for RChars<'_>

Source§

impl<'a, 'p, P: Pattern<'p>> ConstIntoIter for RSplit<'a, 'p, P>

Source§

impl<'a, 'p, P: Pattern<'p>> ConstIntoIter for RSplitTerminator<'a, 'p, P>

Source§

impl<'a, 'p, P: Pattern<'p>> ConstIntoIter for Split<'a, 'p, P>

Source§

impl<'a, 'p, P: Pattern<'p>> ConstIntoIter for SplitTerminator<'a, 'p, P>

Source§

impl<'a, T> ConstIntoIter for Chunks<'a, T>

Source§

impl<'a, T> ConstIntoIter for ChunksExact<'a, T>

Source§

impl<'a, T> ConstIntoIter for ChunksExactRev<'a, T>

Source§

impl<'a, T> ConstIntoIter for ChunksRev<'a, T>

Source§

impl<'a, T> ConstIntoIter for Iter<'a, T>

Source§

impl<'a, T> ConstIntoIter for IterCopied<'a, T>

Source§

impl<'a, T> ConstIntoIter for IterCopiedRev<'a, T>

Source§

impl<'a, T> ConstIntoIter for IterRev<'a, T>

Source§

impl<'a, T> ConstIntoIter for RChunks<'a, T>

Source§

impl<'a, T> ConstIntoIter for RChunksExact<'a, T>

Source§

impl<'a, T> ConstIntoIter for RChunksExactRev<'a, T>

Source§

impl<'a, T> ConstIntoIter for RChunksRev<'a, T>

Source§

impl<'a, T> ConstIntoIter for Windows<'a, T>

Source§

impl<'a, T> ConstIntoIter for WindowsRev<'a, T>

Source§

impl<'a, T, const N: usize> ConstIntoIter for ArrayChunks<'a, T, N>

Source§

impl<'a, T, const N: usize> ConstIntoIter for ArrayChunksRev<'a, T, N>

Source§

impl<T> ConstIntoIter for RangeFromIter<T>
where T: Step,

Source§

impl<T> ConstIntoIter for RangeInclusiveIter<T>
where T: Step,

Source§

impl<T> ConstIntoIter for RangeInclusiveIterRev<T>
where T: Step,

Source§

impl<T> ConstIntoIter for RangeIter<T>
where T: Step,

Source§

impl<T> ConstIntoIter for RangeIterRev<T>
where T: Step,

Source§

impl<T> ConstIntoIter for Repeat<T>