use core::{borrow::Borrow, fmt, marker::{Destruct, PhantomData}};
use array_trait::length::LengthValue;
use crate::{Bulk, DoubleEndedBulk, IntoBulk, SplitBulk, StaticBulk};
pub const fn empty<T>() -> Empty<T>
{
Empty(PhantomData)
}
#[must_use = "bulks are lazy and do nothing unless consumed"]
pub struct Empty<T, P = T>(PhantomData<(T, P)>)
where
T: Borrow<P>;
impl<T, P> const Clone for Empty<T, P>
where
T: Borrow<P>
{
fn clone(&self) -> Self
{
Self(PhantomData)
}
}
impl<T, P> fmt::Debug for Empty<T, P>
where
T: Borrow<P>
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
f.debug_struct("Empty").finish()
}
}
impl<T, P> IntoIterator for Empty<T, P>
where
T: Borrow<P>
{
type Item = T;
type IntoIter = core::iter::Empty<T>;
fn into_iter(self) -> Self::IntoIter
{
core::iter::empty()
}
}
impl<T> const IntoBulk for core::iter::Empty<T>
{
type IntoBulk = Empty<T>;
fn into_bulk(self) -> Self::IntoBulk
{
empty()
}
}
impl<T, P> const Bulk for Empty<T, P>
where
T: Borrow<P>
{
type MinLength = [(); 0];
type MaxLength = [(); 0];
fn len(&self) -> usize
{
0
}
fn is_empty(&self) -> bool
{
true
}
fn first(self) -> Option<Self::Item>
where
Self::Item: ~const Destruct,
Self: Sized
{
None
}
fn last(self) -> Option<Self::Item>
where
Self::Item: ~const Destruct,
Self: Sized
{
None
}
fn nth<L>(self, _n: L) -> Option<Self::Item>
where
Self: Sized,
Self::Item: ~const Destruct,
L: LengthValue
{
None
}
fn for_each<F>(self, f: F)
where
Self: Sized,
F: ~const FnMut(Self::Item) + ~const Destruct
{
let _ = f;
}
fn try_for_each<F, R>(self, f: F) -> R
where
Self: Sized,
F: ~const FnMut(Self::Item) -> R + ~const Destruct,
R: ~const core::ops::Try<Output = (), Residual: ~const Destruct>
{
let _ = f;
R::from_output(())
}
}
impl<T, P> const DoubleEndedBulk for Empty<T, P>
where
T: Borrow<P>
{
fn rev_for_each<F>(self, f: F)
where
Self: Sized,
F: ~const FnMut(Self::Item) + ~const Destruct
{
let _ = f;
}
fn try_rev_for_each<F, R>(self, f: F) -> R
where
Self: Sized,
F: ~const FnMut(Self::Item) -> R + ~const Destruct,
R: ~const core::ops::Try<Output = (), Residual: ~const Destruct>
{
let _ = f;
R::from_output(())
}
}
impl<T, P, L> const SplitBulk<L> for Empty<T, P>
where
L: LengthValue,
T: Borrow<P>
{
type Left = Self;
type Right = Self;
fn split_at(bulk: Self, _n: L) -> (Self::Left, Self::Right)
where
Self: Sized
{
(bulk.clone(), bulk)
}
}
pub const trait EmptyBulk: ~const DoubleEndedBulk + StaticBulk<Length = [(); 0]>
{
}
impl<T> const EmptyBulk for T
where
T: ~const DoubleEndedBulk + StaticBulk<Length = [(); 0]>
{
}
#[cfg(test)]
mod test
{
use crate::Bulk;
#[test]
fn it_works()
{
let a = const {
crate::empty::<u8>().collect_array()
};
assert_eq!(a, [])
}
}