Skip to content

Commit

Permalink
Add support for smallvec (#341)
Browse files Browse the repository at this point in the history
* feat(buf): impl `IoBuf[Mut]` for smallvec

* also impl io vec buf
  • Loading branch information
George-Miao authored Nov 23, 2024
1 parent f7f0403 commit c851126
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 1 deletion.
2 changes: 2 additions & 0 deletions compio-buf/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ rustdoc-args = ["--cfg", "docsrs"]
bumpalo = { version = "3.14.0", optional = true }
arrayvec = { version = "0.7.4", optional = true }
bytes = { workspace = true, optional = true }
smallvec = { version = "1.13.2", optional = true }

[target.'cfg(unix)'.dependencies]
libc = { workspace = true }

[features]
# Dependencies
arrayvec = ["dep:arrayvec"]
smallvec = ["dep:smallvec"]
bumpalo = ["dep:bumpalo"]
bytes = ["dep:bytes"]

Expand Down
50 changes: 50 additions & 0 deletions compio-buf/src/io_buf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,24 @@ unsafe impl<const N: usize> IoBuf for arrayvec::ArrayVec<u8, N> {
}
}

#[cfg(feature = "smallvec")]
unsafe impl<const N: usize> IoBuf for smallvec::SmallVec<[u8; N]>
where
[u8; N]: smallvec::Array<Item = u8>,
{
fn as_buf_ptr(&self) -> *const u8 {
self.as_ptr()
}

fn buf_len(&self) -> usize {
self.len()
}

fn buf_capacity(&self) -> usize {
self.capacity()
}
}

/// A mutable compio compatible buffer.
///
/// The `IoBufMut` trait is implemented by buffer types that can be passed to
Expand Down Expand Up @@ -396,6 +414,16 @@ unsafe impl<const N: usize> IoBufMut for arrayvec::ArrayVec<u8, N> {
}
}

#[cfg(feature = "smallvec")]
unsafe impl<const N: usize> IoBufMut for smallvec::SmallVec<[u8; N]>
where
[u8; N]: smallvec::Array<Item = u8>,
{
fn as_buf_mut_ptr(&mut self) -> *mut u8 {
self.as_mut_ptr()
}
}

/// A helper trait for `set_len` like methods.
pub trait SetBufInit {
/// Set the buffer length. If `len` is less than the current length, nothing
Expand Down Expand Up @@ -469,6 +497,18 @@ impl<const N: usize> SetBufInit for arrayvec::ArrayVec<u8, N> {
}
}

#[cfg(feature = "smallvec")]
impl<const N: usize> SetBufInit for smallvec::SmallVec<[u8; N]>
where
[u8; N]: smallvec::Array<Item = u8>,
{
unsafe fn set_buf_init(&mut self, len: usize) {
if (**self).buf_len() < len {
self.set_len(len);
}
}
}

impl<T: IoBufMut> SetBufInit for [T] {
unsafe fn set_buf_init(&mut self, len: usize) {
default_set_buf_init(self.iter_mut(), len)
Expand Down Expand Up @@ -496,6 +536,16 @@ impl<T: IoBufMut, const N: usize> SetBufInit for arrayvec::ArrayVec<T, N> {
}
}

#[cfg(feature = "smallvec")]
impl<T: IoBufMut, const N: usize> SetBufInit for smallvec::SmallVec<[T; N]>
where
[T; N]: smallvec::Array<Item = T>,
{
unsafe fn set_buf_init(&mut self, len: usize) {
default_set_buf_init(self.iter_mut(), len)
}
}

unsafe fn default_set_buf_init<'a, B: IoBufMut>(
iter: impl IntoIterator<Item = &'a mut B>,
mut len: usize,
Expand Down
29 changes: 28 additions & 1 deletion compio-buf/src/io_vec_buf.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::ops::{Deref, DerefMut};

use crate::{
IndexedIter, IoBuf, IoBufMut, IoSlice, IoSliceMut, OwnedIterator, SetBufInit, t_alloc,
t_alloc, IndexedIter, IoBuf, IoBufMut, IoSlice, IoSliceMut, OwnedIterator, SetBufInit,
};

/// A type that's either owned or borrowed. Like [`Cow`](std::rc::Cow) but
Expand Down Expand Up @@ -149,6 +149,23 @@ impl<T: IoBuf, const N: usize> IoVectoredBuf for arrayvec::ArrayVec<T, N> {
}
}

#[cfg(feature = "smallvec")]
impl<T: IoBuf, const N: usize> IoVectoredBuf for smallvec::SmallVec<[T; N]>
where
[T; N]: smallvec::Array<Item = T>,
{
type Buf = T;
type OwnedIter = IndexedIter<Self>;

fn iter_buf(&self) -> impl Iterator<Item = MaybeOwned<'_, T>> {
self.iter().map(MaybeOwned::Borrowed)
}

fn owned_iter(self) -> Result<Self::OwnedIter, Self> {
IndexedIter::new(self)
}
}

/// A trait for mutable vectored buffers.
pub trait IoVectoredBufMut: IoVectoredBuf<Buf: IoBufMut, OwnedIter: IoBufMut> + SetBufInit {
/// An iterator for the [`IoSliceMut`]s of the buffers.
Expand Down Expand Up @@ -195,3 +212,13 @@ impl<T: IoBufMut, const N: usize> IoVectoredBufMut for arrayvec::ArrayVec<T, N>
self.iter_mut().map(MaybeOwnedMut::Borrowed)
}
}

#[cfg(feature = "smallvec")]
impl<T: IoBufMut, const N: usize> IoVectoredBufMut for smallvec::SmallVec<[T; N]>
where
[T; N]: smallvec::Array<Item = T>,
{
fn iter_buf_mut(&mut self) -> impl Iterator<Item = MaybeOwnedMut<'_, Self::Buf>> {
self.iter_mut().map(MaybeOwnedMut::Borrowed)
}
}
22 changes: 22 additions & 0 deletions compio-buf/src/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,18 @@ impl<T, const N: usize> Indexable for arrayvec::ArrayVec<T, N> {
}
}

#[cfg(feature = "smallvec")]
impl<T, const N: usize> Indexable for smallvec::SmallVec<[T; N]>
where
[T; N]: smallvec::Array<Item = T>,
{
type Output = T;

fn index(&self, n: usize) -> Option<&T> {
self.get(n)
}
}

impl<T> IndexableMut for &mut [T] {
fn index_mut(&mut self, n: usize) -> Option<&mut T> {
self.get_mut(n)
Expand Down Expand Up @@ -195,3 +207,13 @@ impl<T, const N: usize> IndexableMut for arrayvec::ArrayVec<T, N> {
self.get_mut(n)
}
}

#[cfg(feature = "smallvec")]
impl<T, const N: usize> IndexableMut for smallvec::SmallVec<[T; N]>
where
[T; N]: smallvec::Array<Item = T>,
{
fn index_mut(&mut self, n: usize) -> Option<&mut T> {
self.get_mut(n)
}
}

0 comments on commit c851126

Please sign in to comment.