stack_array/
lib.rs

1#![doc = include_str!("../README.md")]
2
3mod drain;
4mod interface;
5mod partial_eq;
6mod retain_mut;
7mod vector;
8mod write;
9
10pub use drain::Drain;
11pub use interface::Array;
12use retain_mut::retain_mut;
13
14use core::{
15    borrow::*,
16    fmt, hash, mem,
17    mem::MaybeUninit,
18    ops,
19    ops::{Deref, DerefMut, Index, IndexMut, Range, RangeBounds},
20    ptr,
21    ptr::NonNull,
22    slice,
23    slice::SliceIndex,
24};
25use std::cmp;
26
27/// A data structure for storing and manipulating fixed number of elements of a specific type.
28pub struct ArrayBuf<T, const N: usize> {
29    len: usize,
30    buf: [MaybeUninit<T>; N],
31}
32
33impl<T, const N: usize> ArrayBuf<T, N> {
34    /// Constructs a new, `ArrayBuf`
35    ///
36    /// # Examples
37    ///
38    /// ```
39    /// use stack_array::*;
40    ///
41    /// let mut arr: ArrayBuf<u8, 64> = ArrayBuf::new();
42    /// ```
43    #[inline]
44    pub const fn new() -> Self {
45        Self {
46            len: 0,
47            buf: unsafe { MaybeUninit::uninit().assume_init() },
48        }
49    }
50
51    /// Returns `true`, If the array is full.
52    ///
53    /// # Examples
54    ///
55    /// ```
56    /// use stack_array::*;
57    ///
58    /// let arr = ArrayBuf::from([1, 2, 3]);
59    /// assert!(arr.is_full());
60    /// ```
61    #[inline]
62    pub const fn is_full(&self) -> bool {
63        self.len >= N
64    }
65}
66
67impl<T, const N: usize> Array<T> for ArrayBuf<T, N> {
68    #[inline]
69    fn capacity(&self) -> usize {
70        N
71    }
72
73    #[inline]
74    fn as_ptr(&self) -> *const T {
75        self.buf.as_ptr() as _
76    }
77
78    #[inline]
79    fn as_mut_ptr(&mut self) -> *mut T {
80        self.buf.as_mut_ptr() as _
81    }
82
83    #[inline]
84    unsafe fn set_len(&mut self, new_len: usize) {
85        debug_assert!(new_len <= self.capacity());
86        self.len = new_len;
87    }
88
89    #[inline]
90    fn len(&self) -> usize {
91        self.len
92    }
93}
94
95impl<T, const N: usize> Drop for ArrayBuf<T, N> {
96    fn drop(&mut self) {
97        self.clear();
98    }
99}
100
101impl<T, const N: usize> Default for ArrayBuf<T, N> {
102    #[inline]
103    fn default() -> Self {
104        Self::new()
105    }
106}
107
108impl<T, const N: usize> AsRef<[T]> for ArrayBuf<T, N> {
109    #[inline]
110    fn as_ref(&self) -> &[T] {
111        self
112    }
113}
114
115impl<T, const N: usize> AsMut<[T]> for ArrayBuf<T, N> {
116    #[inline]
117    fn as_mut(&mut self) -> &mut [T] {
118        self
119    }
120}
121
122impl<T, const N: usize> Deref for ArrayBuf<T, N> {
123    type Target = [T];
124    #[inline]
125    fn deref(&self) -> &Self::Target {
126        self.as_slice()
127    }
128}
129
130impl<T, const N: usize> DerefMut for ArrayBuf<T, N> {
131    #[inline]
132    fn deref_mut(&mut self) -> &mut Self::Target {
133        self.as_mut_slice()
134    }
135}
136
137impl<T: Copy, const N: usize> From<&[T]> for ArrayBuf<T, N> {
138    fn from(values: &[T]) -> Self {
139        let mut array = Self::new();
140        array.extend_from_slice(values);
141        array
142    }
143}
144
145impl<T: Copy, const N: usize> From<[T; N]> for ArrayBuf<T, N> {
146    fn from(values: [T; N]) -> Self {
147        let mut array = Self::new();
148        array.extend_from_slice(values);
149        array
150    }
151}
152
153impl<T, I: SliceIndex<[T]>, const N: usize> Index<I> for ArrayBuf<T, N> {
154    type Output = I::Output;
155    #[inline]
156    fn index(&self, index: I) -> &Self::Output {
157        Index::index(&**self, index)
158    }
159}
160
161impl<T, I: SliceIndex<[T]>, const N: usize> IndexMut<I> for ArrayBuf<T, N> {
162    #[inline]
163    fn index_mut(&mut self, index: I) -> &mut Self::Output {
164        IndexMut::index_mut(&mut **self, index)
165    }
166}
167
168impl<T: fmt::Debug, const N: usize> fmt::Debug for ArrayBuf<T, N> {
169    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
170        fmt::Debug::fmt(&**self, f)
171    }
172}
173
174impl<T, const N: usize> Borrow<[T]> for ArrayBuf<T, N> {
175    fn borrow(&self) -> &[T] {
176        &self[..]
177    }
178}
179
180impl<T, const N: usize> BorrowMut<[T]> for ArrayBuf<T, N> {
181    fn borrow_mut(&mut self) -> &mut [T] {
182        &mut self[..]
183    }
184}
185
186/// Implements comparison of vectors, [lexicographically](core::cmp::Ord#lexicographical-comparison).
187impl<T: PartialOrd, const N: usize> cmp::PartialOrd for ArrayBuf<T, N> {
188    #[inline]
189    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
190        PartialOrd::partial_cmp(&**self, &**other)
191    }
192}
193
194impl<T: Eq, const N: usize> Eq for ArrayBuf<T, N> {}
195
196/// Implements ordering of vectors, [lexicographically](core::cmp::Ord#lexicographical-comparison).
197impl<T: Ord, const N: usize> cmp::Ord for ArrayBuf<T, N> {
198    #[inline]
199    fn cmp(&self, other: &Self) -> cmp::Ordering {
200        Ord::cmp(&**self, &**other)
201    }
202}
203
204impl<T: hash::Hash, const N: usize> hash::Hash for ArrayBuf<T, N> {
205    fn hash<H: hash::Hasher>(&self, state: &mut H) {
206        hash::Hash::hash(&**self, state)
207    }
208}