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
kindIsIteratorKind
kind- Standard library types, of the
IsStdKind
kind
§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 {
§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.
§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§
Sourcetype Kind
type Kind
What kind of type this is:
IsIntoIterKind
: user-defined types that are convertible to const iteratorsIsIteratorKind
: const iteratorsIsStdKind
: standard library types that are convertible to const iterators
Sourcetype IntoIter: ConstIntoIter<Item = Self::Item>
type IntoIter: ConstIntoIter<Item = Self::Item>
The iterator that this can be converted into.