use super::Array;
use core::{
mem::{
MaybeUninit,
forget
},
slice::{
Iter,
IterMut
},
iter::{
ExactSizeIterator,
DoubleEndedIterator,
FusedIterator,
TrustedLen
},
marker::Destruct
};
pub struct Iterable<Type, const N: usize> {
index: usize,
reduced: usize,
length: usize,
data: MaybeUninit<[Type; N]>
}
const impl<Type: [const] Destruct, const N: usize> Drop for Iterable<Type, N> {
fn drop(&mut self) {while let Some(value) = self.next() {drop(value)}}
}
const impl<Type, const N: usize> Iterator for Iterable<Type, N> {
type Item = Type;
fn next(&mut self) -> Option<Self::Item> {
return if self.length - self.reduced - self.index == 0 {None} else {
let value = unsafe {(self.data.as_ptr() as *const Type).add(self.index).read()};
self.index += 1;
Some(value)
}
}
fn size_hint(&self) -> (usize, Option<usize>) {return (self.length - self.index, Some(self.length - self.index))}
}
impl<Type, const N: usize> ExactSizeIterator for Iterable<Type, N> {}
const impl<Type, const N: usize> DoubleEndedIterator for Iterable<Type, N> {
fn next_back(&mut self) -> Option<Self::Item> {
return if self.length - self.reduced - self.index == 0 {None} else {
let value = unsafe {(self.data.as_ptr() as *const Type).add(self.length - 1 - self.reduced).read()};
self.reduced += 1;
Some(value)
}
}
}
impl<Type, const N: usize> FusedIterator for Iterable<Type, N> {}
unsafe impl<Type, const N: usize> TrustedLen for Iterable<Type, N> {}
impl<Type, const N: usize> FromIterator<Type> for Array<Type, N> {
fn from_iter<T: IntoIterator<Item = Type>>(iter: T) -> Self {
let mut array = Self::new();
array.extend(iter);
return array;
}
}
const impl<Type, const N: usize> IntoIterator for Array<Type, N> {
type Item = Type;
type IntoIter = Iterable<Type, N>;
fn into_iter(self) -> Self::IntoIter {
let iterator = Self::IntoIter {
index: 0,
reduced: 0,
length: self.length,
data: unsafe {MaybeUninit::new(self.data.as_ptr().read())}
};
forget(self);
return iterator;
}
}
const impl<'valid, Type, const N: usize> IntoIterator for &'valid Array<Type, N> {
type Item = &'valid Type;
type IntoIter = Iter<'valid, Type>;
fn into_iter(self) -> Self::IntoIter {self.iter()}
}
const impl<'valid, Type, const N: usize> IntoIterator for &'valid mut Array<Type, N> {
type Item = &'valid mut Type;
type IntoIter = IterMut<'valid, Type>;
fn into_iter(self) -> Self::IntoIter {self.iter_mut()}
}