devela/data/collections/stack/
impl_traits.rs#[cfg(feature = "alloc")]
use crate::Boxed;
use crate::{
Array, Bare, ConstDefault, DataCollection, DataStack, NotAvailable, NotEnoughElements,
NotEnoughSpace, Ordering, Stack, StackIter, Storage, _core::fmt,
};
macro_rules! impl_stack {
() => {
impl_stack![
u8:"_stack_u8", u16:"_stack_u16", u32:"_stack_u32", usize:"_stack_usize"];
};
($( $IDX:ty: $cap:literal ),+) => {
$(
#[cfg(feature = $cap )]
impl_stack![@$IDX:$cap];
)+
};
(@$IDX:ty : $cap:literal) => { crate::paste! {
impl<T, const LEN: usize, S: Storage> DataCollection for Stack<T, LEN, $IDX, S> {
type Element = T;
fn collection_capacity(&self)
-> Result<usize, NotAvailable> { Ok(self.capacity() as usize) }
fn collection_len(&self)
-> Result<usize, NotAvailable> { Ok(self.len() as usize) }
fn collection_is_empty(&self)
-> Result<bool, NotAvailable> { Ok(self.is_empty()) }
fn collection_is_full(&self)
-> Result<bool, NotAvailable> { Ok(self.is_full()) }
fn collection_contains(&self, element: Self::Element)
-> Result<bool, NotAvailable> where T: PartialEq {
Ok(self.contains(&element)) }
fn collection_count(&self, element: &Self::Element)
-> Result<usize, NotAvailable> where T: PartialEq {
Ok(self.iter().filter(|&e| e == element).count()) }
}
#[rustfmt::skip]
#[cfg(any(feature = "safe_data", not(feature = "unsafe_ptr")))]
impl<T: Clone, const CAP: usize, S: Storage> DataStack for Stack<T, CAP, $IDX, S> {
fn stack_pop(&mut self)
-> Result<<Self as DataCollection>::Element, NotEnoughElements> {
self.pop()
}
fn stack_push(&mut self, element: <Self as DataCollection>::Element)
-> Result<(), NotEnoughSpace> {
self.push(element)
}
}
#[rustfmt::skip]
#[cfg(all(not(feature = "safe_data"), feature = "unsafe_ptr"))]
impl<T, const CAP: usize, S: Storage> DataStack for Stack<T, CAP, $IDX, S> {
fn stack_pop(&mut self)
-> Result<<Self as DataCollection>::Element, NotEnoughElements> {
self.pop()
}
fn stack_push(&mut self, element: <Self as DataCollection>::Element)
-> Result<(), NotEnoughSpace> {
self.push(element)
}
}
impl<T: Default, I, const CAP: usize> From<I> for Stack<T, CAP, $IDX, Bare>
where
I: IntoIterator<Item = T>,
{
fn from(iterator: I) -> Stack<T, CAP, $IDX, Bare> {
let mut s = Stack::<T, CAP, $IDX, Bare>::default();
let _ = s.extend(iterator);
s
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "alloc")))]
impl<T: Default, I, const CAP: usize> From<I> for Stack<T, CAP, $IDX, Boxed>
where
I: IntoIterator<Item = T>,
{
fn from(iterator: I) -> Stack<T, CAP, $IDX, Boxed> {
let mut s = Stack::<T, CAP, $IDX, Boxed>::default();
let _ = s.extend(iterator);
s
}
}
impl<'s, T, const CAP: usize, S: Storage> Iterator for StackIter<'s, T, CAP, $IDX, S> {
type Item = &'s T;
fn next(&mut self) -> Option<Self::Item> {
let item = if self.idx == self.stack.len as usize {
None
} else {
Some(&self.stack.data[self.idx])
};
self.idx += 1;
item
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.stack.len as usize, Some(self.stack.len as usize))
}
}
impl<'s, T, const CAP: usize, S: Storage> ExactSizeIterator
for StackIter<'s, T, CAP, $IDX, S> {}
impl<T: PartialOrd, const CAP: usize, S: Storage> PartialOrd for Stack<T, CAP, $IDX, S>
where
S::Stored<[T; CAP]>: PartialOrd,
{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.iter().partial_cmp(other.iter())
}
}
impl<T: Ord, const CAP: usize, S: Storage> Ord for Stack<T, CAP, $IDX, S>
where
S::Stored<[T; CAP]>: Ord,
{
fn cmp(&self, other: &Self) -> Ordering {
self.iter().cmp(other.iter())
}
}
}};
}
impl_stack!();
impl<T: Clone, const CAP: usize, IDX: Copy, S: Storage> Clone for Stack<T, CAP, IDX, S>
where
S::Stored<[T; CAP]>: Clone,
{
fn clone(&self) -> Self {
Self { data: self.data.clone(), len: self.len }
}
}
impl<T: Copy, const CAP: usize, IDX: Copy, S: Storage> Copy for Stack<T, CAP, IDX, S> where
S::Stored<[T; CAP]>: Copy
{
}
impl<T: fmt::Debug, const CAP: usize, IDX: fmt::Debug, S: Storage> fmt::Debug
for Stack<T, CAP, IDX, S>
where
S::Stored<[T; CAP]>: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Stack")
.field("CAP", &CAP)
.field("len", &self.len)
.field("data", &self.data)
.finish()
}
}
impl<T: PartialEq, const CAP: usize, IDX: PartialEq, S: Storage> PartialEq for Stack<T, CAP, IDX, S>
where
S::Stored<[T; CAP]>: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.data == other.data && self.len == other.len
}
}
impl<T: Eq, const CAP: usize, IDX: Eq, S: Storage> Eq for Stack<T, CAP, IDX, S> where
S::Stored<[T; CAP]>: Eq
{
}
impl<T: Default, const CAP: usize, IDX: Default> Default for Stack<T, CAP, IDX, Bare> {
fn default() -> Self {
Self { data: Array::default(), len: IDX::default() }
}
}
impl<T: ConstDefault, const CAP: usize, IDX: ConstDefault> ConstDefault
for Stack<T, CAP, IDX, Bare>
{
const DEFAULT: Self = Self { data: Array::DEFAULT, len: IDX::DEFAULT };
}
#[cfg(feature = "alloc")]
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "alloc")))]
impl<T: Default, const CAP: usize, IDX: Default> Default for Stack<T, CAP, IDX, Boxed> {
fn default() -> Self {
Self { data: Array::default(), len: IDX::default() }
}
}