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 into_inner(self) -> Buffer<T> {
35 self.0
36 }
37}
38
39impl<T, const A: usize> TryFrom<Buffer<T>> for ConstBuffer<T, A> {
40 type Error = VortexError;
41
42 fn try_from(value: Buffer<T>) -> Result<Self, Self::Error> {
43 if !value.alignment().is_aligned_to(Alignment::new(A)) {
44 vortex_bail!(
45 "Cannot convert buffer with alignment {} to buffer with alignment {}",
46 value.alignment(),
47 A
48 );
49 }
50 Ok(Self(value))
51 }
52}
53
54impl<T, const A: usize> AsRef<Buffer<T>> for ConstBuffer<T, A> {
55 fn as_ref(&self) -> &Buffer<T> {
56 &self.0
57 }
58}
59
60impl<T, const A: usize> Deref for ConstBuffer<T, A> {
61 type Target = [T];
62
63 fn deref(&self) -> &Self::Target {
64 self.0.as_slice()
65 }
66}