oom/
vec.rs

1extern crate alloc;
2
3use alloc::vec::Vec;
4use core::cmp::Ordering;
5use core::hint::unreachable_unchecked;
6use core::mem::size_of;
7use core::num::NonZeroUsize;
8
9use crate::{NonEmptyMutSlice, NonEmptySlice};
10
11/// A non-empty vector type, counterpart of `Vec<T>`.
12pub struct NonEmptyVec<T: Sized> {
13    inner: Vec<T>,
14}
15
16const _SIZE: () = {
17    const FOO: [(); 1] = [()];
18    const SIZE: usize = size_of::<NonEmptyVec<&str>>();
19    #[cfg(target_pointer_width = "64")]
20    let idx = !(SIZE == 24) as usize;
21    #[cfg(target_pointer_width = "32")]
22    let idx = !(SIZE == 12) as usize;
23    FOO[idx]
24};
25
26const _BUILTIN_TRAITS: () = {
27    impl<T: Clone> Clone for NonEmptyVec<T> {
28        fn clone(&self) -> Self {
29            Self::from_vec(self.to_vec())
30        }
31    }
32
33    impl<T: Eq> Eq for NonEmptyVec<T> {}
34
35    impl<T: PartialEq> PartialEq for NonEmptyVec<T> {
36        fn eq(&self, other: &Self) -> bool {
37            self.as_slice().eq(other.as_slice())
38        }
39    }
40
41    impl<T: Ord> Ord for NonEmptyVec<T> {
42        fn cmp(&self, other: &Self) -> Ordering {
43            self.as_slice().cmp(other.as_slice())
44        }
45    }
46
47    impl<T: PartialOrd> PartialOrd for NonEmptyVec<T> {
48        fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
49            self.as_slice().partial_cmp(other.as_slice())
50        }
51    }
52
53    impl<T> AsRef<[T]> for NonEmptyVec<T> {
54        fn as_ref(&self) -> &[T] {
55            self.as_slice()
56        }
57    }
58};
59
60impl<T: Sized> NonEmptyVec<T> {
61    /// Converts a `Vec<T>` into a `NonEmptyVec`.
62    ///
63    /// # Panics
64    ///
65    /// This function will panic if passed `Vec` is empty.
66    pub fn from_vec(vec: Vec<T>) -> Self {
67        match Self::from_vec_checked(vec) {
68            Ok(v) => v,
69            Err(_) => panic!("vec shouldn't be empty"),
70        }
71    }
72
73    /// Converts a `Vec<T>` into a `NonEmptyVec`.
74    /// Returns passed `Vec` if it is empty.
75    pub fn from_vec_checked(vec: Vec<T>) -> Result<Self, Vec<T>> {
76        if vec.is_empty() {
77            return Err(vec);
78        }
79        Ok(Self { inner: vec })
80    }
81
82    /// Returns a raw pointer to the vector's buffer.
83    pub fn as_ptr(&self) -> *const T {
84        self.inner.as_ptr()
85    }
86
87    /// Returns an unsafe mutable pointer to the vector's buffer.
88    pub fn as_mut_ptr(&mut self) -> *mut T {
89        self.inner.as_mut_ptr()
90    }
91
92    /// Returns a non-empty slice from this vec.
93    pub fn as_nonempty_slice(&self) -> NonEmptySlice<'_, T> {
94        NonEmptySlice { inner: &self.inner }
95    }
96
97    /// Returns a non-empty mutable slice from this vec.
98    pub fn as_nonempty_mut_slice(&mut self) -> NonEmptyMutSlice<'_, T> {
99        NonEmptyMutSlice { inner: &mut self.inner }
100    }
101
102    /// Extracts a slice containing the entire vector.
103    pub fn as_slice(&self) -> &[T] {
104        self.inner.as_slice()
105    }
106
107    /// Extracts a mutable slice of the entire vector.
108    pub fn as_mut_slice(&mut self) -> &mut [T] {
109        self.inner.as_mut_slice()
110    }
111
112    /// Returns the number of elements in the vector.
113    pub fn len(&self) -> NonZeroUsize {
114        unsafe { NonZeroUsize::new_unchecked(self.inner.len()) }
115    }
116
117    /// Always returns `false` because the vector is non-empty.
118    pub fn is_empty(&self) -> bool {
119        false
120    }
121
122    /// Returns the number of elements the vector can hold without reallocating.
123    pub fn capacity(&self) -> NonZeroUsize {
124        unsafe { NonZeroUsize::new_unchecked(self.inner.capacity()) }
125    }
126
127    /// Converts `self` into a vector without clones or allocations.
128    pub fn into_vec(self) -> Vec<T> {
129        self.inner
130    }
131
132    /// Copies `self` into a new `Vec`.
133    pub fn to_vec(&self) -> Vec<T>
134    where
135        T: Clone,
136    {
137        self.as_slice().to_vec()
138    }
139
140    /// A shorthand for [`NonEmptyMutSlice::first`].
141    pub fn first(&self) -> &T {
142        match self.as_slice() {
143            [first, ..] => first,
144            [] => unsafe { unreachable_unchecked() },
145        }
146    }
147
148    /// A shorthand for [`NonEmptyMutSlice::first_mut`].
149    pub fn first_mut(&mut self) -> &mut T {
150        match self.as_mut_slice() {
151            [first, ..] => first,
152            [] => unsafe { unreachable_unchecked() },
153        }
154    }
155
156    /// A shorthand for [`NonEmptyMutSlice::last`].
157    pub fn last(&self) -> &T {
158        match self.as_slice() {
159            [.., last] => last,
160            [] => unsafe { unreachable_unchecked() },
161        }
162    }
163
164    /// A shorthand for [`NonEmptyMutSlice::last_mut`].
165    pub fn last_mut(&mut self) -> &mut T {
166        match self.as_mut_slice() {
167            [.., last] => last,
168            [] => unsafe { unreachable_unchecked() },
169        }
170    }
171
172    /// A shorthand for [`NonEmptyMutSlice::split_first`].
173    pub fn split_first(&self) -> (&T, &[T]) {
174        match self.as_slice() {
175            [first, rest @ ..] => (first, rest),
176            [] => unsafe { unreachable_unchecked() },
177        }
178    }
179
180    /// A shorthand for [`NonEmptyMutSlice::split_first_mut`].
181    pub fn split_first_mut(&mut self) -> (&mut T, &mut [T]) {
182        match self.as_mut_slice() {
183            [first, rest @ ..] => (first, rest),
184            [] => unsafe { unreachable_unchecked() },
185        }
186    }
187
188    /// A shorthand for [`NonEmptyMutSlice::split_last`].
189    pub fn split_last(&self) -> (&T, &[T]) {
190        match self.as_slice() {
191            [rest @ .., last] => (last, rest),
192            [] => unsafe { unreachable_unchecked() },
193        }
194    }
195
196    /// A shorthand for [`NonEmptyMutSlice::split_last_mut`].
197    pub fn split_last_mut(&mut self) -> (&mut T, &mut [T]) {
198        match self.as_mut_slice() {
199            [rest @ .., last] => (last, rest),
200            [] => unsafe { unreachable_unchecked() },
201        }
202    }
203}