1use core::ops::{Index, IndexMut};
2
3use crate::ringbuffer_trait::{
4 RingBuffer, RingBufferIntoIterator, RingBufferIterator, RingBufferMutIterator,
5};
6
7extern crate alloc;
8
9use crate::{impl_ring_buffer_set_len, mask_and, GrowableAllocRingBuffer, SetLen};
11use core::ptr;
12
13#[derive(Debug)]
40pub struct AllocRingBuffer<T> {
41 pub(crate) buf: *mut T,
42
43 size: usize,
45 capacity: usize,
48
49 readptr: usize,
50 writeptr: usize,
51}
52
53unsafe impl<T: Sync> Sync for AllocRingBuffer<T> {}
56unsafe impl<T: Send> Send for AllocRingBuffer<T> {}
57
58impl<T, const N: usize> From<[T; N]> for AllocRingBuffer<T> {
59 fn from(value: [T; N]) -> Self {
60 let mut rb = Self::new(value.len());
61 rb.extend(value);
62 rb
63 }
64}
65
66impl<T: Clone, const N: usize> From<&[T; N]> for AllocRingBuffer<T> {
67 #[allow(trivial_casts)]
69 fn from(value: &[T; N]) -> Self {
70 Self::from(value as &[T])
71 }
72}
73
74impl<T: Clone> From<&[T]> for AllocRingBuffer<T> {
75 fn from(value: &[T]) -> Self {
76 let mut rb = Self::new(value.len());
77 rb.extend(value.iter().cloned());
78 rb
79 }
80}
81
82impl<T> From<GrowableAllocRingBuffer<T>> for AllocRingBuffer<T> {
83 fn from(mut v: GrowableAllocRingBuffer<T>) -> AllocRingBuffer<T> {
84 let mut rb = AllocRingBuffer::new(v.len());
85 rb.extend(v.drain());
86 rb
87 }
88}
89
90impl<T: Clone> From<&mut [T]> for AllocRingBuffer<T> {
91 fn from(value: &mut [T]) -> Self {
92 Self::from(&*value)
93 }
94}
95
96impl<T: Clone, const CAP: usize> From<&mut [T; CAP]> for AllocRingBuffer<T> {
97 fn from(value: &mut [T; CAP]) -> Self {
98 Self::from(value.clone())
99 }
100}
101
102impl<T> From<alloc::vec::Vec<T>> for AllocRingBuffer<T> {
103 fn from(value: alloc::vec::Vec<T>) -> Self {
104 let mut res = AllocRingBuffer::new(value.len());
105 res.extend(value);
106 res
107 }
108}
109
110impl<T> From<alloc::collections::VecDeque<T>> for AllocRingBuffer<T> {
111 fn from(value: alloc::collections::VecDeque<T>) -> Self {
112 let mut res = AllocRingBuffer::new(value.len());
113 res.extend(value);
114 res
115 }
116}
117
118impl<T> From<alloc::collections::LinkedList<T>> for AllocRingBuffer<T> {
119 fn from(value: alloc::collections::LinkedList<T>) -> Self {
120 let mut res = AllocRingBuffer::new(value.len());
121 res.extend(value);
122 res
123 }
124}
125
126impl From<alloc::string::String> for AllocRingBuffer<char> {
127 fn from(value: alloc::string::String) -> Self {
128 let mut res = AllocRingBuffer::new(value.len());
129 res.extend(value.chars());
130 res
131 }
132}
133
134impl From<&str> for AllocRingBuffer<char> {
135 fn from(value: &str) -> Self {
136 let mut res = AllocRingBuffer::new(value.len());
137 res.extend(value.chars());
138 res
139 }
140}
141
142impl<T, const CAP: usize> From<crate::ConstGenericRingBuffer<T, CAP>> for AllocRingBuffer<T> {
143 fn from(mut value: crate::ConstGenericRingBuffer<T, CAP>) -> Self {
144 let mut res = AllocRingBuffer::new(value.len());
145 res.extend(value.drain());
146 res
147 }
148}
149
150impl<T> Drop for AllocRingBuffer<T> {
151 fn drop(&mut self) {
152 self.drain().for_each(drop);
153
154 let layout = alloc::alloc::Layout::array::<T>(self.size).unwrap();
155 unsafe {
156 alloc::alloc::dealloc(self.buf.cast(), layout);
157 }
158 }
159}
160
161impl<T: Clone> Clone for AllocRingBuffer<T> {
162 fn clone(&self) -> Self {
163 debug_assert_ne!(self.capacity, 0);
164
165 let mut new = Self::new(self.capacity);
166 new.extend(self.iter().cloned());
167 new
168 }
169}
170
171impl<T: PartialEq> PartialEq for AllocRingBuffer<T> {
172 fn eq(&self, other: &Self) -> bool {
173 self.capacity == other.capacity
174 && self.len() == other.len()
175 && self.iter().zip(other.iter()).all(|(a, b)| a == b)
176 }
177}
178
179impl<T: Eq + PartialEq> Eq for AllocRingBuffer<T> {}
180
181impl<T> IntoIterator for AllocRingBuffer<T> {
182 type Item = T;
183 type IntoIter = RingBufferIntoIterator<T, Self>;
184
185 fn into_iter(self) -> Self::IntoIter {
186 RingBufferIntoIterator::new(self)
187 }
188}
189
190#[allow(clippy::into_iter_without_iter)]
191impl<'a, T> IntoIterator for &'a AllocRingBuffer<T> {
193 type Item = &'a T;
194 type IntoIter = RingBufferIterator<'a, T, AllocRingBuffer<T>>;
195
196 fn into_iter(self) -> Self::IntoIter {
197 self.iter()
198 }
199}
200
201#[allow(clippy::into_iter_without_iter)]
202impl<'a, T> IntoIterator for &'a mut AllocRingBuffer<T> {
204 type Item = &'a mut T;
205 type IntoIter = RingBufferMutIterator<'a, T, AllocRingBuffer<T>>;
206
207 fn into_iter(self) -> Self::IntoIter {
208 self.iter_mut()
209 }
210}
211
212impl<T> Extend<T> for AllocRingBuffer<T> {
213 fn extend<A: IntoIterator<Item = T>>(&mut self, iter: A) {
214 let iter = iter.into_iter();
215
216 for i in iter {
217 let _ = self.enqueue(i);
218 }
219 }
220}
221
222unsafe impl<T> RingBuffer<T> for AllocRingBuffer<T> {
223 #[inline]
224 unsafe fn ptr_capacity(rb: *const Self) -> usize {
225 (*rb).capacity
226 }
227
228 #[inline]
229 unsafe fn ptr_buffer_size(rb: *const Self) -> usize {
230 (*rb).size
231 }
232
233 impl_ringbuffer!(readptr, writeptr);
234
235 #[inline]
236 fn enqueue(&mut self, value: T) -> Option<T> {
237 let mut ret = None;
238
239 if self.is_full() {
240 let previous_value =
242 unsafe { ptr::read(get_unchecked_mut(self, mask_and(self.size, self.readptr))) };
243
244 ret = Some(previous_value);
245 self.readptr += 1;
246 }
247
248 let index = mask_and(self.size, self.writeptr);
250
251 unsafe {
252 ptr::write(get_unchecked_mut(self, index), value);
253 }
254
255 self.writeptr += 1;
256
257 ret
258 }
259
260 fn dequeue(&mut self) -> Option<T> {
261 if self.is_empty() {
262 None
263 } else {
264 let index = mask_and(self.size, self.readptr);
266 let res = unsafe { get_unchecked_mut(self, index) };
267 self.readptr += 1;
268
269 unsafe { Some(ptr::read(res)) }
273 }
274 }
275
276 impl_ringbuffer_ext!(
277 get_base_ptr,
278 get_base_mut_ptr,
279 get_unchecked,
280 get_unchecked_mut,
281 readptr,
282 writeptr,
283 mask_and
284 );
285
286 #[inline]
287 fn fill_with<F: FnMut() -> T>(&mut self, mut f: F) {
288 self.clear();
289
290 self.readptr = 0;
291 self.writeptr = self.capacity;
292
293 for i in 0..self.capacity {
294 unsafe { ptr::write(get_unchecked_mut(self, i), f()) };
295 }
296 }
297}
298
299impl<T> AllocRingBuffer<T> {
300 #[inline]
303 #[must_use]
304 pub fn with_capacity_power_of_2(cap_power_of_two: usize) -> Self {
305 Self::new(1 << cap_power_of_two)
306 }
307
308 #[inline]
309 #[must_use]
311 #[deprecated = "alias of new"]
312 pub fn with_capacity(cap: usize) -> Self {
313 Self::new(cap)
314 }
315
316 #[inline]
321 #[must_use]
322 pub fn new(capacity: usize) -> Self {
323 assert_ne!(capacity, 0, "Capacity must be greater than 0");
324 let size = capacity.next_power_of_two();
325 let layout = alloc::alloc::Layout::array::<T>(size).unwrap();
326 let buf = unsafe { alloc::alloc::alloc(layout).cast() };
327 Self {
328 buf,
329 size,
330 capacity,
331 readptr: 0,
332 writeptr: 0,
333 }
334 }
335}
336
337unsafe fn get_base_ptr<T>(rb: *const AllocRingBuffer<T>) -> *const T {
339 (*rb).buf.cast()
340}
341
342unsafe fn get_base_mut_ptr<T>(rb: *mut AllocRingBuffer<T>) -> *mut T {
344 (*rb).buf
345}
346
347#[inline]
351unsafe fn get_unchecked<'a, T>(rb: *const AllocRingBuffer<T>, index: usize) -> &'a T {
352 let p = (*rb).buf.add(index);
353 &*p
356}
357
358#[inline]
362unsafe fn get_unchecked_mut<T>(rb: *mut AllocRingBuffer<T>, index: usize) -> *mut T {
363 let p = (*rb).buf.add(index);
364
365 p.cast()
368}
369
370impl<T> Index<usize> for AllocRingBuffer<T> {
371 type Output = T;
372
373 fn index(&self, index: usize) -> &Self::Output {
374 self.get(index).expect("index out of bounds")
375 }
376}
377
378impl<T> IndexMut<usize> for AllocRingBuffer<T> {
379 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
380 self.get_mut(index).expect("index out of bounds")
381 }
382}
383
384impl<T> SetLen for AllocRingBuffer<T> {
385 impl_ring_buffer_set_len!(readptr, writeptr);
386}
387
388#[cfg(test)]
389mod tests {
390 use crate::{AllocRingBuffer, RingBuffer};
391
392 #[test]
394 fn test_generic_clone() {
395 fn helper(a: &AllocRingBuffer<i32>) -> AllocRingBuffer<i32> {
396 a.clone()
397 }
398
399 _ = helper(&AllocRingBuffer::new(2));
400 _ = helper(&AllocRingBuffer::new(5));
401 }
402
403 #[test]
404 fn test_not_power_of_two() {
405 let mut rb = AllocRingBuffer::new(10);
406 const NUM_VALS: usize = 1000;
407
408 for _ in 0..100 {
411 for i in 0..NUM_VALS {
412 let _ = rb.enqueue(i);
413 }
414 assert!(rb.is_full());
415
416 for i in 0..10 {
417 assert_eq!(Some(i + NUM_VALS - rb.capacity()), rb.dequeue());
418 }
419
420 assert!(rb.is_empty());
421 }
422 }
423
424 #[test]
425 fn test_with_capacity_power_of_two() {
426 let b = AllocRingBuffer::<i32>::with_capacity_power_of_2(2);
427 assert_eq!(b.capacity, 4);
428 }
429
430 #[test]
431 #[should_panic]
432 fn test_index_zero_length() {
433 let b = AllocRingBuffer::<i32>::new(2);
434 let _ = b[2];
435 }
436
437 #[test]
438 fn test_extend() {
439 let mut buf = AllocRingBuffer::<u8>::new(4);
440 (0..4).for_each(|_| {
441 let _ = buf.enqueue(0);
442 });
443
444 let new_data = [0, 1, 2];
445 buf.extend(new_data);
446
447 let expected = [0, 0, 1, 2];
448
449 for i in 0..4 {
450 let actual = buf[i];
451 let expected = expected[i];
452 assert_eq!(actual, expected);
453 }
454 }
455
456 #[test]
457 fn test_extend_with_overflow() {
458 let mut buf = AllocRingBuffer::<u8>::new(8);
459 (0..8).for_each(|_| {
460 let _ = buf.enqueue(0);
461 });
462
463 let new_data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
464 buf.extend(new_data);
465
466 let expected = [2, 3, 4, 5, 6, 7, 8, 9];
467
468 for i in 0..8 {
469 let actual = buf[i];
470 let expected = expected[i];
471 assert_eq!(actual, expected);
472 }
473 }
474
475 #[test]
476 fn test_conversions() {
477 let data: &[i32] = &[1, 2, 3, 4];
479 let buf = AllocRingBuffer::from(data);
480 assert_eq!(buf.capacity, 4);
481 assert_eq!(buf.to_vec(), alloc::vec![1, 2, 3, 4]);
482
483 let buf = AllocRingBuffer::from(&[1, 2, 3, 4]);
485 assert_eq!(buf.capacity, 4);
486 assert_eq!(buf.to_vec(), alloc::vec![1, 2, 3, 4]);
487
488 let buf = AllocRingBuffer::from([1, 2, 3, 4]);
490 assert_eq!(buf.capacity, 4);
491 assert_eq!(buf.to_vec(), alloc::vec![1, 2, 3, 4]);
492 }
493}