vortex_buffer/
const.rs

1use std::ops::Deref;
2
3use vortex_error::{VortexError, vortex_bail};
4
5use crate::{Alignment, Buffer};
6
7/// A buffer of items of `T` with a compile-time alignment.
8#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Hash)]
9pub struct ConstBuffer<T, const A: usize>(Buffer<T>);
10
11impl<T, const A: usize> ConstBuffer<T, A> {
12    /// Returns the alignment of the buffer.
13    pub const fn alignment() -> Alignment {
14        Alignment::new(A)
15    }
16
17    /// Align the given buffer (possibly with a copy) and return a new `ConstBuffer`.
18    pub fn align_from<B: Into<Buffer<T>>>(buf: B) -> Self {
19        Self(buf.into().aligned(Self::alignment()))
20    }
21
22    /// Create a new [`ConstBuffer`] with a copy from the provided slice.
23    pub fn copy_from<B: AsRef<[T]>>(buf: B) -> Self {
24        Self(Buffer::<T>::copy_from_aligned(buf, Self::alignment()))
25    }
26
27    /// Returns a slice over the buffer of elements of type T.
28    #[inline(always)]
29    pub fn as_slice(&self) -> &[T] {
30        self.0.as_slice()
31    }
32
33    /// Unwrap the inner buffer.
34    pub fn inner(&self) -> &Buffer<T> {
35        &self.0
36    }
37
38    /// Unwrap the inner buffer.
39    pub fn into_inner(self) -> Buffer<T> {
40        self.0
41    }
42}
43
44impl<T, const A: usize> TryFrom<Buffer<T>> for ConstBuffer<T, A> {
45    type Error = VortexError;
46
47    fn try_from(value: Buffer<T>) -> Result<Self, Self::Error> {
48        if !value.alignment().is_aligned_to(Alignment::new(A)) {
49            vortex_bail!(
50                "Cannot convert buffer with alignment {} to buffer with alignment {}",
51                value.alignment(),
52                A
53            );
54        }
55        Ok(Self(value))
56    }
57}
58
59impl<T, const A: usize> AsRef<Buffer<T>> for ConstBuffer<T, A> {
60    fn as_ref(&self) -> &Buffer<T> {
61        &self.0
62    }
63}
64
65impl<T, const A: usize> Deref for ConstBuffer<T, A> {
66    type Target = [T];
67
68    fn deref(&self) -> &Self::Target {
69        self.0.as_slice()
70    }
71}