1use std::ops::Deref;
5
6use vortex_error::{VortexError, vortex_bail};
7
8use crate::{Alignment, Buffer};
9
10#[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 pub const fn alignment() -> Alignment {
17 Alignment::new(A)
18 }
19
20 pub fn align_from<B: Into<Buffer<T>>>(buf: B) -> Self {
22 Self(buf.into().aligned(Self::alignment()))
23 }
24
25 pub fn copy_from<B: AsRef<[T]>>(buf: B) -> Self {
27 Self(Buffer::<T>::copy_from_aligned(buf, Self::alignment()))
28 }
29
30 #[inline(always)]
32 pub fn as_slice(&self) -> &[T] {
33 self.0.as_slice()
34 }
35
36 pub fn inner(&self) -> &Buffer<T> {
38 &self.0
39 }
40
41 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}