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