ringbuffer/with_alloc/
vecdeque.rs

1use crate::ringbuffer_trait::{RingBufferIntoIterator, RingBufferIterator, RingBufferMutIterator};
2use crate::{AllocRingBuffer, RingBuffer};
3use alloc::collections::VecDeque;
4use core::ops::{Deref, DerefMut, Index, IndexMut};
5
6/// A growable ringbuffer. Once capacity is reached, the size is doubled.
7/// Wrapper of the built-in [`VecDeque`] struct.
8///
9/// The reason this is a wrapper, is that we want `RingBuffers` to implement `Index<isize>`,
10/// which we cannot do for remote types like `VecDeque`
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct GrowableAllocRingBuffer<T>(VecDeque<T>);
13
14impl<T, const N: usize> From<[T; N]> for GrowableAllocRingBuffer<T> {
15    fn from(value: [T; N]) -> Self {
16        Self(VecDeque::from(value))
17    }
18}
19
20impl<T> From<VecDeque<T>> for GrowableAllocRingBuffer<T> {
21    fn from(value: VecDeque<T>) -> Self {
22        Self(value)
23    }
24}
25
26impl<T: Clone, const N: usize> From<&[T; N]> for GrowableAllocRingBuffer<T> {
27    // the cast here is actually not trivial
28    #[allow(trivial_casts)]
29    fn from(value: &[T; N]) -> Self {
30        Self::from(value as &[T])
31    }
32}
33
34impl<T: Clone> From<&[T]> for GrowableAllocRingBuffer<T> {
35    fn from(value: &[T]) -> Self {
36        let mut rb = Self::new();
37        rb.extend(value.iter().cloned());
38        rb
39    }
40}
41
42impl<T> From<AllocRingBuffer<T>> for GrowableAllocRingBuffer<T> {
43    fn from(mut v: AllocRingBuffer<T>) -> GrowableAllocRingBuffer<T> {
44        let mut rb = GrowableAllocRingBuffer::new();
45        rb.extend(v.drain());
46        rb
47    }
48}
49
50impl<T: Clone> From<&mut [T]> for GrowableAllocRingBuffer<T> {
51    fn from(value: &mut [T]) -> Self {
52        Self::from(&*value)
53    }
54}
55
56impl<T: Clone, const CAP: usize> From<&mut [T; CAP]> for GrowableAllocRingBuffer<T> {
57    fn from(value: &mut [T; CAP]) -> Self {
58        Self::from(value.clone())
59    }
60}
61
62impl<T> From<alloc::vec::Vec<T>> for GrowableAllocRingBuffer<T> {
63    fn from(value: alloc::vec::Vec<T>) -> Self {
64        let mut res = GrowableAllocRingBuffer::new();
65        res.extend(value);
66        res
67    }
68}
69
70impl<T> From<alloc::collections::LinkedList<T>> for GrowableAllocRingBuffer<T> {
71    fn from(value: alloc::collections::LinkedList<T>) -> Self {
72        let mut res = GrowableAllocRingBuffer::new();
73        res.extend(value);
74        res
75    }
76}
77
78impl From<alloc::string::String> for GrowableAllocRingBuffer<char> {
79    fn from(value: alloc::string::String) -> Self {
80        let mut res = GrowableAllocRingBuffer::new();
81        res.extend(value.chars());
82        res
83    }
84}
85
86impl From<&str> for GrowableAllocRingBuffer<char> {
87    fn from(value: &str) -> Self {
88        let mut res = GrowableAllocRingBuffer::new();
89        res.extend(value.chars());
90        res
91    }
92}
93
94impl<T, const CAP: usize> From<crate::ConstGenericRingBuffer<T, CAP>>
95    for GrowableAllocRingBuffer<T>
96{
97    fn from(mut value: crate::ConstGenericRingBuffer<T, CAP>) -> Self {
98        let mut res = GrowableAllocRingBuffer::new();
99        res.extend(value.drain());
100        res
101    }
102}
103
104impl<T> Deref for GrowableAllocRingBuffer<T> {
105    type Target = VecDeque<T>;
106
107    fn deref(&self) -> &Self::Target {
108        &self.0
109    }
110}
111
112impl<T> DerefMut for GrowableAllocRingBuffer<T> {
113    fn deref_mut(&mut self) -> &mut Self::Target {
114        &mut self.0
115    }
116}
117
118impl<T> Default for GrowableAllocRingBuffer<T> {
119    fn default() -> Self {
120        Self::new()
121    }
122}
123
124impl<T> AsRef<VecDeque<T>> for GrowableAllocRingBuffer<T> {
125    fn as_ref(&self) -> &VecDeque<T> {
126        &self.0
127    }
128}
129
130impl<T> GrowableAllocRingBuffer<T> {
131    /// Creates an empty ringbuffer.
132    #[must_use]
133    pub fn new() -> Self {
134        Self(VecDeque::new())
135    }
136
137    /// Creates an empty ringbuffer with space for at least capacity elements.
138    #[must_use]
139    pub fn with_capacity(capacity: usize) -> Self {
140        Self(VecDeque::with_capacity(capacity))
141    }
142}
143
144impl<T> IntoIterator for GrowableAllocRingBuffer<T> {
145    type Item = T;
146    type IntoIter = RingBufferIntoIterator<T, Self>;
147
148    fn into_iter(self) -> Self::IntoIter {
149        RingBufferIntoIterator::new(self)
150    }
151}
152
153impl<'a, T> IntoIterator for &'a GrowableAllocRingBuffer<T> {
154    type Item = &'a T;
155    type IntoIter = RingBufferIterator<'a, T, GrowableAllocRingBuffer<T>>;
156
157    fn into_iter(self) -> Self::IntoIter {
158        self.iter()
159    }
160}
161
162impl<'a, T> IntoIterator for &'a mut GrowableAllocRingBuffer<T> {
163    type Item = &'a mut T;
164    type IntoIter = RingBufferMutIterator<'a, T, GrowableAllocRingBuffer<T>>;
165
166    fn into_iter(self) -> Self::IntoIter {
167        self.iter_mut()
168    }
169}
170
171unsafe impl<T> RingBuffer<T> for GrowableAllocRingBuffer<T> {
172    unsafe fn ptr_len(rb: *const Self) -> usize {
173        (*rb).0.len()
174    }
175
176    #[inline]
177    unsafe fn ptr_capacity(rb: *const Self) -> usize {
178        (*rb).0.capacity()
179    }
180    #[inline]
181    unsafe fn ptr_buffer_size(rb: *const Self) -> usize {
182        (*rb).0.capacity()
183    }
184
185    fn dequeue(&mut self) -> Option<T> {
186        self.pop_front()
187    }
188
189    fn enqueue(&mut self, value: T) -> Option<T> {
190        self.push_back(value);
191        None
192    }
193
194    fn fill_with<F: FnMut() -> T>(&mut self, mut f: F) {
195        self.clear();
196        let initial_capacity = self.0.capacity();
197        for _ in 0..initial_capacity {
198            self.0.push_back(f());
199        }
200
201        debug_assert_eq!(initial_capacity, self.0.capacity());
202    }
203
204    fn clear(&mut self) {
205        self.0.clear();
206    }
207
208    fn get(&self, index: usize) -> Option<&T> {
209        if self.is_empty() {
210            None
211        } else {
212            self.0.get(crate::mask_modulo(self.0.len(), index))
213        }
214    }
215
216    fn get_signed(&self, index: isize) -> Option<&T> {
217        if self.is_empty() {
218            None
219        } else if index >= 0 {
220            self.0
221                .get(crate::mask_modulo(self.0.len(), index.unsigned_abs()))
222        } else {
223            let positive_index = index.unsigned_abs() - 1;
224            let masked = crate::mask_modulo(self.0.len(), positive_index);
225            let index = self.0.len() - 1 - masked;
226
227            self.0.get(index)
228        }
229    }
230
231    unsafe fn ptr_get_mut_signed(rb: *mut Self, index: isize) -> Option<*mut T> {
232        #[allow(trivial_casts)]
233        if RingBuffer::ptr_len(rb) == 0 {
234            None
235        } else if index >= 0 {
236            (*rb).0.get_mut(index.unsigned_abs())
237        } else {
238            let len = Self::ptr_len(rb);
239
240            let positive_index = index.unsigned_abs() + 1;
241            let masked = crate::mask_modulo(len, positive_index);
242            let index = len - 1 - masked;
243
244            (*rb).0.get_mut(index)
245        }
246        .map(|i| i as *mut T)
247    }
248
249    unsafe fn ptr_get_mut(rb: *mut Self, index: usize) -> Option<*mut T> {
250        #[allow(trivial_casts)]
251        if RingBuffer::ptr_len(rb) == 0 {
252            None
253        } else {
254            (*rb).0.get_mut(index)
255        }
256        .map(|i| i as *mut T)
257    }
258
259    unsafe fn ptr_copy_to_slice(rb: *const Self, offset: usize, dst: &mut [T])
260    where
261        T: Copy,
262    {
263        let len = Self::ptr_len(rb);
264        let dst_len = dst.len();
265        assert!(
266            (offset == 0 && len == 0) || offset < len,
267            "offset ({offset}) is out of bounds for the current buffer length ({len})"
268        );
269        assert!(len - offset == dst_len, "destination slice length ({dst_len}) doesn't match buffer length ({len}) when considering the specified offset ({offset})");
270
271        if dst_len == 0 {
272            return;
273        }
274
275        let (front, back) = (*rb).0.as_slices();
276        let first_len = front.len();
277
278        if offset < first_len {
279            let n_in_first = first_len - offset;
280            dst[..n_in_first].copy_from_slice(&front[offset..]);
281
282            if n_in_first < dst_len {
283                dst[n_in_first..].copy_from_slice(&back[..dst_len - n_in_first]);
284            }
285        } else {
286            dst.copy_from_slice(&back[offset - first_len..]);
287        }
288    }
289
290    unsafe fn ptr_copy_from_slice(rb: *mut Self, offset: usize, src: &[T])
291    where
292        T: Copy,
293    {
294        let len = Self::ptr_len(rb);
295        let src_len = src.len();
296        assert!(
297            (offset == 0 && len == 0) || offset < len,
298            "offset ({offset}) is out of bounds for the current buffer length ({len})"
299        );
300        assert!(len - offset == src_len, "source slice length ({src_len}) doesn't match buffer length ({len}) when considering the specified offset ({offset})");
301
302        if src_len == 0 {
303            return;
304        }
305
306        let (front, back) = (*rb).0.as_mut_slices();
307        let first_len = front.len();
308
309        if offset < first_len {
310            let n_in_first = first_len - offset;
311            front[offset..].copy_from_slice(&src[..n_in_first]);
312
313            if n_in_first < src_len {
314                back[..src_len - n_in_first].copy_from_slice(&src[n_in_first..]);
315            }
316        } else {
317            back[offset - first_len..].copy_from_slice(src);
318        }
319    }
320}
321
322impl<T> Extend<T> for GrowableAllocRingBuffer<T> {
323    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
324        self.0.extend(iter);
325    }
326}
327
328impl<T> Index<usize> for GrowableAllocRingBuffer<T> {
329    type Output = T;
330
331    fn index(&self, index: usize) -> &Self::Output {
332        self.get(index).expect("index out of bounds")
333    }
334}
335
336impl<T> IndexMut<usize> for GrowableAllocRingBuffer<T> {
337    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
338        self.get_mut(index).expect("index out of bounds")
339    }
340}
341
342impl<T> FromIterator<T> for GrowableAllocRingBuffer<T> {
343    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
344        Self(VecDeque::from_iter(iter))
345    }
346}