1use std::ops::Deref;
2
3use vortex_error::{VortexError, vortex_bail};
4
5use crate::{Alignment, Buffer};
6
7#[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 pub const fn alignment() -> Alignment {
14 Alignment::new(A)
15 }
16
17 pub fn align_from<B: Into<Buffer<T>>>(buf: B) -> Self {
19 Self(buf.into().aligned(Self::alignment()))
20 }
21
22 pub fn copy_from<B: AsRef<[T]>>(buf: B) -> Self {
24 Self(Buffer::<T>::copy_from_aligned(buf, Self::alignment()))
25 }
26
27 #[inline(always)]
29 pub fn as_slice(&self) -> &[T] {
30 self.0.as_slice()
31 }
32
33 pub fn inner(&self) -> &Buffer<T> {
35 &self.0
36 }
37
38 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}