reusing_vec/
lib.rs

1// Overrides for `docs.rs` links in the README. This first definition takes precedence.
2
3#![cfg_attr(feature = "std", doc = "[Vec]: std::vec::Vec")]
4
5// Normal link to crate items:
6//! [`ReusingVec`]: ReusingVec
7//! [`ReusingQueue`]: ReusingQueue
8//! [`pop_front`]: ReusingQueue::pop_front
9
10#![doc = include_str!("../README.md")]
11
12#![no_std]
13
14extern crate alloc;
15use alloc::vec::Vec;
16use alloc::string::String;
17use alloc::collections::*;
18
19mod queue;
20pub use queue::ReusingQueue;
21
22/// A wrapper around [`Vec`] that supports reusing contained elements without dropping them
23///
24/// NOTE: Many interfaces are missing or different because the recommended usage pattern is
25/// to leave elements in the vector, therefore interfaces like `pop` and `remove` are not
26/// included.  They could be, but that might (partially) defeat the purpose of this crate.
27///
28/// However, if there is an interface you would like, please raise an issue.
29#[derive(Clone, Default)]
30pub struct ReusingVec<T> {
31    logical_len: usize,
32    contents: Vec<T>
33}
34
35impl<T> core::fmt::Debug for ReusingVec<T> where T: core::fmt::Debug {
36    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
37        write!(f, "{:?}", self as &[_])
38    }
39}
40
41impl<T> ReusingVec<T> {
42    /// Create a new empty vector, does not allocate until the first element is added
43    #[inline]
44    pub const fn new() -> Self {
45        Self {
46            logical_len: 0,
47            contents: Vec::new()
48        }
49    }
50    /// Create a new empty vector with at least the specified capacity preallocated
51    #[inline]
52    pub fn with_capacity(capacity: usize) -> Self {
53        Self {
54            logical_len: 0,
55            contents: Vec::with_capacity(capacity)
56        }
57    }
58    /// Clears the vector, logically removing all values, but not dropping them
59    #[inline]
60    pub fn clear(&mut self) {
61        self.logical_len = 0;
62    }
63    /// Shortens the vector, keeping the first `len` elements and logically removing the rest
64    ///
65    /// If `len` is greater or equal to the vector’s current logical length, this has no effect.
66    #[inline]
67    pub fn truncate(&mut self, len: usize) {
68        if len < self.logical_len {
69            self.logical_len = len;
70        }
71    }
72    /// Returns the number of logical elements in the vector, also referred to as its ‘length’
73    #[inline]
74    pub fn len(&self) -> usize {
75        self.logical_len
76    }
77    /// Returns `true` if the vector contains no logical elements
78    #[inline]
79    pub fn is_empty(&self) -> bool {
80        self.logical_len == 0
81    }
82    /// Appends the provided element to the back of a vector, increasing the logical length by 1
83    ///
84    /// NOTE: This operation may cause an inactive `T` to be dropped, as it is overwritten by the
85    /// new element provided, so [`push_with`](Self::push_with) or [`push_mut`](Self::push_mut)
86    /// is the usual way to get the full benefit from this crate.
87    #[inline]
88    pub fn push_val(&mut self, val: T) {
89        if self.logical_len < self.contents.len() {
90            *self.contents.get_mut(self.logical_len).unwrap() = val;
91        } else {
92            self.contents.push(val);
93        }
94        self.logical_len += 1;
95    }
96    /// Appends an element to the back of a vector, increasing the logical length by 1,
97    /// creating or reinitializing the element with one of the supplied closures
98    #[inline]
99    pub fn push_with<NewF, ResetF>(&mut self, new_f: NewF, reset_f: ResetF)
100        where
101        NewF: FnOnce() -> T,
102        ResetF: FnOnce(&mut T)
103    {
104        if self.logical_len < self.contents.len() {
105            reset_f(self.contents.get_mut(self.logical_len).unwrap());
106        } else {
107            self.contents.push(new_f());
108        }
109        self.logical_len += 1;
110    }
111    /// Removes the last element from the vector
112    ///
113    /// Returns a mutable reference to the element that was removed, or `None` if the vector was already empty
114    #[inline]
115    pub fn pop(&mut self) -> Option<&mut T> {
116        if self.logical_len > 0 {
117            self.logical_len -= 1;
118            self.contents.get_mut(self.logical_len)
119        } else {
120            None
121        }
122    }
123}
124
125impl<T> AsMut<[T]> for ReusingVec<T> {
126    fn as_mut(&mut self) -> &mut [T] {
127        &mut self.contents[0..self.logical_len]
128    }
129}
130
131impl<T> AsRef<[T]> for ReusingVec<T> {
132    fn as_ref(&self) -> &[T] {
133        &self.contents[0..self.logical_len]
134    }
135}
136
137impl<T> core::borrow::Borrow<[T]> for ReusingVec<T> {
138    fn borrow(&self) -> &[T] {
139        &self.contents[0..self.logical_len]
140    }
141}
142
143impl<T> core::borrow::BorrowMut<[T]> for ReusingVec<T> {
144    fn borrow_mut(&mut self) -> &mut [T] {
145        &mut self.contents[0..self.logical_len]
146    }
147}
148
149impl<T> core::ops::Deref for ReusingVec<T> {
150    type Target = [T];
151    fn deref(&self) -> &[T] {
152        &self.contents[0..self.logical_len]
153    }
154}
155
156impl<T> core::ops::DerefMut for ReusingVec<T> {
157    fn deref_mut(&mut self) -> &mut [T] {
158        &mut self.contents[0..self.logical_len]
159    }
160}
161
162//NOTE: The extend interface defeats the point of this structure, so I'd rather not support it
163// impl<T: ReusableElement> Extend<T::ArgT> for ReusingVec<T> {
164//     fn extend<I>(&mut self, iter: I) where I: IntoIterator<Item = T::ArgT> {
165//         for element_args in iter {
166//             self.push(element_args);
167//         }
168//     }
169// }
170
171impl<T> From<Vec<T>> for ReusingVec<T> {
172    fn from(vec: Vec<T>) -> Self {
173        Self {
174            logical_len: vec.len(),
175            contents: vec
176        }
177    }
178}
179
180impl<T> From<ReusingVec<T>> for Vec<T> {
181    fn from(mut vec: ReusingVec<T>) -> Self {
182        vec.contents.truncate(vec.logical_len);
183        vec.contents
184    }
185}
186
187impl<T, U> FromIterator<U> for ReusingVec<T> where T: From<U> {
188    fn from_iter<I: IntoIterator<Item=U>>(iter: I) -> Self {
189        let contents: Vec<T> = iter.into_iter().map(|element| element.into()).collect();
190        Self {
191            logical_len: contents.len(),
192            contents,
193        }
194    }
195}
196
197impl<T> IntoIterator for ReusingVec<T> {
198    type Item = T;
199    type IntoIter = ReusingVecIter<T>;
200    fn into_iter(self) -> Self::IntoIter {
201        self.contents.into_iter().take(self.logical_len)
202    }
203}
204
205/// An [`Iterator`] created from a [`ReusingVec`]
206pub type ReusingVecIter<T> = core::iter::Take<alloc::vec::IntoIter<T>>;
207
208impl<T> PartialEq<Self> for ReusingVec<T> where T: PartialEq {
209    fn eq(&self, other: &Self) -> bool {
210        (self as &[T]).eq(other as &[T])
211    }
212}
213impl<T> Eq for ReusingVec<T> where T: Eq {}
214
215impl<T> PartialEq<[T]> for ReusingVec<T> where T: PartialEq {
216    fn eq(&self, other: &[T]) -> bool {
217        (self as &[T]).eq(other)
218    }
219}
220
221impl<T> PartialEq<Vec<T>> for ReusingVec<T> where T: PartialEq {
222    fn eq(&self, other: &Vec<T>) -> bool {
223        (self as &[T]).eq(other)
224    }
225}
226
227impl<T: ReusableElement> ReusingVec<T> {
228    /// Appends an empty element to the back of a vector, increasing the logical length by 1, and returns
229    /// a mutable reference to the new / re-initialized element
230    #[inline]
231    pub fn push_mut(&mut self) -> &mut T {
232        if self.logical_len < self.contents.len() {
233            self.contents.get_mut(self.logical_len).unwrap().reset();
234        } else {
235            self.contents.push(T::new());
236        }
237        let element = self.contents.get_mut(self.logical_len).unwrap();
238        self.logical_len += 1;
239        element
240    }
241}
242
243/// Implemented on element types to provide a unified interface for creating a new element and
244/// reinitializing an existing element
245pub trait ReusableElement {
246    fn reset(&mut self);
247    fn new() -> Self;
248}
249
250impl<T> ReusableElement for Option<T> {
251    fn reset(&mut self) {
252        *self = None
253    }
254    fn new() -> Self {
255        None
256    }
257}
258
259impl<T> ReusableElement for Vec<T> {
260    fn reset(&mut self) {
261        self.clear()
262    }
263    fn new() -> Self {
264        Self::new()
265    }
266}
267
268impl ReusableElement for String {
269    fn reset(&mut self) {
270        self.clear()
271    }
272    fn new() -> Self {
273        Self::new()
274    }
275}
276
277impl<T: Ord> ReusableElement for BinaryHeap<T> {
278    fn reset(&mut self) {
279        self.clear()
280    }
281    fn new() -> Self {
282        Self::new()
283    }
284}
285
286impl<K, V> ReusableElement for BTreeMap<K, V> {
287    fn reset(&mut self) {
288        self.clear()
289    }
290    fn new() -> Self {
291        Self::new()
292    }
293}
294
295impl<T> ReusableElement for BTreeSet<T> {
296    fn reset(&mut self) {
297        self.clear()
298    }
299    fn new() -> Self {
300        Self::new()
301    }
302}
303
304impl<T> ReusableElement for LinkedList<T> {
305    fn reset(&mut self) {
306        self.clear()
307    }
308    fn new() -> Self {
309        Self::new()
310    }
311}
312
313impl<T> ReusableElement for VecDeque<T> {
314    fn reset(&mut self) {
315        self.clear()
316    }
317    fn new() -> Self {
318        Self::new()
319    }
320}
321
322#[cfg(feature = "std")]
323extern crate std;
324
325#[cfg(feature = "std")]
326impl<K, V> ReusableElement for std::collections::HashMap<K, V> {
327    fn reset(&mut self) {
328        self.clear()
329    }
330    fn new() -> Self {
331        Self::new()
332    }
333}
334
335#[cfg(feature = "std")]
336impl<T> ReusableElement for std::collections::HashSet<T> {
337    fn reset(&mut self) {
338        self.clear()
339    }
340    fn new() -> Self {
341        Self::new()
342    }
343}
344
345#[cfg(feature = "smallvec")]
346impl<A: smallvec::Array> ReusableElement for smallvec::SmallVec<A> {
347    fn reset(&mut self) {
348        self.clear()
349    }
350    fn new() -> Self {
351        Self::new()
352    }
353}