0xAA55 发表于 2025-4-14 21:02:14

【Rust】分享一个模块:CopiableBuffer。自己造轮子实现简易的栈上缓冲区。

这玩意儿可以 Debug,Clone,Copy,push(),len(),set_len(),last(),iter(),iter_mut(),into_iter(),clear(),capacity(),is_full(),is_empty(),以及带边界检查的索引和可变索引。如果不想它进行边界检查,你就自己读写它的 buffer 就好了。
拉珠元素拉满。
一个定长数组和一个变量存储了你往里面写入了多少数据。
在需要简短的像 Vec<T> 一样的东西,却也不希望失去 Copy 的时候,可以使用这个。

use std::{io, ops::{Index, IndexMut}, iter::FromIterator, fmt::Debug};

pub trait CopiableItem: Default + Clone + Copy + Debug + Sized {}
impl<T> CopiableItem for T where T: Default + Clone + Copy + Debug + Sized {}

#
pub struct CopiableBuffer<T, const N: usize>
where T: CopiableItem {
    buffer: ,
    buf_used: usize,
}

#
pub struct CopiableBufferIter<'a, T, const N: usize>
where T: CopiableItem {
    refbuf: &'a CopiableBuffer<T, N>,
    iter_index: usize,
}

#
pub struct CopiableBufferIterMut<'a, T, const N: usize>
where T: CopiableItem {
    refbuf: &'a mut CopiableBuffer<T, N>,
    iter_index: usize,
}

#
pub struct CopiableBufferIntoIter<T, const N: usize>
where T: CopiableItem {
    buffer: ,
    buf_used: usize,
    iter_index: usize,
}

impl<T, const N: usize> CopiableBuffer<T, N>
where T: CopiableItem {
    pub fn new() -> Self {
      Self {
            buffer: ,
            buf_used: 0,
      }
    }

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

    pub fn set_len(&mut self, new_len: usize) {
      self.buf_used = new_len;
    }

    #
    pub fn last(&mut self) -> &mut T {
      if self.buf_used == 0 {
            panic!("CopiableBuffer<{}, {N}> is empty.", std::any::type_name::<T>());
      }
      &mut self.buffer
    }

    #
    pub fn push(&mut self, data: T) {
      if self.buf_used >= self.buffer.len() {
            panic!("CopiableBuffer<{}, {N}> is full.", std::any::type_name::<T>());
      } else {
            self.buffer = data;
            self.buf_used += 1;
      }
    }

    pub fn iter(&self) -> impl Iterator<Item = &T> {
      CopiableBufferIter::<T, N> {
            refbuf: &self,
            iter_index: 0,
      }
    }

    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
      CopiableBufferIterMut::<T, N> {
            refbuf: self,
            iter_index: 0,
      }
    }

    pub fn clear(&mut self) {
      self.set_len(0)
    }

    pub fn capacity(&self) -> usize {
      N
    }

    pub fn is_full(&self) -> bool {
      self.len() == self.capacity()
    }
   
    pub fn is_empty(&self) -> bool {
      self.len() == 0
    }
}

impl<T, const N: usize> Index<usize> for CopiableBuffer<T, N>
where T: CopiableItem {
    type Output = T;

    #
    fn index(&self, index: usize) -> &Self::Output {
      if index >= self.buf_used {
            panic!(
                "Index out of bounds: {} >= {}",
                index, self.buf_used
            );
      }
      &self.buffer
    }
}

impl<T, const N: usize> IndexMut<usize> for CopiableBuffer<T, N>
where T: CopiableItem {

    #
    fn index_mut<'a>(&mut self, index: usize) -> &mut T {
      if index >= self.buf_used {
            panic!(
                "Index out of bounds: {} >= {}",
                index, self.buf_used
            );
      }
      &mut self.buffer
    }
}

impl<T, const N: usize> FromIterator<T> for CopiableBuffer<T, N>
where T: CopiableItem {
    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
      let mut iter = iter.into_iter();
      let mut ret = Self::new();
      while let Some(data) = iter.next() {
            ret.push(data);
      }
      ret
    }
}

impl<'a, T, const N: usize> Iterator for CopiableBufferIter<'a, T, N>
where T: CopiableItem {
    type Item = &'a T;

    fn next(&mut self) -> Option<Self::Item> {
      if self.iter_index < self.refbuf.len() {
            let r = &self.refbuf.buffer;
            self.iter_index += 1;
            Some(r)
      } else {
            None
      }
    }

    fn nth(&mut self, n: usize) -> Option<Self::Item> {
      self.iter_index += n;
      self.next()
    }
}

impl<'a, T, const N: usize> Iterator for CopiableBufferIterMut<'a, T, N>
where T: CopiableItem {
    type Item = &'a mut T;

    fn next(&mut self) -> Option<Self::Item> {
      if self.iter_index < self.refbuf.len() {
            unsafe {
                let item_ptr = self.refbuf.buffer.as_mut_ptr().add(self.iter_index);
                self.iter_index += 1;
                Some(&mut *item_ptr)
            }
      } else {
            None
      }
    }

    fn nth(&mut self, n: usize) -> Option<Self::Item> {
      self.iter_index += n;
      self.next()
    }
}

impl<T, const N: usize> Iterator for CopiableBufferIntoIter<T, N>
where T: CopiableItem {
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
      if self.iter_index < self.buf_used {
            let ret = Some(self.buffer);
            self.iter_index += 1;
            ret
      } else {
            None
      }
    }

    fn nth(&mut self, n: usize) -> Option<Self::Item> {
      self.iter_index += n;
      self.next()
    }
}

impl<T, const N: usize> IntoIterator for CopiableBuffer<T, N>
where T: CopiableItem {
    type Item = T;
    type IntoIter = CopiableBufferIntoIter<T, N>;

    fn into_iter(self) -> Self::IntoIter {
      Self::IntoIter {
            buffer: self.buffer,
            buf_used: self.buf_used,
            iter_index: 0,
      }
    }
}

impl<T, const N: usize> Debug for CopiableBuffer<T, N>
where T: CopiableItem {
    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
      fmt.debug_struct(&format!("CopiableBuffer<{}, {N}>", std::any::type_name::<T>()))
            .field("buffer", &&self.buffer[..self.buf_used])
            .field("buf_used", &self.buf_used)
            .finish()
    }
}

impl<T, const N: usize> Debug for CopiableBufferIntoIter<T, N>
where T: CopiableItem {
    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
      fmt.debug_struct(&format!("CopiableBufferIntoIter<{}, {N}>", std::any::type_name::<T>()))
            .field("buffer", &&self.buffer[..self.buf_used])
            .field("buf_used", &self.buf_used)
            .field("iter_index", &self.iter_index)
            .finish()
    }
}
页: [1]
查看完整版本: 【Rust】分享一个模块:CopiableBuffer。自己造轮子实现简易的栈上缓冲区。