Skip to main content

vortex_buffer/
const_.rs

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