Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions src/with_alloc/alloc_ringbuffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,62 @@ impl<T: Clone> From<&mut [T]> for AllocRingBuffer<T, NonPowerOfTwo> {
}
}

impl<T: Clone, const CAP: usize> From<&mut [T; CAP]> for AllocRingBuffer<T, NonPowerOfTwo> {
fn from(value: &mut [T; CAP]) -> Self {
Self::from(value.clone())
}
}

impl<T> From<alloc::vec::Vec<T>> for AllocRingBuffer<T, NonPowerOfTwo> {
fn from(value: alloc::vec::Vec<T>) -> Self {
let mut res = AllocRingBuffer::with_capacity_non_power_of_two(value.len());
res.extend(value.into_iter());
res
}
}

impl<T> From<alloc::collections::VecDeque<T>> for AllocRingBuffer<T, NonPowerOfTwo> {
fn from(value: alloc::collections::VecDeque<T>) -> Self {
let mut res = AllocRingBuffer::with_capacity_non_power_of_two(value.len());
res.extend(value.into_iter());
res
}
}

impl<T> From<alloc::collections::LinkedList<T>> for AllocRingBuffer<T, NonPowerOfTwo> {
fn from(value: alloc::collections::LinkedList<T>) -> Self {
let mut res = AllocRingBuffer::with_capacity_non_power_of_two(value.len());
res.extend(value.into_iter());
res
}
}

impl From<alloc::string::String> for AllocRingBuffer<char, NonPowerOfTwo> {
fn from(value: alloc::string::String) -> Self {
let mut res = AllocRingBuffer::with_capacity_non_power_of_two(value.len());
res.extend(value.chars());
res
}
}

impl From<&str> for AllocRingBuffer<char, NonPowerOfTwo> {
fn from(value: &str) -> Self {
let mut res = AllocRingBuffer::with_capacity_non_power_of_two(value.len());
res.extend(value.chars());
res
}
}

impl<T, const CAP: usize> From<crate::ConstGenericRingBuffer<T, CAP>>
for AllocRingBuffer<T, NonPowerOfTwo>
{
fn from(mut value: crate::ConstGenericRingBuffer<T, CAP>) -> Self {
let mut res = AllocRingBuffer::with_capacity_non_power_of_two(value.len());
res.extend(value.drain());
res
}
}

impl<T, SIZE: RingbufferSize> Drop for AllocRingBuffer<T, SIZE> {
fn drop(&mut self) {
self.drain().for_each(drop);
Expand Down
103 changes: 70 additions & 33 deletions src/with_alloc/vecdeque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,22 @@ impl<T> From<VecDeque<T>> for GrowableAllocRingBuffer<T> {
}
}

impl<T: Clone, const N: usize> From<&[T; N]> for GrowableAllocRingBuffer<T> {
// the cast here is actually not trivial
#[allow(trivial_casts)]
fn from(value: &[T; N]) -> Self {
Self::from(value as &[T])
}
}

impl<T: Clone> From<&[T]> for GrowableAllocRingBuffer<T> {
fn from(value: &[T]) -> Self {
let mut rb = Self::new();
rb.extend(value.iter().cloned());
rb
}
}

impl<T, SIZE: RingbufferSize> From<AllocRingBuffer<T, SIZE>> for GrowableAllocRingBuffer<T> {
fn from(mut v: AllocRingBuffer<T, SIZE>) -> GrowableAllocRingBuffer<T> {
let mut rb = GrowableAllocRingBuffer::new();
Expand All @@ -31,6 +47,60 @@ impl<T, SIZE: RingbufferSize> From<AllocRingBuffer<T, SIZE>> for GrowableAllocRi
}
}

impl<T: Clone> From<&mut [T]> for GrowableAllocRingBuffer<T> {
fn from(value: &mut [T]) -> Self {
Self::from(&*value)
}
}

impl<T: Clone, const CAP: usize> From<&mut [T; CAP]> for GrowableAllocRingBuffer<T> {
fn from(value: &mut [T; CAP]) -> Self {
Self::from(value.clone())
}
}

impl<T> From<alloc::vec::Vec<T>> for GrowableAllocRingBuffer<T> {
fn from(value: alloc::vec::Vec<T>) -> Self {
let mut res = GrowableAllocRingBuffer::new();
res.extend(value.into_iter());
res
}
}

impl<T> From<alloc::collections::LinkedList<T>> for GrowableAllocRingBuffer<T> {
fn from(value: alloc::collections::LinkedList<T>) -> Self {
let mut res = GrowableAllocRingBuffer::new();
res.extend(value.into_iter());
res
}
}

impl From<alloc::string::String> for GrowableAllocRingBuffer<char> {
fn from(value: alloc::string::String) -> Self {
let mut res = GrowableAllocRingBuffer::new();
res.extend(value.chars());
res
}
}

impl From<&str> for GrowableAllocRingBuffer<char> {
fn from(value: &str) -> Self {
let mut res = GrowableAllocRingBuffer::new();
res.extend(value.chars());
res
}
}

impl<T, const CAP: usize> From<crate::ConstGenericRingBuffer<T, CAP>>
for GrowableAllocRingBuffer<T>
{
fn from(mut value: crate::ConstGenericRingBuffer<T, CAP>) -> Self {
let mut res = GrowableAllocRingBuffer::new();
res.extend(value.drain());
res
}
}

impl<T> Deref for GrowableAllocRingBuffer<T> {
type Target = VecDeque<T>;

Expand Down Expand Up @@ -176,36 +246,3 @@ unsafe impl<T> RingBufferExt<T> for GrowableAllocRingBuffer<T> {
unimplemented!()
}
}

#[cfg(test)]
mod tests {
use crate::{
AllocRingBuffer, GrowableAllocRingBuffer, RingBuffer, RingBufferRead, RingBufferWrite,
};

#[test]
fn test_convert() {
let mut a = GrowableAllocRingBuffer::new();
a.push(0);
a.push(1);

let mut b: AllocRingBuffer<_, _> = a.into();
assert_eq!(b.capacity(), 2);
assert_eq!(b.len(), 2);
assert_eq!(b.dequeue(), Some(0));
assert_eq!(b.dequeue(), Some(1));
}

#[test]
fn test_convert_back() {
let mut a = AllocRingBuffer::new(2);
a.push(0);
a.push(1);

let mut b: GrowableAllocRingBuffer<_> = a.into();
assert_eq!(b.len(), 2);
assert!(b.capacity() >= 2);
assert_eq!(b.dequeue(), Some(0));
assert_eq!(b.dequeue(), Some(1));
}
}
92 changes: 92 additions & 0 deletions src/with_const_generics.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::with_alloc::alloc_ringbuffer::RingbufferSize;
use crate::{RingBuffer, RingBufferExt, RingBufferRead, RingBufferWrite};
use core::iter::FromIterator;
use core::mem;
Expand Down Expand Up @@ -39,6 +40,97 @@ pub struct ConstGenericRingBuffer<T, const CAP: usize> {
writeptr: usize,
}

impl<T, const CAP: usize> From<[T; CAP]> for ConstGenericRingBuffer<T, CAP> {
fn from(value: [T; CAP]) -> Self {
Self {
// Safety:
// T has the same layout as MaybeUninit<T>
// [T; N] has the same layout as [MaybeUninit<T>; N]
buf: unsafe { mem::transmute_copy(&value) },
readptr: 0,
writeptr: CAP,
}
}
}

impl<T: Clone, const CAP: usize> From<&[T; CAP]> for ConstGenericRingBuffer<T, CAP> {
fn from(value: &[T; CAP]) -> Self {
Self::from(value.clone())
}
}

impl<T: Clone, const CAP: usize> From<&[T]> for ConstGenericRingBuffer<T, CAP> {
fn from(value: &[T]) -> Self {
value.iter().cloned().collect()
}
}

impl<T: Clone, const CAP: usize> From<&mut [T; CAP]> for ConstGenericRingBuffer<T, CAP> {
fn from(value: &mut [T; CAP]) -> Self {
Self::from(value.clone())
}
}

impl<T: Clone, const CAP: usize> From<&mut [T]> for ConstGenericRingBuffer<T, CAP> {
fn from(value: &mut [T]) -> Self {
value.iter().cloned().collect()
}
}

#[cfg(feature = "alloc")]
impl<T, const CAP: usize> From<alloc::vec::Vec<T>> for ConstGenericRingBuffer<T, CAP> {
fn from(value: alloc::vec::Vec<T>) -> Self {
value.into_iter().collect()
}
}

#[cfg(feature = "alloc")]
impl<T, const CAP: usize> From<alloc::collections::VecDeque<T>> for ConstGenericRingBuffer<T, CAP> {
fn from(value: alloc::collections::VecDeque<T>) -> Self {
value.into_iter().collect()
}
}

#[cfg(feature = "alloc")]
impl<T, const CAP: usize> From<alloc::collections::LinkedList<T>>
for ConstGenericRingBuffer<T, CAP>
{
fn from(value: alloc::collections::LinkedList<T>) -> Self {
value.into_iter().collect()
}
}

#[cfg(feature = "alloc")]
impl<const CAP: usize> From<alloc::string::String> for ConstGenericRingBuffer<char, CAP> {
fn from(value: alloc::string::String) -> Self {
value.chars().collect()
}
}

impl<const CAP: usize> From<&str> for ConstGenericRingBuffer<char, CAP> {
fn from(value: &str) -> Self {
value.chars().collect()
}
}

#[cfg(feature = "alloc")]
impl<T, const CAP: usize> From<crate::GrowableAllocRingBuffer<T>>
for ConstGenericRingBuffer<T, CAP>
{
fn from(mut value: crate::GrowableAllocRingBuffer<T>) -> Self {
value.drain().collect()
}
}

#[cfg(feature = "alloc")]
impl<T, const CAP: usize, SIZE: RingbufferSize> From<crate::AllocRingBuffer<T, SIZE>>
for ConstGenericRingBuffer<T, CAP>
{
fn from(mut value: crate::AllocRingBuffer<T, SIZE>) -> Self {
value.drain().collect()
}
}

impl<T, const CAP: usize> Drop for ConstGenericRingBuffer<T, CAP> {
fn drop(&mut self) {
self.drain().for_each(drop);
Expand Down
3 changes: 3 additions & 0 deletions tests/compiletests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ extern crate compiletest_rs as compiletest;

use std::path::PathBuf;

#[cfg(test)]
mod conversions;

fn run_mode(mode: &'static str) {
let mut config = compiletest::Config::default();

Expand Down
Loading