use core::{
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>(PhantomData<T>);
const impl<T> Clone for Empty<T>
{
fn clone(&self) -> Self
{
Self(PhantomData)
}
}
impl<T> fmt::Debug for Empty<T>
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
f.debug_struct("Empty").finish()
}
}
const impl<T> IntoIterator for Empty<T>
{
type IntoIter = core::iter::Empty<T>;
type Item = T;
fn into_iter(self) -> Self::IntoIter
{
core::iter::empty()
}
}
const impl<T> IntoBulk for core::iter::Empty<T>
{
type IntoBulk = Empty<T>;
fn into_bulk(self) -> Self::IntoBulk
{
empty()
}
}
const impl<T> Bulk for Empty<T>
{
type MaxLength = [(); 0];
type MinLength = [(); 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 = ()>
{
let _ = f;
R::from_output(())
}
}
const impl<T> DoubleEndedBulk for Empty<T>
{
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 = ()>
{
let _ = f;
R::from_output(())
}
}
const impl<T, L> SplitBulk<L> for Empty<T>
where
L: LengthValue
{
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<Array<()> = [(); 0]> {}
const impl<T> EmptyBulk for T where T: [const] DoubleEndedBulk + StaticBulk<Array<()> = [(); 0]> {}
#[cfg(test)]
mod test
{
use crate::Bulk;
#[test]
fn it_works()
{
let a = const { crate::empty::<u8>().collect_array() };
assert_eq!(a, [])
}
}