use std::{convert::AsRef, iter::FromIterator, sync::Arc, usize};
use crate::{trusted_len::TrustedLen, types::NativeType};
use super::bytes::Bytes;
use super::mutable::MutableBuffer;
#[derive(Clone, PartialEq)]
pub struct Buffer<T: NativeType> {
data: Arc<Bytes<T>>,
offset: usize,
length: usize,
}
impl<T: NativeType> std::fmt::Debug for Buffer<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(&**self, f)
}
}
impl<T: NativeType> Default for Buffer<T> {
#[inline]
fn default() -> Self {
MutableBuffer::new().into()
}
}
impl<T: NativeType> Buffer<T> {
#[inline]
pub fn new() -> Self {
Self::default()
}
#[inline]
pub fn new_zeroed(length: usize) -> Self {
MutableBuffer::from_len_zeroed(length).into()
}
#[cfg(not(feature = "cache_aligned"))]
#[cfg_attr(docsrs, doc(cfg(not(feature = "cache_aligned"))))]
#[inline]
pub fn from_vec(data: Vec<T>) -> Self {
MutableBuffer::from_vec(data).into()
}
pub(crate) fn from_bytes(bytes: Bytes<T>) -> Self {
let length = bytes.len();
Buffer {
data: Arc::new(bytes),
offset: 0,
length,
}
}
#[inline]
pub fn len(&self) -> usize {
self.length
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
pub fn as_slice(&self) -> &[T] {
&self.data[self.offset..self.offset + self.length]
}
#[inline]
pub fn slice(self, offset: usize, length: usize) -> Self {
assert!(
offset + length <= self.len(),
"the offset of the new Buffer cannot exceed the existing length"
);
unsafe { self.slice_unchecked(offset, length) }
}
#[inline]
pub unsafe fn slice_unchecked(mut self, offset: usize, length: usize) -> Self {
self.offset += offset;
self.length = length;
self
}
#[inline]
pub(crate) fn as_ptr(&self) -> std::ptr::NonNull<T> {
self.data.ptr()
}
pub(crate) fn offset(&self) -> usize {
self.offset
}
}
impl<T: NativeType> Buffer<T> {
#[inline]
pub fn from_trusted_len_iter<I: TrustedLen<Item = T>>(iterator: I) -> Self {
MutableBuffer::from_trusted_len_iter(iterator).into()
}
#[inline]
pub fn try_from_trusted_len_iter<E, I: TrustedLen<Item = std::result::Result<T, E>>>(
iterator: I,
) -> std::result::Result<Self, E> {
Ok(MutableBuffer::try_from_trusted_len_iter(iterator)?.into())
}
#[inline]
pub unsafe fn from_trusted_len_iter_unchecked<I: Iterator<Item = T>>(iterator: I) -> Self {
MutableBuffer::from_trusted_len_iter_unchecked(iterator).into()
}
#[inline]
pub unsafe fn try_from_trusted_len_iter_unchecked<
E,
I: Iterator<Item = std::result::Result<T, E>>,
>(
iterator: I,
) -> std::result::Result<Self, E> {
Ok(MutableBuffer::try_from_trusted_len_iter_unchecked(iterator)?.into())
}
}
impl<T: NativeType, U: AsRef<[T]>> From<U> for Buffer<T> {
#[inline]
fn from(p: U) -> Self {
MutableBuffer::from(p).into()
}
}
impl<T: NativeType> std::ops::Deref for Buffer<T> {
type Target = [T];
#[inline]
fn deref(&self) -> &[T] {
self.as_slice()
}
}
impl<T: NativeType> FromIterator<T> for Buffer<T> {
#[inline]
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
MutableBuffer::from_iter(iter).into()
}
}