astack/
lib.rs

1//! `astack` offers a [`Stack`] data structure with fixed capacity capable of
2//! fast LIFO operations.
3//!
4//! The crate contains:
5//! * A [`Stack`] struct, the main object used to perform TOS operations.
6//! * A [`stack`] macro, used to conveniently construct a new [`Stack`].
7//! * A [`StackError`] used by the [`Stack`] to signal an invalid operation has occurred.
8//! * A [`StackIntoIter`] struct used to iterate over the values of a [`Stack`].
9//!
10//! `astack` may be used in both std and non-std environments, and is therefore
11//! considered platform-agnostic. The crate does not require an allocator at all!
12//!
13//! You can optionally enable the `std` feature to use some additional features,
14//! such as the `std::error::Error` implementation for [`StackError`].
15//!
16//! # Examples
17//!
18//! ## Creating an empty `Stack`
19//!
20//! ```
21//! use astack::{stack, Stack};
22//!
23//! // Through the Stack::new() method
24//! let stack = Stack::<u64, 10>::new();
25//!
26//! // Through the stack! macro
27//! let stack = stack![u64; 10];
28//! ```
29//!
30//! ## Creating a `Stack` with already some items inside
31//!
32//! ```
33//! use astack::stack;
34//!
35//! // Through the stack! macro
36//! let stack = stack! {
37//!     [u64; 10] = [1, 2, 3]
38//! };
39//! ```
40//!
41//! ## Creating a `Stack` filled with items
42//!
43//! ```
44//! use astack::Stack;
45//!
46//! // A Stack filled with one single Copy item.
47//! let stack_of_44 = Stack::<u64, 10>::fill_with_copy(44);
48//!
49//! // A Stack filled with the Default implementation of u64.
50//! let stack_of_default = Stack::<u64, 10>::fill_with_default();
51//!
52//! // A Stack filled with a value based on the result of a function.
53//! let stack = Stack::<String, 10>::fill_with_fn(|i| {
54//!     format!("Value n. {}", i)
55//! });
56//! ```
57//!
58//! ## Common `Stack` operations
59//!
60//! ```
61//! use astack::stack;
62//!
63//! // Create a new Stack.
64//! let mut stack = stack! {
65//!     [i32; 4] = [10, 20, 30]
66//! };
67//!
68//! // Add an item as TOS. This returns Err if the stack if full.
69//! stack.push(40).unwrap();
70//!
71//! // Pop TOS. This returns None if the stack is empty.
72//! let last_value = stack.pop().unwrap();
73//!
74//! // Get a reference to TOS. This returns None if the stack is empty.
75//! assert_eq!(stack.tos(), Some(&30));
76//! ```
77
78#![warn(rust_2018_idioms, rust_2024_compatibility)]
79#![deny(
80    missing_docs,
81    missing_debug_implementations,
82    unsafe_op_in_unsafe_fn,
83    clippy::missing_safety_doc,
84    clippy::missing_errors_doc,
85    clippy::missing_inline_in_public_items,
86    clippy::missing_const_for_fn,
87    rustdoc::missing_crate_level_docs
88)]
89#![doc(html_playground_url = "https://play.rust-lang.org")]
90#![no_std]
91
92// https://doc.rust-lang.org/nightly/cargo/reference/features.html#feature-unification
93#[cfg(feature = "std")]
94extern crate std;
95
96mod iter;
97
98use core::{fmt, hash, mem, ptr};
99pub use iter::StackIntoIter;
100
101#[doc(hidden)]
102#[macro_export(local_inner_macros)]
103macro_rules! count_args {
104    ($_:expr,) => { 1 };
105    ($_:expr, $($others:expr,)+) => {
106        count_args!($_,) + count_args!($($others,)*)
107    }
108}
109
110/// A macro for conveniently creating a [`Stack`].
111///
112/// [`stack`] is used for 2 purposes:
113/// * Create an empty [`Stack`].
114/// * Create a [`Stack`] and push some items onto it.
115///
116/// The syntax is similar to one used to declare an array. If you wanted to create
117/// an array of `i32` (filled with `0`s) you'd have to go like this:
118/// ```
119/// let arr: [i32; 10] = [0; 10];
120/// ```
121///
122/// To create an empty [`Stack`], you can just declare your `T` and `N` in the macro
123/// like this:
124/// ```
125/// use astack::stack;
126/// let stack = stack![i32; 10];
127/// ```
128///
129/// or, if you want to both create and push some values at the same time, you can
130/// use the same array syntax:
131/// ```
132/// use astack::stack;
133/// let stack = stack! {
134///     [i32; 10] = [1, 2, 3]
135/// };
136/// ```
137///
138/// Note that in the last scenario [`stack`] checks at compile time if the number
139/// of values passed to the macro exceeds the capacity specified.
140///
141/// # Macro expansion
142///
143/// The code
144/// ```ignore
145/// let stack = stack![i32; 10];
146/// ```
147///
148/// expands to
149/// ```ignore
150/// let stack = Stack::<i32, 10>::new();
151/// ```
152///
153/// On the other hand, the code
154/// ```ignore
155/// let stack = stack! {
156///     [i32; 10] = [1, 2, 3]
157/// };
158/// ```
159///
160/// roughly expands to
161/// ```ignore
162/// let stack = unsafe {
163///     let mut stack = Stack::<i32, 10>::new();
164///     stack.push_unchecked(1);
165///     stack.push_unchecked(2);
166///     stack.push_unchecked(3);
167///     stack
168/// };
169/// ```
170#[macro_export(local_inner_macros)]
171macro_rules! stack {
172    ($T:ty; $N:expr) => {
173        $crate::Stack::<$T, $N>::new()
174    };
175    ([$T:ty; $N:expr] = [$($expr:expr),+ $(,)?]) => {{
176        // Compile-time error rather than runtime error
177        const _: () = core::prelude::rust_2021::assert!(
178            count_args!($($expr,)*) <= $N,
179            core::prelude::rust_2021::concat!(
180                "The number of items exceeds the capacity specified, which is ",
181                $N
182            )
183        );
184
185        let mut stack = stack![$T; $N];
186
187        // SAFETY: we have asserted before that we have enouch capacity
188        $( unsafe { stack.push_unchecked($expr) }; )*
189        stack
190    }};
191}
192
193/// The type returned by [`Stack`]'s checked operations if they fail.
194///
195/// # The `std` feature
196///
197/// If the `std` feature is enable, [`StackError`] implements `std::error::Error`.
198#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
199pub enum StackError {
200    /// Stack overflow occurs when there is not enough capacity to perform a stack
201    /// operation. Examples of that are [`push`][Stack::push] and [`extend`][Stack::extend].
202    Overflow,
203    /// Stack underflow occurs when there are not enough items to perform a stack
204    /// operation. Examples of that are [`rotate_tos`][Stack::rotate_tos] and
205    /// [`swap_tos`][Stack::swap_tos].
206    ///
207    /// From Wikipedia: For integers, the term "integer underflow" typically refers to a
208    /// special kind of integer overflow or integer wraparound condition whereby the result
209    /// of subtraction would result in a value less than the minimum allowed for a given
210    /// integer type.
211    Underflow,
212}
213
214impl fmt::Display for StackError {
215    #[inline]
216    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
217        write!(f, "{:?}", self)
218    }
219}
220
221/// This implementation is only available when the `std` feature is
222/// enabled.
223#[cfg(feature = "std")]
224impl std::error::Error for StackError {}
225
226/// A data structure with fixed capacity aimed at fast LIFO operations.
227///
228/// The [`Stack`] excels in working with the TOS, also known as the top of the stack.
229/// It is generic over any type `T`, and offers some implementations, such
230/// as [`Clone`], [`Debug`], [`PartialEq`] and [`Hash`] if `T` supports it as well.
231///
232/// The [`Stack`] offers three ways to manipulate data:
233/// * Checked methods, such as [`push`][Stack::push] and [`pop`][Stack::pop], which
234/// return an [`Option`] or a [`Result`]. A bit slower but *much* safer. 👍
235/// * `_panicking` methods, such as [`push_panicking`][Stack::push_panicking]
236/// and [`pop_panicking`][Stack::pop_panicking], which panic if the operation fails.
237/// * `_unchecked` methods, such as [`push_unchecked`][Stack::push_unchecked]
238/// and [`pop_unchecked`][Stack::pop_unchecked] which cause [undefined behavior]
239/// if the operation fails. The fastest choice but the unsafest! ⚠️
240///
241/// # How it works
242///
243/// A [`Stack`] is no more than a fixed size array of [`MaybeUninit`] and an [`usize`]
244/// that keeps track of the items count and is in charge of bound checking.
245/// The usage of [`MaybeUninit`] enhances the performance of the data structure,
246/// as it only allocates when needed. The [`Stack`] makes usage of [`unsafe`] code
247/// internally to handle data through raw pointers, and further increase the
248/// speed of read/write/swap operations.
249///
250/// # Safety
251///
252/// Users are recommended to rely on the checked methods or the `_panicking` ones,
253/// even though the second category should be used for testing and teaching purposes,
254/// as it does not allow for proper error handling by panicking on error.
255/// If deemed necessary, `_unchecked` (but faster) versions of the safe methods
256/// are available. These ones skip the safety checks, but will result in
257/// *[undefined behavior]* if the user does not respect the [safety contract].
258///
259/// If the user is certain that the safety contract is guaranteed to be respected,
260/// the `_unchecked` versions are available for use. However, as mentioned in the
261/// beginning of this paragraph, most of the time users will be happy enough to
262/// rely on the safe counterparts and trade off a bit of performance to avoid UB.
263///
264/// # Examples
265///
266/// ## Creating an empty `Stack`
267///
268/// ```
269/// use astack::{stack, Stack};
270///
271/// // Through the Stack::new() method
272/// let stack = Stack::<u64, 10>::new();
273///
274/// // Through the stack! macro
275/// let stack = stack![u64; 10];
276/// ```
277///
278/// ## Creating a `Stack` with already some items inside
279///
280/// ```
281/// use astack::stack;
282///
283/// // Through the stack! macro
284/// let stack = stack! {
285///     [u64; 10] = [1, 2, 3]
286/// };
287/// ```
288///
289/// ## Creating a `Stack` filled with items
290///
291/// ```
292/// use astack::Stack;
293///
294/// // A Stack filled with one single Copy item.
295/// let stack_of_44 = Stack::<u64, 10>::fill_with_copy(44);
296///
297/// // A Stack filled with the Default implementation of `T`.
298/// let stack_of_default = Stack::<u64, 10>::fill_with_default();
299///
300/// // A Stack filled with a value based on the result of a function.
301/// let stack = Stack::<String, 10>::fill_with_fn(|i| {
302///     format!("Value n. {}", i)
303/// });
304/// ```
305///
306/// ## List of all checked `Stack` operations
307/// | Name | Description |
308/// |---|---|
309/// | [`push`][Stack::push] | Push an item |
310/// | [`extend`][Stack::extend] | Push many items |
311/// | [`extend_array`][Stack::extend_array] | Push many items from an array |
312/// | [`pop`][Stack::pop] | Pop and return an item |
313/// | [`cut`][Stack::cut] | Pop and return many items |
314/// | [`tos`][Stack::tos] | Get a reference to TOS |
315/// | [`tos_mut`][Stack::tos_mut] | Get a mutable reference to TOS |
316/// | [`truncate`][Stack::truncate] | Pop and discard many items |
317/// | [`swap_tos`][Stack::swap_tos] | Replace TOS with an item |
318/// | [`rotate_tos`][Stack::rotate_tos] | Swap TOS with TOS - 1: |
319///
320/// [`MaybeUninit`]: core::mem::MaybeUninit
321/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
322/// [safety contract]: https://doc.rust-lang.org/std/keyword.unsafe.html
323/// [`Debug`]: core::fmt::Debug
324/// [`Hash`]: core::hash::Hash
325/// [`unsafe`]: https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html
326pub struct Stack<T, const N: usize> {
327    items: [mem::MaybeUninit<T>; N],
328    len: usize,
329}
330
331impl<T, const N: usize> Stack<T, N> {
332    /// Returns a new empty [`Stack`] with its items uninitialized.
333    ///
334    /// * If you want to get a [`Stack`] filled with [`Copy`] items, see
335    /// [`fill_with_copy`][Stack::fill_with_copy].
336    /// * If you want to get a [`Stack`] filled with [`Default`] items, see
337    /// [`fill_with_default`][Stack::fill_with_default].
338    /// * If you want to get a [`Stack`] filled with the value returned by a function,
339    /// see [`fill_with_fn`][Stack::fill_with_fn].
340    ///
341    /// # Examples
342    ///
343    /// ```
344    /// use astack::{Stack, stack};
345    /// // Create an empty Stack which can hold up to 10 String.
346    /// let stack1 = Stack::<String, 10>::new();
347    ///
348    /// // You can achieve the same result with the stack! macro.
349    /// let same_as_stack1 = stack![String; 10];
350    ///
351    /// // Both stacks do not have initialized items.
352    /// assert!(stack1.is_empty() && same_as_stack1.is_empty());
353    /// ```
354    #[inline]
355    pub const fn new() -> Self {
356        Self {
357            // SAFETY: The `assume_init` is safe because the type we are claiming
358            // to have initialized here is a bunch of `MaybeUninit`s, which do not
359            // require initialization.
360            // https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#initializing-an-array-element-by-element
361            items: unsafe { mem::MaybeUninit::uninit().assume_init() },
362            len: 0,
363        }
364    }
365
366    /// Returns a [`Stack`] filled with `item`. Only works if `item` implements [`Copy`].
367    /// This is optimized for types which implement [`Copy`].
368    ///
369    /// * If you want to get a [`Stack`] filled with [`Default`] items, see
370    /// [`fill_with_default`][Stack::fill_with_default].
371    /// * If you want to get a [`Stack`] filled with the value returned by a function,
372    /// see [`fill_with_fn`][Stack::fill_with_fn].
373    ///
374    /// # Examples
375    /// ```
376    /// use astack::Stack;
377    ///
378    /// // A stack full of 42.
379    /// let stack_of_42 = Stack::<u8, 50>::fill_with_copy(42);
380    /// assert!(stack_of_42.is_full());
381    /// assert_eq!(stack_of_42.tos(), Some(&42));
382    ///
383    /// ```
384    ///
385    /// [this link]: https://doc.rust-lang.org/std/primitive.array.html
386    #[inline]
387    pub const fn fill_with_copy(item: T) -> Self
388    where
389        T: Copy,
390    {
391        Self {
392            items: [mem::MaybeUninit::new(item); N],
393            len: N,
394        }
395    }
396
397    /// Returns a [`Stack`] filled with the item returned by `f`. This is useful
398    /// to create a [`Stack`] out of non-[`Copy`] and non-[`Default`] items.
399    /// The `f` takes as input a [`usize`] which is the i-th index
400    ///
401    /// * If you want to get a [`Stack`] filled with [`Copy`] items, see
402    /// [`fill_with_copy`][Stack::fill_with_copy].
403    /// * If you want to get a [`Stack`] filled with [`Default`] items, see
404    /// [`fill_with_default`][Stack::fill_with_default].
405    ///
406    /// # Examples
407    ///
408    /// ```
409    /// use astack::Stack;
410    ///
411    /// fn long_computation(i: usize) -> String {
412    ///     // Perform a long and heavy computation...
413    ///     format!("Item n. {}", i)
414    /// }
415    ///
416    /// let stack = Stack::<String, 32>::fill_with_fn(long_computation);
417    /// assert!(stack.is_full());
418    /// assert_eq!(stack.tos(), Some(&String::from("Item n. 31")));
419    /// ```
420    #[inline]
421    pub fn fill_with_fn<F>(mut f: F) -> Self
422    where
423        F: FnMut(usize) -> T,
424    {
425        Self {
426            items: core::array::from_fn(|i| mem::MaybeUninit::new(f(i))),
427            len: N,
428        }
429    }
430
431    /// Returns a [`Stack`] filled with the default value for `T`.
432    ///
433    /// * If you want to get a [`Stack`] filled with [`Copy`] items, see
434    /// [`fill_with_copy`][Stack::fill_with_copy].
435    /// * If you want to get a [`Stack`] filled with the value returned by a function,
436    /// see [`fill_with_fn`][Stack::fill_with_fn].
437    ///
438    /// # Examples
439    ///
440    /// ```
441    /// use astack::Stack;
442    ///
443    /// // A Stack filled with empty Strings
444    /// let stack = Stack::<String, 4>::fill_with_default();
445    /// assert!(stack.is_full());
446    /// assert_eq!(stack.tos(), Some(&String::default()));
447    /// ```
448    #[inline]
449    pub fn fill_with_default() -> Self
450    where
451        T: Default,
452    {
453        Self::fill_with_fn(|_| T::default())
454    }
455
456    /// Builds a [`Stack`] from an array of [`MaybeUninit`] and a `len`,
457    /// representing the count of initialized items.
458    ///
459    /// # Safety
460    ///
461    /// Building a [`Stack`] using [`from_raw_parts`][Stack::from_raw_parts] is
462    /// *[undefined behavior]* if one of the following occurs:
463    /// * `len` is greater than the maximum number of items the stack is allowed to hold.
464    ///
465    /// * `items[..len]` is composed of uninitialized [`MaybeUninit`].
466    ///
467    /// # Leaking
468    ///
469    /// Building a [`Stack`] using [`from_raw_parts`][Stack::from_raw_parts]
470    /// will cause a memory leak if both conditions are met:
471    ///
472    /// * `items[len..N]` is composed of one or more already initialized [`MaybeUninit`].
473    ///
474    /// * `T` does not implement [`Copy`].
475    ///
476    /// # Examples
477    ///
478    /// ```
479    /// use std::mem;
480    /// use astack::{Stack, stack};
481    ///
482    /// // Create a stack from raw parts.
483    /// // [3, 2, 1, (uninit)]
484    /// let items = [
485    ///     mem::MaybeUninit::new(3),
486    ///     mem::MaybeUninit::new(2),
487    ///     mem::MaybeUninit::new(1),
488    ///     mem::MaybeUninit::uninit(),
489    /// ];
490    /// let len = 3;
491    ///
492    /// // Safety: the items have been initialized in the correct way.
493    /// // Safety: len correctly represents the count of initialized items.
494    ///
495    /// let stack = unsafe { Stack::from_raw_parts(items, len) };
496    /// assert_eq!(stack.len(), 3);
497    /// assert_eq!(stack.tos(), Some(&1));
498    /// assert_eq!(stack, stack! {
499    ///     [i32; 4] = [3, 2, 1]
500    /// });
501    /// ```
502    ///
503    /// [`MaybeUninit`]: core::mem::MaybeUninit
504    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
505    #[inline]
506    pub const unsafe fn from_raw_parts(items: [mem::MaybeUninit<T>; N], len: usize) -> Self {
507        debug_assert!(len <= N);
508        Self { items, len }
509    }
510
511    /// Returns `true` if the stack does not have initialized items, and is therefore
512    /// considered empty.
513    ///
514    /// # Examples
515    ///
516    /// ```
517    /// use astack::stack;
518    ///
519    /// // Create an empty stack
520    /// let mut stack = stack![i32; 16];
521    /// assert!(stack.is_empty());
522    ///
523    /// // Add items
524    /// stack.push_panicking(42);
525    /// stack.push_panicking(69);
526    ///
527    /// // Not the stack is not empty anymore!
528    /// assert!(!stack.is_empty());
529    /// ```
530    #[inline]
531    pub const fn is_empty(&self) -> bool {
532        self.len == 0
533    }
534
535    /// Returns `true` if the stack contains only initialized items, and is therefore
536    /// considered full.
537    ///
538    /// # Examples
539    ///
540    /// ```
541    /// use astack::stack;
542    ///
543    /// // Create a stack full of custom items.
544    /// let mut stack = stack! {
545    ///     [i64; 4] = [567, 212, 890, 90]
546    /// };
547    /// assert!(stack.is_full());
548    ///
549    /// // Remove an item.
550    /// stack.pop_panicking();
551    ///
552    /// // Not the stack is not full anymore, even if there are
553    /// // still three items inside!
554    /// assert!(!stack.is_full());
555    /// ```
556    #[inline]
557    pub const fn is_full(&self) -> bool {
558        self.len >= N
559    }
560
561    /// Returns the number of initialized items in the stack, also referred to
562    /// as its 'len'.
563    ///
564    /// # Examples
565    ///
566    /// ```
567    /// use astack::stack;
568    ///
569    /// let stack = stack! {
570    ///     [bool; 10] = [false, true, false]
571    /// };
572    /// assert_eq!(stack.len(), 3);
573    /// ```
574    #[inline]
575    pub const fn len(&self) -> usize {
576        self.len
577    }
578
579    /// Returns the capacity of the stack. Remember that a [`Stack`] has a fixed
580    /// capacity!
581    ///
582    /// This does not return the *remaining* capacity, but rather the total capacity
583    /// that was given as input when the [`Stack`] was created, i.e., the number of
584    /// items that the stack is able to hold.
585    ///
586    /// # Examples
587    ///
588    /// ```
589    /// use astack::stack;
590    ///
591    /// let mut stack = stack![i32; 10];
592    /// assert_eq!(stack.capacity(), 10);
593    ///
594    /// // Even if we push some items, the capacity remains the same.
595    /// stack.push_panicking(50);
596    /// stack.push_panicking(150);
597    ///
598    /// assert_eq!(stack.len(), 2);
599    /// assert_eq!(stack.capacity(), 10);
600    /// ```
601    #[inline]
602    pub const fn capacity(&self) -> usize {
603        N
604    }
605
606    /// Returns the number of items the stack can push before becoming full.
607    ///
608    /// # Examples
609    ///
610    /// ```
611    /// use astack::stack;
612    ///
613    /// let mut stack = stack![i32; 5];
614    /// // The stack is empty now.
615    /// assert_eq!(stack.capacity_remaining(), 5);
616    ///
617    /// // Add some items.
618    /// stack.extend_array_panicking([7, 8, 9]);
619    ///
620    /// assert_eq!(stack.capacity_remaining(), 2);
621    /// ```
622    #[inline]
623    pub const fn capacity_remaining(&self) -> usize {
624        N - self.len
625    }
626
627    /// Returns a reference to the top of the stack or [`None`] if it is empty.
628    /// This does not remove TOS from the stack.
629    ///
630    /// # Examples
631    ///
632    /// ```
633    /// use astack::stack;
634    ///
635    /// let mut stack = stack! {
636    ///     [&str; 3] = ["my", "body!"]
637    /// };
638    ///
639    /// // The top of the stack is the last inserted one!
640    /// let tos = stack.tos();
641    /// assert_eq!(tos, Some(&"body!"));
642    ///
643    /// // Remove all items
644    /// stack.clear();
645    ///
646    /// assert_eq!(stack.tos(), None);
647    /// ```
648    #[inline]
649    pub const fn tos(&self) -> Option<&T> {
650        if self.is_empty() {
651            None
652        } else {
653            Some(unsafe { self.tos_unchecked() })
654        }
655    }
656
657    /// Returns a reference to the top of the stack. This does not remove TOS from
658    /// the stack.
659    /// # Panics
660    ///
661    /// Panics if the stack is empty.
662    ///
663    /// # Examples
664    ///
665    /// ```
666    /// use astack::stack;
667    ///
668    /// // An empty stack has no TOS!
669    /// let mut stack = stack![i32; 100];
670    /// stack.push_panicking(80);
671    ///
672    /// // This example would panic if there was no TOS.
673    /// assert_eq!(stack.tos_panicking(), &80);
674    /// ```
675    #[inline]
676    pub const fn tos_panicking(&self) -> &T {
677        assert!(
678            !self.is_empty(),
679            "Called Stack::tos_panicking on an empty stack"
680        );
681        unsafe { self.tos_unchecked() }
682    }
683
684    /// Returns a reference to the top of the stack without checking whether
685    /// the latter is empty or not. For a safe alternative see [`tos`][Stack::tos]
686    /// or [`tos_panicking`][Stack::tos_panicking]. This does not remove TOS from
687    /// the stack.
688    ///
689    /// # Safety
690    ///
691    /// Calling this method on an empty stack is *[undefined behavior]*
692    /// even if the resulting reference is not used.
693    ///
694    /// # Examples
695    ///
696    /// ```
697    /// use astack::stack;
698    ///
699    /// let mut stack = stack! {
700    ///     [&str; 3] = ["my", "body!"]
701    /// };
702    ///
703    /// // We know that the tos exists, so we use the unchecked version.
704    /// let tos = unsafe { stack.tos_unchecked() };
705    /// assert_eq!(tos, &"body!");
706    ///
707    /// // Remove all items
708    /// stack.clear();
709    ///
710    /// // The following line will cause undefined behavior
711    /// // if commented out!
712    /// // let tos = unsafe { stack.tos_unchecked() };
713    /// ```
714    ///
715    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
716    #[inline]
717    pub const unsafe fn tos_unchecked(&self) -> &T {
718        debug_assert!(!self.is_empty());
719
720        // SAFETY: the caller must uphold the safety requirements
721        // (self.len must be > 0)
722        //
723        // The following is the same as SliceIndex::get_unchecked with usize
724        // By not using the trait method, we can make this function const
725        unsafe { (*self.items.as_ptr().add(self.len - 1)).assume_init_ref() }
726    }
727
728    /// Returns a mutable reference to the top of the stack or [`None`]
729    /// if it is empty. This does not remove TOS from the stack.
730    ///
731    /// # Examples
732    ///
733    /// ```
734    /// use astack::stack;
735    ///
736    /// // A stack with one item: the number 0.
737    /// let mut stack = stack! {
738    ///     [i32; 8] = [0]
739    /// };
740    /// assert_eq!(stack.tos(), Some(&0));
741    ///
742    /// // Increment tos by 10
743    /// if let Some(tos) = stack.tos_mut() {
744    ///     *tos += 10;
745    /// }
746    ///
747    /// assert_eq!(stack.tos(), Some(&10));
748    /// ```
749    #[inline]
750    pub fn tos_mut(&mut self) -> Option<&mut T> {
751        if self.is_empty() {
752            None
753        } else {
754            Some(unsafe { self.tos_mut_unchecked() })
755        }
756    }
757
758    /// Returns a mutable reference to the top of the stack. This does not remove TOS from
759    /// the stack.
760    ///
761    /// # Panics
762    ///
763    /// Panics if the stack is empty.
764    ///
765    /// # Examples
766    ///
767    /// ```
768    /// use astack::stack;
769    ///
770    /// // A stack with one item: the number 0.
771    /// let mut stack = stack! {
772    ///     [i32; 8] = [0]
773    /// };
774    ///
775    /// // The following like would cause a panic if the stack was empty!
776    /// let mut tos = stack.tos_mut_panicking();
777    /// assert_eq!(tos, &mut 0);
778    ///
779    /// // Increment tos by 10
780    /// *tos += 10;
781    ///
782    /// assert_eq!(stack.tos_mut_panicking(), &mut 10);
783    /// ```
784    #[inline]
785    pub fn tos_mut_panicking(&mut self) -> &mut T {
786        assert!(
787            !self.is_empty(),
788            "Called Stack::tos_mut_panicking on an empty stack"
789        );
790        unsafe { self.tos_mut_unchecked() }
791    }
792
793    /// Returns a mutable reference to the top of the stack without checking
794    /// whether the latter is empty or not. For a safe alternative see
795    /// [`tos_mut`][Stack::tos_mut] or [`tos_mut_panicking`][Stack::tos_mut_panicking].
796    /// This does not remove TOS from the stack.
797    ///
798    /// # Safety
799    ///
800    /// Calling this method on an empty stack is *[undefined behavior]*
801    /// even if the resulting reference is not used.
802    ///
803    /// # Examples
804    ///
805    /// ```
806    /// use astack::stack;
807    ///
808    /// let mut stack = stack! {
809    ///     [char; 10] = ['a', 'b']
810    /// };
811    ///
812    /// // We know that there must be a tos
813    /// // Increment tos ascii value by one
814    /// let tos = unsafe { stack.tos_mut_unchecked() };
815    /// *tos = (*tos as u8 + 1) as char;
816    ///
817    /// assert_eq!(stack.tos(), Some(&'c'));
818    /// ```
819    ///
820    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
821    #[inline]
822    pub unsafe fn tos_mut_unchecked(&mut self) -> &mut T {
823        debug_assert!(!self.is_empty());
824
825        // SAFETY: the caller must uphold the safety requirements
826        // (self.len must be > 0)
827        //
828        // The following is the same as SliceIndex::get_unchecked with usize
829        // By not using the trait method, we can make this function const (not yet!)
830        unsafe { (*self.items.as_mut_ptr().add(self.len - 1)).assume_init_mut() }
831    }
832
833    /// Pushes an item at the top of the stack.
834    ///
835    /// # Errors
836    ///
837    /// Returns [`StackError`] if the stack is full.
838    ///
839    /// # Examples
840    ///
841    /// ```
842    /// use astack::{Stack, StackError};
843    ///
844    /// // Create a full stack.
845    /// let mut stack = Stack::<i16, 20>::fill_with_copy(100);
846    ///
847    /// // Try to push `my_lucky_num`.
848    /// let my_lucky_num = 16;
849    /// assert_eq!(stack.push(my_lucky_num), Err(StackError::Overflow));
850    ///
851    /// // Make some space for `my_lucky_num`.
852    /// stack.clear();
853    ///
854    /// assert_eq!(stack.push(my_lucky_num), Ok(()));
855    /// ```
856    #[inline]
857    pub fn push(&mut self, item: T) -> Result<(), StackError> {
858        if self.is_full() {
859            Err(StackError::Overflow)
860        } else {
861            unsafe { self.push_unchecked(item) };
862            Ok(())
863        }
864    }
865
866    /// Pushes an item at the top of the stack
867    ///
868    /// # Panics
869    ///
870    /// Panics if the stack is full.
871    ///
872    /// # Examples
873    ///
874    /// ```
875    /// use astack::{Stack, StackError};
876    ///
877    /// // Create a full stack.
878    /// let mut stack = Stack::<i16, 20>::fill_with_copy(100);
879    ///
880    /// // Try to push `my_lucky_num`.
881    /// let my_lucky_num = 16;
882    ///
883    /// // The following line, if commented out, would cause a panic!
884    /// // assert_eq!(stack.push(my_lucky_num), Err(StackError::Overflow));
885    ///
886    /// // Make some space for `my_lucky_num`.
887    /// stack.clear();
888    ///
889    /// // Now it is safe to push_panicking.
890    /// stack.push_panicking(my_lucky_num);
891    /// assert_eq!(stack.tos(), Some(&16));
892    /// ```
893    #[inline]
894    pub fn push_panicking(&mut self, item: T) {
895        assert!(
896            !self.is_full(),
897            "Called Stack::push_panicking but the stack is full"
898        );
899        unsafe { self.push_unchecked(item) };
900    }
901
902    /// Pushes an item at the top of the stack, without checking whether the latter
903    /// is full or not. For a safe alternative, see [`push`][Stack::push] or
904    /// [`push_panicking`][Stack::push_panicking].
905    ///
906    /// # Safety
907    ///
908    /// Calling this method if the stack is full is *[undefined behavior]*.
909    ///
910    /// # Examples
911    /// ```
912    /// use astack::stack;
913    ///
914    /// let mut my_stack1 = stack![i32; 10];
915    ///
916    /// // Fill the stack manually.
917    /// for i in 0..10 {
918    ///     unsafe {
919    ///         my_stack1.push_unchecked(i);
920    ///     }
921    /// }
922    ///
923    /// // The following line if commented out, would result in undefined behavior!
924    /// // unsafe { my_stack1.push_unchecked(11); }
925    /// ```
926    ///
927    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
928    #[inline]
929    pub unsafe fn push_unchecked(&mut self, item: T) {
930        debug_assert!(!self.is_full());
931
932        // SAFETY: the caller must uphold the safety requirements (self.len < N).
933        //
934        // This is similar to Vec::push
935        unsafe {
936            let end = self.items.as_mut_ptr().add(self.len);
937            ptr::write(end, mem::MaybeUninit::new(item));
938        }
939        self.len += 1;
940    }
941
942    /// Removes the top of the stack and returns it, or [`None`] if the stack
943    /// is empty.
944    ///
945    /// # Examples
946    ///
947    /// ```
948    /// use astack::stack;
949    ///
950    /// let mut stack = stack!{
951    ///     [i32; 16] = [10, 20, 30]
952    /// };
953    ///
954    /// assert_eq!(stack.pop(), Some(30));
955    /// assert_eq!(stack.pop(), Some(20));
956    /// assert_eq!(stack.pop(), Some(10));
957    /// assert_eq!(stack.pop(), None);
958    /// ```
959    #[inline]
960    pub fn pop(&mut self) -> Option<T> {
961        if self.is_empty() {
962            None
963        } else {
964            Some(unsafe { self.pop_unchecked() })
965        }
966    }
967
968    /// Removes the top of the stack and returns it
969    ///
970    /// # Panics
971    ///
972    /// Panics if the stack is empty.
973    ///
974    /// # Examples
975    ///
976    /// ```
977    /// use astack::stack;
978    ///
979    /// let mut stack = stack!{
980    ///     [i32; 16] = [10, 20, 30]
981    /// };
982    ///
983    /// // Cannot pop_unchecked more than 3 times, otherwise a panic occurs!
984    /// assert_eq!(stack.pop_panicking(), 30);
985    /// assert_eq!(stack.pop_panicking(), 20);
986    /// assert_eq!(stack.pop_panicking(), 10);
987    /// ```
988    #[inline]
989    pub fn pop_panicking(&mut self) -> T {
990        assert!(
991            !self.is_empty(),
992            "Called Stack::pop_panicking but the stack is empty"
993        );
994        unsafe { self.pop_unchecked() }
995    }
996
997    /// Removes the top of the stack and returns it, without checking whether
998    /// the latter is empty or not. For a safe alternative, see [`pop`][Stack::pop]
999    /// or [`pop_panicking`][Stack::pop_panicking].
1000    ///
1001    /// # Safety
1002    ///
1003    /// Calling this method if the stack is empty is *[undefined behavior]*.
1004    ///
1005    /// # Examples
1006    ///
1007    /// ```
1008    /// use astack::stack;
1009    ///
1010    /// let mut stack = stack! {
1011    ///     [char; 4] = ['a', 'b']
1012    /// };
1013    ///
1014    /// // We know there are exactly 2 items at this point, so it is safe to use
1015    /// // the unchecked version.
1016    /// unsafe {
1017    ///     assert_eq!(stack.pop_unchecked(), 'b');
1018    ///     assert_eq!(stack.pop_unchecked(), 'a');
1019    /// }
1020    ///
1021    /// // If commented out, the following line results in undefined behavior!
1022    /// // unsafe { stack.pop_unchecked(); };
1023    /// ```
1024    ///
1025    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1026    #[inline]
1027    pub unsafe fn pop_unchecked(&mut self) -> T {
1028        debug_assert!(!self.is_empty());
1029
1030        // SAFETY: the caller must uphold the safety requirements
1031        // (self.len > 0)
1032        // (self.items.as_ptr().add(self.len) must be in an initialized state)
1033        //
1034        // This is similar to Vec::pop
1035        self.len -= 1;
1036        unsafe { ptr::read(self.items.as_ptr().add(self.len)).assume_init() }
1037    }
1038
1039    /// Pushes items of an array of length `M` on the stack. This is optimized
1040    /// for arrays, and should be preferred before [`extend`][Stack::extend]
1041    /// if you have an array of elements.
1042    ///
1043    /// # Errors
1044    ///
1045    /// Returns [`StackError`] if the stack cannot hold `M` more items
1046    /// (`stack.len() + M > stack.capacity()`).
1047    ///
1048    /// # Examples
1049    ///
1050    /// ```
1051    /// use astack::{stack, StackError};
1052    ///
1053    /// let mut stack = stack! {
1054    ///     [i32; 5] = [1, 2, 3]
1055    /// };
1056    ///
1057    /// // Extend the stack
1058    /// stack.extend_array([4, 5]).unwrap();
1059    /// assert_eq!(stack.tos(), Some(&5));
1060    /// assert_eq!(stack, [1, 2, 3, 4, 5]);
1061    ///
1062    /// // The stack is full: cannot push more items!
1063    /// assert_eq!(stack.extend_array([6, 7, 8]), Err(StackError::Overflow));
1064    /// ```
1065    #[inline]
1066    pub fn extend_array<const M: usize>(&mut self, arr: [T; M]) -> Result<(), StackError> {
1067        if self.len + M > N {
1068            Err(StackError::Overflow)
1069        } else {
1070            unsafe { self.extend_array_unchecked(arr) };
1071            Ok(())
1072        }
1073    }
1074
1075    /// Pushes items of an array of length `M` on the stack. This is optimized
1076    /// for arrays, and should be preferred before [`extend_panicking`][Stack::extend_panicking]
1077    /// if you have an array of elements.
1078    ///
1079    /// # Panics
1080    ///
1081    /// Panics if the stack cannot hold `M` more items
1082    /// (`stack.len() + M > stack.capacity()`).
1083    ///
1084    /// # Examples
1085    ///
1086    /// ```should_panic
1087    /// use astack::stack;
1088    ///
1089    /// let mut characters = stack![char; 4];
1090    ///
1091    /// // Extend operations
1092    /// characters.extend_array_panicking(['x', 'y']);
1093    /// characters.extend_array_panicking(['z', '_']);
1094    /// assert_eq!(characters, ['x', 'y', 'z', '_']);
1095    ///
1096    /// // The following line makes the program crash!
1097    /// characters.extend_array_panicking(['a', 'b']);
1098    /// ```
1099    #[inline]
1100    pub fn extend_array_panicking<const M: usize>(&mut self, arr: [T; M]) {
1101        assert!(
1102            self.len + M <= N,
1103            "Called Stack::push_array_panicking but self.len + M > N"
1104        );
1105        unsafe { self.extend_array_unchecked(arr) };
1106    }
1107
1108    /// Pushes items of an array of length `M` on the stack. This is optimized
1109    /// for arrays, and should be preferred before [`extend_panicking`][Stack::extend_panicking]
1110    /// if you have an array of elements.
1111    ///
1112    /// # Safety
1113    ///
1114    /// Calling this method if `stack.len() + M > stack.capacity()` is
1115    /// *[undefined behavior]*.
1116    ///
1117    /// # Examples
1118    ///
1119    /// ```
1120    /// use astack::stack;
1121    ///
1122    /// let mut characters = stack![char; 4];
1123    ///
1124    /// // SAFETY: we know that at this point the stack can hold exactly 4 characters
1125    /// // and therefore it is safe to pass an array of 4 chars.
1126    /// unsafe {
1127    ///     characters.extend_array_unchecked(['7', '8', '9', '0']);   
1128    /// }
1129    /// assert_eq!(characters, ['7', '8', '9', '0']);
1130    ///
1131    /// // The following line, if uncommented, causes undefined behavior.
1132    /// // characters.extend_array_unchecked(['a', 'b']);
1133    /// ```
1134    ///
1135    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1136    #[inline]
1137    pub unsafe fn extend_array_unchecked<const M: usize>(&mut self, arr: [T; M]) {
1138        debug_assert!(self.len + M <= N);
1139        let mut arr = arr.map(|item| mem::MaybeUninit::new(item));
1140
1141        // SAFETY: this is similar to slice::swap_with_slice. The slices cannot
1142        // overlap because mutable references are exclusive.
1143        unsafe {
1144            ptr::swap_nonoverlapping(
1145                self.items[self.len..(self.len + M)].as_mut_ptr(),
1146                arr[..].as_mut_ptr(),
1147                M,
1148            );
1149        }
1150        self.len += M;
1151    }
1152
1153    /// Moves items of an [`IntoIterator`] onto the stack. This is the equivalent of calling
1154    /// [`push`][Stack::push] for each item of the [`IntoIterator`]. If you want to push
1155    /// items of an array, see [`extend_array`][Stack::extend_array].
1156    ///
1157    /// # Errors
1158    ///
1159    /// Returns [`StackError`] if the stack runs out of capacity while inserting
1160    /// the items.
1161    ///
1162    /// # Examples
1163    ///
1164    /// ```
1165    /// use astack::{stack, StackError};
1166    ///
1167    /// let mut stack = stack![u8; 7];
1168    ///
1169    /// // This works!
1170    /// stack.extend(0..2).unwrap();
1171    /// assert_eq!(stack, [0, 1]);
1172    ///
1173    /// // All types that support IntoIterator can be used with `extend`.
1174    /// stack.extend("aa".chars().map(|ch| ch as _)).unwrap();
1175    /// assert_eq!(stack, [0, 1, 97, 97]);
1176    ///
1177    /// // NOT RECOMMENDED: use `extend_array` for that.
1178    /// stack.extend([4, 5, 6]).unwrap();
1179    /// assert_eq!(stack.tos(), Some(&6));
1180    ///
1181    /// // The stack is at full capacity!
1182    /// assert_eq!(stack.extend(1..), Err(StackError::Overflow));
1183    /// ```
1184    #[inline]
1185    pub fn extend<I>(&mut self, items: I) -> Result<(), StackError>
1186    where
1187        I: IntoIterator<Item = T>,
1188    {
1189        items.into_iter().try_for_each(|item| self.push(item))
1190    }
1191
1192    /// Moves items of an [`IntoIterator`] onto the stack. This is the equivalent of calling
1193    /// [`push_panicking`][Stack::push_panicking] for each item of the [`IntoIterator`].
1194    /// If you want to push items of an array, see
1195    /// [`extend_array_panicking`][Stack::extend_array_panicking].
1196    ///
1197    /// # Panics
1198    ///
1199    /// Panics if the stack runs out of capacity while inserting the items.
1200    ///
1201    /// # Examples
1202    ///
1203    /// ```should_panic
1204    /// use astack::stack;
1205    ///
1206    /// let mut stack = stack![u8; 7];
1207    ///
1208    /// // This works!
1209    /// stack.extend_panicking(0..5);
1210    /// assert_eq!(stack, [0, 1, 2, 3, 4]);
1211    ///
1212    /// // All types that support IntoIterator can be used with `extend_panicking`.
1213    /// stack.extend_panicking("ee".chars().map(|ch| ch as _));
1214    /// assert_eq!(stack, [0, 1, 2, 3, 4, 101, 101]);
1215    /// assert!(stack.is_full());
1216    ///
1217    /// // The stack is at full capacity! The program panics at the line below.
1218    /// stack.extend_panicking(1..);
1219    /// ```
1220    #[inline]
1221    pub fn extend_panicking<I>(&mut self, items: I)
1222    where
1223        I: IntoIterator<Item = T>,
1224    {
1225        items.into_iter().for_each(|item| self.push_panicking(item));
1226    }
1227
1228    /// Moves items of an [`IntoIterator`] onto the stack without checking for overflow.
1229    /// This is the equivalent of calling [`push_unchecked`][Stack::push_unchecked]
1230    /// for each item of the [`IntoIterator`]. If you want to push items of an array, see
1231    /// [`extend_array_unchecked`][Stack::extend_array_unchecked].
1232    ///
1233    /// # Safety
1234    ///
1235    /// If the [`IntoIterator`] overflows the capacity of the stack, *[undefined behavior]*
1236    /// occurs.
1237    ///
1238    /// # Examples
1239    ///
1240    /// ```
1241    /// use astack::stack;
1242    ///
1243    /// let mut stack = stack![char; 4];
1244    ///
1245    /// // SAFETY: we know there is enough capacity to do this.
1246    /// unsafe {
1247    ///     stack.extend_unchecked("lmao".chars());
1248    /// }
1249    /// assert_eq!(stack, ['l', 'm', 'a', 'o']);
1250    ///
1251    /// // The following line, if commented out, causes undefined behavior!
1252    /// // unsafe { stack.extend_unchecked("ub".chars()) };
1253    /// ```
1254    ///
1255    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1256    #[inline]
1257    pub unsafe fn extend_unchecked<I>(&mut self, items: I)
1258    where
1259        I: IntoIterator<Item = T>,
1260    {
1261        // SAFETY: the safety contract of Stack::push_unchecked applies.
1262        items
1263            .into_iter()
1264            .for_each(|item| unsafe { self.push_unchecked(item) });
1265    }
1266
1267    /// Pops `M` items from the stack and returns them as an array (no dynamic
1268    /// allocation is involved). The order of the items is preserved: the stack
1269    /// is literally 'cut'.
1270    ///
1271    /// # Errors
1272    ///
1273    /// Returns [`StackError`] if `M > stack.len`, i.e., the requested number of
1274    /// items exceeds the number of items available. No item is removed if the
1275    /// operation is invalid.
1276    ///
1277    /// # Examples
1278    ///
1279    /// ```
1280    /// use astack::{stack, StackError};
1281    ///
1282    /// let mut greetings = stack! {
1283    ///     [&str; 5] = ["hello", "ciao", "hola", "salut"]
1284    /// };
1285    ///
1286    /// let arr = greetings.cut::<2>();
1287    ///
1288    /// // The order of the items is preserved.
1289    /// assert_eq!(arr, Ok(["hola", "salut"]));
1290    /// assert_eq!(greetings, ["hello", "ciao"]);
1291    /// assert_eq!(greetings.tos(), Some(&"ciao"));
1292    ///
1293    /// // Not enough items!
1294    /// let invalid = greetings.cut::<3>();
1295    /// assert_eq!(invalid, Err(StackError::Underflow));
1296    ///
1297    /// // No item is removed if the operation is invalid.
1298    /// assert_eq!(greetings, ["hello", "ciao"])
1299    /// ```
1300    #[inline]
1301    #[must_use = "If you want to discard the result, see `Stack::truncate`"]
1302    pub fn cut<const M: usize>(&mut self) -> Result<[T; M], StackError> {
1303        if M > self.len {
1304            Err(StackError::Underflow)
1305        } else {
1306            Ok(unsafe { self.cut_unchecked() })
1307        }
1308    }
1309
1310    /// Pops `M` items from the stack and returns them as an array (no dynamic
1311    /// allocation is involved). The order of the items is preserved: the stack
1312    /// is literally 'cut'.
1313    ///
1314    /// # Panics
1315    ///
1316    /// Panics if `M > stack.len`, i.e., the requested number of
1317    /// items exceeds the number of items available.
1318    ///
1319    /// # Examples
1320    ///
1321    /// ```should_panic
1322    /// use astack::stack;
1323    ///
1324    /// let mut stack = stack! {
1325    ///     [String; 3] = ["data1".into(), "data2".into(), "data3".into()]
1326    /// };
1327    /// let data = stack.cut_panicking::<2>();
1328    /// assert_eq!(data, ["data2".to_string(), "data3".to_string()]);
1329    /// assert_eq!(stack.tos(), Some(&String::from("data1")));
1330    ///
1331    /// // The following operation panics at runtime!
1332    /// let _ = stack.cut_panicking::<2>();
1333    /// ```
1334    #[inline]
1335    #[must_use = "If you want to discard the result, see `Stack::truncate_panicking`"]
1336    pub fn cut_panicking<const M: usize>(&mut self) -> [T; M] {
1337        assert!(
1338            M <= self.len,
1339            "Called Stack::cut_panicking but M > self.len"
1340        );
1341        unsafe { self.cut_unchecked() }
1342    }
1343
1344    /// Pops `M` items from the stack and returns them as an array (no dynamic
1345    /// allocation is involved) without checking if there are enough items.
1346    /// The order of the items is preserved: the stack is literally 'cut'.
1347    ///
1348    /// # Safety
1349    ///
1350    /// If `M > stack.len`, i.e., the requested number of
1351    /// items exceeds the number of items available, *[undefined behavior]* occurs.
1352    ///
1353    /// # Examples
1354    ///
1355    /// ```
1356    /// use astack::stack;
1357    ///
1358    /// let mut stack = stack! {
1359    ///     [i64; 8] = [89, 34, 56, 78, 12, 90, 78, 67]
1360    /// };
1361    ///
1362    /// let last_three_numbers = unsafe { stack.cut_unchecked::<3>() };
1363    /// assert_eq!(last_three_numbers, [90, 78, 67]);
1364    /// assert_eq!(stack, [89, 34, 56, 78, 12]);
1365    ///
1366    /// // The following operation would result in undefined behavior, as there are
1367    /// // only 5 items remaining in the stack.
1368    /// // let _ = unsafe { stack.cut_unchecked::<6>() };
1369    /// ```
1370    ///
1371    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1372    #[inline]
1373    #[must_use = "If you want to discard the result, see `Stack::truncate_unchecked`"]
1374    pub unsafe fn cut_unchecked<const M: usize>(&mut self) -> [T; M] {
1375        debug_assert!(M <= self.len);
1376
1377        unsafe {
1378            // SAFETY: The `assume_init` is safe because the type we are claiming
1379            // to have initialized here is a bunch of `MaybeUninit`s, which do not
1380            // require initialization.
1381            // https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#initializing-an-array-element-by-element
1382            let mut arr = mem::MaybeUninit::<[mem::MaybeUninit<T>; M]>::uninit().assume_init();
1383
1384            // SAFETY: this is similar to slice::swap_with_slice. The slices cannot
1385            // overlap because mutable references are exclusive.
1386            ptr::swap_nonoverlapping(
1387                self.items[(self.len - M)..].as_mut_ptr(),
1388                arr[..].as_mut_ptr(),
1389                M,
1390            );
1391            self.len -= M;
1392
1393            // SAFETY: At this point all the items inside arr have been swapped with
1394            // initialized data.
1395            arr.map(|item| item.assume_init())
1396        }
1397    }
1398
1399    /// Swaps TOS with `item`, returning the previous TOS.
1400    ///
1401    /// # Errors
1402    ///
1403    /// If the stack is empty, [`StackError`] is returned instead.
1404    ///
1405    /// # Examples
1406    ///
1407    /// ```
1408    /// use astack::stack;
1409    ///
1410    /// let mut stack = stack! {
1411    ///     [&str; 10] = ["praise", "Lamborghini", "supercars!"]
1412    /// };
1413    ///
1414    /// // Replace "supercars" with "tractors".
1415    /// if let Ok(old_tos) = stack.swap_tos("tractors") {
1416    ///     println!("The old tos was: {}", old_tos);
1417    ///     assert_eq!(old_tos, "supercars!");
1418    /// } else {
1419    ///     println!("Could not swap tos: empty stack!");
1420    /// }
1421    /// ```
1422    #[inline]
1423    pub fn swap_tos(&mut self, item: T) -> Result<T, StackError> {
1424        if self.is_empty() {
1425            Err(StackError::Underflow)
1426        } else {
1427            Ok(unsafe { self.swap_tos_unchecked(item) })
1428        }
1429    }
1430
1431    /// Swaps TOS with `item`, returning the previous TOS.
1432    ///
1433    /// # Panics
1434    ///
1435    /// Panics if the stack is empty.
1436    ///
1437    /// # Examples
1438    ///
1439    /// ```
1440    /// use astack::stack;
1441    ///
1442    /// let mut stack = stack![i64; 9];
1443    ///
1444    /// // SAFETY: We know there's enough space to do it.
1445    /// unsafe {
1446    ///     stack.push_unchecked(81);
1447    ///     stack.push_unchecked(3);
1448    /// }
1449    ///
1450    /// // This will panic if the stack is empty!
1451    /// assert_eq!(stack.swap_tos_panicking(16), 3);
1452    /// assert_eq!(stack.swap_tos_panicking(25), 16);
1453    /// assert_eq!(stack, stack! {
1454    ///     [i64; 9] = [81, 25]
1455    /// });
1456    /// ```
1457    #[inline]
1458    pub fn swap_tos_panicking(&mut self, item: T) -> T {
1459        assert!(
1460            !self.is_empty(),
1461            "Called Stack::swap_tos_panicking but the stack is empty"
1462        );
1463        unsafe { self.swap_tos_unchecked(item) }
1464    }
1465
1466    /// Swaps TOS with `item`, returning the previous TOS without checking whether
1467    /// the stack is empty or not. For a safe alternative, see [`swap_tos`][Stack::swap_tos]
1468    /// or [`swap_tos_panicking`][Stack::swap_tos_panicking].
1469    ///
1470    /// # Safety
1471    ///
1472    /// Calling this method if the stack is empty is *[undefined behavior]*.
1473    ///
1474    /// # Examples
1475    ///
1476    /// ```
1477    /// use astack::stack;
1478    ///
1479    /// // A stack full of &str.
1480    /// let mut stack = stack! {
1481    ///     [&str; 2] = ["yeet", "lmao"]
1482    /// };
1483    ///
1484    /// // SAFETY: we know that the stack is not empty at this point.
1485    /// let old_tos = unsafe {
1486    ///     stack.swap_tos_unchecked("lolxd")
1487    /// };
1488    ///
1489    /// assert_eq!(old_tos, "lmao");
1490    /// assert_eq!(stack.tos(), Some(&"lolxd"));
1491    /// ```
1492    ///
1493    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1494    #[inline]
1495    pub unsafe fn swap_tos_unchecked(&mut self, item: T) -> T {
1496        debug_assert!(!self.is_empty());
1497
1498        unsafe {
1499            // SAFETY: the user has assured us that there is an item to be swapped,
1500            // and that `item` won't point to garbage.
1501            let item = ptr::replace(
1502                self.items.as_mut_ptr().add(self.len - 1),
1503                mem::MaybeUninit::new(item),
1504            );
1505
1506            // SAFETY: the item has been correctly initialized at this point.
1507            item.assume_init()
1508        }
1509    }
1510
1511    /// Swaps TOS with TOS - 1. In other terms, swaps the topmost item of the stack
1512    /// with the one immediately below it.
1513    ///
1514    /// # Errors
1515    ///
1516    /// If the stack contains less than two items, [`StackError`] is
1517    /// returned.
1518    ///
1519    /// # Examples
1520    ///
1521    /// ```
1522    /// use astack::{stack, StackError};
1523    ///
1524    /// let mut stack1 = stack! {
1525    ///     [char; 10] = ['a', 'b']
1526    /// };
1527    ///
1528    /// stack1.rotate_tos().unwrap();
1529    /// assert_eq!(stack1.tos(), Some(&'a'));
1530    ///
1531    /// // Create a stack with no items.
1532    /// let mut stack2 = stack![i32; 5];
1533    /// assert_eq!(stack2.rotate_tos(), Err(StackError::Underflow));
1534    /// ```
1535    #[inline]
1536    pub fn rotate_tos(&mut self) -> Result<(), StackError> {
1537        if self.len < 2 {
1538            Err(StackError::Underflow)
1539        } else {
1540            unsafe { self.rotate_tos_unchecked() };
1541            Ok(())
1542        }
1543    }
1544
1545    /// Swaps TOS with TOS - 1. In other terms, swaps the topmost item of the stack
1546    /// with the one immediately below it.
1547    ///
1548    /// # Panics
1549    ///
1550    /// Panics if the stack contains less than 2 items.
1551    ///
1552    /// # Examples
1553    ///
1554    /// ```
1555    /// use astack::stack;
1556    ///
1557    /// let mut stack = stack! {
1558    ///     [isize; 5] = [90, 10, 30]
1559    /// };
1560    ///
1561    /// // This would panic if there were less than 2 items!
1562    /// stack.rotate_tos_panicking();
1563    /// assert_eq!(stack.tos(), Some(&10));
1564    ///
1565    /// // Rotate again!
1566    /// stack.rotate_tos_panicking();
1567    ///
1568    /// // Now the tos has been swapped twice.
1569    /// assert_eq!(stack.tos(), Some(&30));
1570    /// ```
1571    #[inline]
1572    pub fn rotate_tos_panicking(&mut self) {
1573        assert!(
1574            self.len >= 2,
1575            "Called Stack::rotate_tos_panicking but the stack contains 1 or 0 items"
1576        );
1577        unsafe { self.rotate_tos_unchecked() };
1578    }
1579
1580    /// Swaps TOS with TOS - 1. In other terms, swaps the topmost item of the stack
1581    /// with the one immediately below it, without checking if the stack contains
1582    /// at least 2 items.
1583    ///
1584    /// # Safety
1585    ///
1586    /// Calling this method if the stack is contains less than 2 items
1587    /// is *[undefined behavior]*.
1588    ///
1589    /// # Examples
1590    ///
1591    /// ```
1592    /// use astack::stack;
1593    ///
1594    /// let mut stack = stack! {
1595    ///     [char; 80] = ['7', '8', '9']
1596    /// };
1597    ///
1598    /// // SAFETY: we know there are at least 2 items at this point.
1599    /// unsafe {
1600    ///     stack.rotate_tos_unchecked();
1601    /// }
1602    ///
1603    /// assert_eq!(stack.tos(), Some(&'8'));
1604    /// ```
1605    ///
1606    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1607    #[inline]
1608    pub unsafe fn rotate_tos_unchecked(&mut self) {
1609        debug_assert!(self.len >= 2);
1610
1611        // SAFETY: this is similar to slice::swap_unchecked.
1612        // Create only 1 single ptr (this is important!)
1613        let ptr = self.items.as_mut_ptr();
1614        unsafe {
1615            ptr::swap(ptr.add(self.len - 1), ptr.add(self.len - 2));
1616        }
1617    }
1618
1619    /// Shortens the stack, keeping the `len` elements and dropping
1620    /// the rest. If `len == stack.len`, nothing happens.
1621    ///
1622    /// # Errors
1623    ///
1624    /// Returns a [`StackError`] if `len > stack.len`.
1625    ///
1626    /// # Examples
1627    ///
1628    /// ```
1629    /// use astack::{stack, StackError};
1630    ///
1631    /// let mut stack = stack! {
1632    ///     [i8; 5] = [8, 3, 0]
1633    /// };
1634    ///
1635    /// // Remove 2 items, we don't need them!
1636    ///
1637    /// assert!(stack.truncate(2).is_ok());
1638    /// // There are not enough items to truncate!
1639    /// assert_eq!(stack.truncate(3), Err(StackError::Underflow));
1640    /// assert_eq!(stack.len(), 2);
1641    /// ```
1642    #[inline]
1643    pub fn truncate(&mut self, new_len: usize) -> Result<(), StackError> {
1644        if new_len > self.len {
1645            Err(StackError::Underflow)
1646        } else {
1647            unsafe { self.truncate_unchecked(new_len) };
1648            Ok(())
1649        }
1650    }
1651
1652    /// Shortens the stack, keeping the `len` elements and dropping
1653    /// the rest. If `len == stack.len`, nothing happens.
1654    ///
1655    /// # Panics
1656    ///
1657    /// Panics if `len > stack.len`.
1658    ///
1659    /// # Examples
1660    ///
1661    /// ```should_panic
1662    /// use astack::stack;
1663    ///
1664    /// let mut stack = stack! {
1665    ///     [i8; 5] = [8, 3, 0]
1666    /// };
1667    ///
1668    /// // Keep 2 items, we don't need them!
1669    ///
1670    /// stack.truncate_panicking(2);
1671    /// // When the following line is executed, the program panics, as there are not
1672    /// // enough items to remove!
1673    /// stack.truncate_panicking(3);
1674    /// ```
1675    #[inline]
1676    pub fn truncate_panicking(&mut self, new_len: usize) {
1677        assert!(
1678            new_len <= self.len,
1679            "Called Stack::truncate_panicking but `len` ({}) is greater than stack's len ({})",
1680            new_len,
1681            self.len
1682        );
1683        unsafe { self.truncate_unchecked(new_len) };
1684    }
1685
1686    /// Shortens the stack, keeping the `len` elements and dropping
1687    /// the rest. If `len == stack.len`, nothing happens. Does not check for the
1688    /// validity of `len`.
1689    ///
1690    /// # Safety
1691    ///
1692    /// If `len > stack.len`, *[undefined behavior]* occurs.
1693    ///
1694    /// # Examples
1695    ///
1696    /// ```
1697    /// use astack::{stack, Stack};
1698    ///
1699    /// // Create a function which removes all items from the stack!
1700    /// // This uses unsafe code but it is safe.
1701    ///
1702    /// fn truncate_all_items<T, const N: usize>(stack: &mut Stack<T, N>) {
1703    ///     unsafe { stack.truncate_unchecked(0) };
1704    /// }
1705    ///
1706    /// let mut stack = stack! {
1707    ///     [i32; 8] = [6, 7, 8, 9, 0]
1708    /// };
1709    ///
1710    /// assert_eq!(stack.len(), 5);
1711    /// truncate_all_items(&mut stack);
1712    /// assert!(stack.is_empty());
1713    /// ```
1714    ///
1715    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1716    #[inline]
1717    pub unsafe fn truncate_unchecked(&mut self, new_len: usize) {
1718        debug_assert!(new_len <= self.len);
1719
1720        // SAFETY: the user gave us a valid len.
1721        let remaining_len = self.len - new_len;
1722        unsafe {
1723            self.drop_items(remaining_len);
1724        }
1725        self.len = new_len;
1726    }
1727
1728    /// Apply `f` to TOS, returning [`StackError`] if the stack is empty. `f` receives
1729    /// a mutable reference to TOS, which can be modified accordingly.
1730    ///
1731    /// # Errors
1732    ///
1733    /// The function returns a [`StackError`] if the stack is empty, because in that
1734    /// situation you could not apply `f` to TOS.
1735    ///
1736    /// # Examples
1737    ///
1738    /// ```
1739    /// use astack::{stack, StackError};
1740    ///
1741    /// fn double(x: &mut usize) {
1742    ///     *x = *x * 2;
1743    /// }
1744    ///
1745    /// let mut stack = stack! {
1746    ///     [usize; 10] = [7, 8, 9]
1747    /// };
1748    ///
1749    /// assert_eq!(stack.apply_tos(double), Ok(()));
1750    /// assert_eq!(stack.tos(), Some(&18));
1751    ///
1752    /// // Let's try this on an empty stack...
1753    ///
1754    /// let mut empty_stack = stack![usize; 10];
1755    /// assert_eq!(empty_stack.apply_tos(double), Err(StackError::Underflow));
1756    /// ```
1757    #[inline]
1758    pub fn apply_tos<F>(&mut self, f: F) -> Result<(), StackError>
1759    where
1760        F: Fn(&mut T),
1761    {
1762        let Some(tos) = self.tos_mut() else {
1763            return Err(StackError::Underflow);
1764        };
1765
1766        f(tos);
1767        Ok(())
1768    }
1769
1770    /// Apply `f` to TOS, panicking if the stack is empty. `f` receives
1771    /// a mutable reference to TOS, which can be modified accordingly.
1772    ///
1773    /// # Examples
1774    ///
1775    /// ```should_panic
1776    /// use astack::stack;
1777    ///
1778    /// let mut names = stack! {
1779    ///     [String; 4] = ["Frank".to_string(), "Joe".to_string()]
1780    /// };
1781    ///
1782    /// names.apply_tos_panicking(|name| {
1783    ///     name.push('!');
1784    /// });
1785    /// assert_eq!(names.tos(), Some(&String::from("Joe!")));
1786    ///
1787    /// names.clear();
1788    ///
1789    /// // The program panics because there is no TOS here!
1790    /// names.apply_tos_panicking(|name| { name.push('!'); });
1791    /// ```
1792    #[inline]
1793    pub fn apply_tos_panicking<F>(&mut self, f: F)
1794    where
1795        F: Fn(&mut T),
1796    {
1797        assert!(
1798            !self.is_empty(),
1799            "Called Stack::apply_tos_panicking on empty stack"
1800        );
1801        unsafe {
1802            self.apply_tos_unchecked(f);
1803        }
1804    }
1805
1806    /// Apply `f` to TOS, without checking whether the stack is empty or not.
1807    /// `f` receives a mutable reference to TOS, which can be modified accordingly.
1808    ///
1809    /// # Safety
1810    ///
1811    /// Calling this method on an empty stack is *[undefined behaviour]*. Refer to
1812    /// [apply_tos][Stack::apply_tos] and [apply_tos_panicking][Stack::apply_tos_panicking]
1813    /// for a safe version of this function.
1814    ///
1815    /// # Examples
1816    ///
1817    /// ```
1818    /// use astack::Stack;
1819    ///
1820    /// fn create_a_non_empty_stack() -> Stack<i32, 16> {
1821    ///     Stack::fill_with_default()
1822    /// }
1823    ///
1824    /// let mut stack = create_a_non_empty_stack();
1825    ///
1826    /// // Safety: we know that the function never returns an empty stack.
1827    /// // It is therefore safe to call `apply_tos_unchecked` here.
1828    /// let set_to_max = |num: &mut i32| *num = i32::MAX;
1829    /// unsafe {
1830    ///     stack.apply_tos_unchecked(set_to_max);
1831    /// }
1832    /// assert_eq!(stack.tos(), Some(&i32::MAX));
1833    /// ```
1834    ///
1835    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1836    #[inline]
1837    pub unsafe fn apply_tos_unchecked<F>(&mut self, f: F)
1838    where
1839        F: Fn(&mut T),
1840    {
1841        debug_assert!(!self.is_empty());
1842
1843        // SAFETY: the user is upholding the safety contract here by promising
1844        // that the stack is not empty.
1845        f(unsafe { self.tos_mut_unchecked() });
1846    }
1847
1848    /// Removes all the initialized items contained in the stack. The `len` becomes
1849    /// 0.
1850    ///
1851    /// # Examples
1852    ///
1853    /// ```
1854    /// use astack::stack;
1855    ///
1856    /// let mut stack = stack! {
1857    ///     [u64; 128] = [7, 8, 9, 10]
1858    /// };
1859    /// assert!(!stack.is_empty());
1860    ///
1861    /// // Remove all the stack items.
1862    /// stack.clear();
1863    /// assert!(stack.is_empty());
1864    /// ```
1865    #[inline]
1866    pub fn clear(&mut self) {
1867        // SAFETY: the items have been correctly initialized, this SHOULD not
1868        // result in a double free (unless user-provied incorrect initialization).
1869        unsafe { self.drop_items(0) };
1870        self.len = 0;
1871    }
1872
1873    /// The implementation of [`Drop::drop`] for [`Stack`].
1874    #[inline]
1875    unsafe fn drop_items(&mut self, start: usize) {
1876        // SAFETY: mem::MaybeUninit<T> has the same memory layout and align as T,
1877        // as it is #[repr(transparent)]. We assume that self.items[..self.len]
1878        // have been correctly initialized: if this is not the case, we drop
1879        // uninit memory, which is bad I suppose. But the user had been warned!
1880        //
1881        // We take inspiration from the Drop implementation of Vec<T> and from
1882        // the link below.
1883        //
1884        // https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.slice_assume_init_mut
1885        unsafe {
1886            let items = self.init_items_as_mut_ptr(start);
1887            ptr::drop_in_place(items);
1888        }
1889    }
1890
1891    /// Returns an immutable raw pointer to a slice of initialized items, beginning
1892    /// from `start`. If `start` is 0, this will return all the initialized items.
1893    #[inline]
1894    unsafe fn init_items_as_ptr(&self, start: usize) -> *const [T] {
1895        debug_assert!(start <= self.len);
1896
1897        // SAFETY: this is only called internally and we know what we are doing.
1898        unsafe { self.items.get_unchecked(start..self.len) as *const [mem::MaybeUninit<T>] as _ }
1899    }
1900
1901    /// Returns a mutable raw pointer to a slice of initialized items, beginning
1902    /// from `start`. If `start` is 0, this will return all the initialized items.
1903    #[inline]
1904    unsafe fn init_items_as_mut_ptr(&mut self, start: usize) -> *mut [T] {
1905        debug_assert!(start <= self.len);
1906
1907        // SAFETY: this is only called internally and we know what we are doing.
1908        unsafe { self.items.get_unchecked_mut(start..self.len) as *mut [mem::MaybeUninit<T>] as _ }
1909    }
1910}
1911
1912impl<T, const N: usize> Default for Stack<T, N> {
1913    /// `Stack::<T, N>::default()` is equivalent to `Stack::<T, N>::new()`.
1914    #[inline]
1915    fn default() -> Self {
1916        Self::new()
1917    }
1918}
1919
1920impl<T, const N: usize> Clone for Stack<T, N>
1921where
1922    T: Clone,
1923{
1924    #[inline]
1925    fn clone(&self) -> Self {
1926        // Create an array of uninitialized memory and fill each uninitialized
1927        // cell with a copy of the corresponding initialized item.
1928        unsafe {
1929            let mut items = mem::MaybeUninit::<[mem::MaybeUninit<T>; N]>::uninit().assume_init();
1930            self.items
1931                .get_unchecked(..self.len)
1932                .iter()
1933                .zip(items.get_unchecked_mut(..self.len))
1934                .for_each(|(src, dst)| {
1935                    dst.write(src.assume_init_ref().clone());
1936                });
1937            Self {
1938                items,
1939                len: self.len,
1940            }
1941        }
1942    }
1943}
1944
1945impl<T, U, const N: usize> PartialEq<Stack<U, N>> for Stack<T, N>
1946where
1947    T: PartialEq<U>,
1948{
1949    #[inline]
1950    fn eq(&self, other: &Stack<U, N>) -> bool {
1951        unsafe {
1952            let items1 = self.init_items_as_ptr(0);
1953            let items2 = other.init_items_as_ptr(0);
1954
1955            // SAFETY: the following items should have been correctly initialized
1956            *items1 == *items2
1957        }
1958    }
1959}
1960
1961impl<T, U, const N: usize> PartialEq<[U]> for Stack<T, N>
1962where
1963    T: PartialEq<U>,
1964{
1965    #[inline]
1966    fn eq(&self, other: &[U]) -> bool {
1967        unsafe {
1968            let items = self.init_items_as_ptr(0);
1969            *items == *other
1970        }
1971    }
1972}
1973
1974impl<T, U, const N: usize, const M: usize> PartialEq<[U; M]> for Stack<T, N>
1975where
1976    T: PartialEq<U>,
1977{
1978    #[inline]
1979    fn eq(&self, other: &[U; M]) -> bool {
1980        unsafe {
1981            let items = self.init_items_as_ptr(0);
1982            *items == *other
1983        }
1984    }
1985}
1986
1987impl<T, const N: usize> hash::Hash for Stack<T, N>
1988where
1989    T: hash::Hash,
1990{
1991    #[inline]
1992    fn hash<H>(&self, state: &mut H)
1993    where
1994        H: hash::Hasher,
1995    {
1996        ptr::hash(unsafe { self.init_items_as_ptr(0) }, state);
1997    }
1998}
1999
2000impl<T, const N: usize> fmt::Debug for Stack<T, N>
2001where
2002    T: fmt::Debug,
2003{
2004    #[inline]
2005    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2006        // Better print output
2007        struct DebugUninit;
2008        impl fmt::Debug for DebugUninit {
2009            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2010                write!(f, "(uninit)")
2011            }
2012        }
2013
2014        let mut list = f.debug_list();
2015
2016        unsafe {
2017            list.entries(
2018                self.items
2019                    .get_unchecked(..self.len)
2020                    .iter()
2021                    .map(|item| item.assume_init_ref()),
2022            );
2023        }
2024
2025        list.entries((self.len..N).map(|_| &DebugUninit));
2026
2027        list.finish()
2028    }
2029}
2030
2031impl<T, const N: usize> Drop for Stack<T, N> {
2032    #[inline]
2033    fn drop(&mut self) {
2034        unsafe { self.drop_items(0) };
2035    }
2036}
2037
2038#[cfg(feature = "std")]
2039impl<T, const N: usize> From<Stack<T, N>> for std::vec::Vec<T> {
2040    #[inline]
2041    fn from(stack: Stack<T, N>) -> Self {
2042        let mut v = std::vec::Vec::with_capacity(stack.len());
2043        // We rev because we want the end of the vec to be the top
2044        // of the stack
2045        v.extend(stack.into_iter().rev());
2046        v
2047    }
2048}
2049
2050#[cfg(feature = "std")]
2051impl<T, const N: usize> TryFrom<std::vec::Vec<T>> for Stack<T, N> {
2052    type Error = StackError;
2053
2054    #[inline]
2055    fn try_from(v: std::vec::Vec<T>) -> Result<Self, Self::Error> {
2056        try_extend_into_iter(v.len(), v)
2057    }
2058}
2059
2060#[cfg(feature = "std")]
2061impl<T, const N: usize> TryFrom<std::collections::LinkedList<T>> for Stack<T, N> {
2062    type Error = StackError;
2063
2064    #[inline]
2065    fn try_from(list: std::collections::LinkedList<T>) -> Result<Self, Self::Error> {
2066        try_extend_into_iter(list.len(), list)
2067    }
2068}
2069
2070#[cfg(feature = "std")]
2071#[inline]
2072fn try_extend_into_iter<T, const N: usize>(
2073    len: usize,
2074    it: impl IntoIterator<Item = T>,
2075) -> Result<Stack<T, N>, StackError> {
2076    if len > N {
2077        return Err(StackError::Overflow);
2078    }
2079
2080    let mut stack = Stack::new();
2081
2082    // SAFETY: we know that the iterator does not have more items
2083    // than the stack's remaining capacity
2084    unsafe {
2085        stack.extend_unchecked(it);
2086    }
2087    Ok(stack)
2088}
2089
2090impl<T, const N: usize> IntoIterator for Stack<T, N> {
2091    type IntoIter = StackIntoIter<T, N>;
2092    type Item = T;
2093
2094    #[inline]
2095    fn into_iter(mut self) -> Self::IntoIter {
2096        // Replace the items with the default array
2097        //
2098        // SAFETY: same as `Stack::new()`
2099        let items = mem::replace(&mut self.items, unsafe {
2100            mem::MaybeUninit::uninit().assume_init()
2101        });
2102
2103        // Do not forget to reset the length as well otherwise we drop more than we have!
2104        let top_len = mem::replace(&mut self.len, 0);
2105
2106        // Safety: `items` and `top_len` are valid as they come from us
2107        unsafe { StackIntoIter::new(items, top_len) }
2108    }
2109}