1use std::ops::Deref;
5
6use vortex_error::VortexError;
7use vortex_error::vortex_bail;
8
9use crate::Alignment;
10use crate::Buffer;
11
12#[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 pub const fn alignment() -> Alignment {
19 Alignment::new(A)
20 }
21
22 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 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 #[allow(clippy::inline_always)]
40 #[inline(always)]
41 pub fn as_slice(&self) -> &[T] {
42 self.0.as_slice()
43 }
44
45 pub fn inner(&self) -> &Buffer<T> {
47 &self.0
48 }
49
50 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}