Skip to content

Commit

Permalink
ringbuffer_trait: add extend_from_slice
Browse files Browse the repository at this point in the history
This adds an extend_from_slice function to the RingBuffer trait. The default
implementation calls push() for each element. However, by creating specialized
implementations for the various buffers, one can do various performance
optimizations in a follow-up.
  • Loading branch information
phip1611 committed Oct 24, 2024
1 parent 75fe4f1 commit b2bc618
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 1 deletion.
13 changes: 12 additions & 1 deletion src/ringbuffer_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ pub unsafe trait RingBuffer<T>:
///
/// Cycles around if capacity is reached.
/// Forms a more natural counterpart to [`dequeue`](RingBuffer::dequeue).
/// An alias is provided with [`push`](RingBuffer::push).
fn enqueue(&mut self, value: T) -> Option<T>;

/// dequeues the top item off the ringbuffer, and moves this item out.
Expand Down Expand Up @@ -237,6 +236,18 @@ pub unsafe trait RingBuffer<T>:
RingBufferIterator::new(self)
}

/// Extends the ringbuffer with elements from a slice.
fn extend_from_slice(&mut self, elements: &[T])
where
T: Clone,
{
// Default implementation.
// For performance reasons, specific RingBuffers should use an optimized implementation.
for element in elements {
let _ = self.enqueue(element.clone());
}
}

/// Converts the buffer to a vector. This Copies all elements in the ringbuffer.
#[cfg(feature = "alloc")]
fn to_vec(&self) -> Vec<T>
Expand Down
8 changes: 8 additions & 0 deletions src/with_alloc/alloc_ringbuffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,4 +474,12 @@ mod tests {
assert_eq!(buf.capacity, 4);
assert_eq!(buf.to_vec(), alloc::vec![1, 2, 3, 4]);
}

#[test]
fn test_extend_from_slice() {
let mut buf = AllocRingBuffer::new(3);
let elems = [1, 2, 3];
buf.extend_from_slice(&elems);
assert_eq!(buf.to_vec().as_slice(), elems)
}
}
13 changes: 13 additions & 0 deletions src/with_alloc/vecdeque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,3 +282,16 @@ impl<T> FromIterator<T> for GrowableAllocRingBuffer<T> {
Self(VecDeque::from_iter(iter))
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_extend_from_slice() {
let mut buf = GrowableAllocRingBuffer::new();
let elems = [1, 2, 3];
buf.extend_from_slice(&elems);
assert_eq!(buf.to_vec().as_slice(), elems)
}
}
8 changes: 8 additions & 0 deletions src/with_const_generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -502,5 +502,13 @@ mod tests {
vec![1, 2, 3]
);
}

#[test]
fn test_extend_from_slice() {
let mut buf = ConstGenericRingBuffer::<i32, 3>::new();
let elems = [1, 2, 3];
buf.extend_from_slice(&elems);
assert_eq!(buf.to_vec().as_slice(), elems)
}
}
}

0 comments on commit b2bc618

Please sign in to comment.