1use core::ops::{Add, AddAssign, Div, Mul, MulAssign, Sub, SubAssign};
2use core::{mem, slice};
3
4use crate::field::Field;
5use crate::AbstractField;
6
7pub trait Packable: 'static + Default + Copy + Send + Sync + PartialEq + Eq {}
11
12pub unsafe trait PackedValue: 'static + Copy + From<Self::Value> + Send + Sync {
17 type Value: Packable;
18
19 const WIDTH: usize;
20
21 fn from_slice(slice: &[Self::Value]) -> &Self;
22 fn from_slice_mut(slice: &mut [Self::Value]) -> &mut Self;
23
24 fn from_fn<F>(f: F) -> Self
26 where
27 F: FnMut(usize) -> Self::Value;
28
29 fn as_slice(&self) -> &[Self::Value];
30 fn as_slice_mut(&mut self) -> &mut [Self::Value];
31
32 fn pack_slice(buf: &[Self::Value]) -> &[Self] {
33 assert!(mem::align_of::<Self>() <= mem::align_of::<Self::Value>());
37 assert!(
38 buf.len() % Self::WIDTH == 0,
39 "Slice length (got {}) must be a multiple of packed field width ({}).",
40 buf.len(),
41 Self::WIDTH
42 );
43 let buf_ptr = buf.as_ptr().cast::<Self>();
44 let n = buf.len() / Self::WIDTH;
45 unsafe { slice::from_raw_parts(buf_ptr, n) }
46 }
47
48 fn pack_slice_with_suffix(buf: &[Self::Value]) -> (&[Self], &[Self::Value]) {
49 let (packed, suffix) = buf.split_at(buf.len() - buf.len() % Self::WIDTH);
50 (Self::pack_slice(packed), suffix)
51 }
52
53 fn pack_slice_mut(buf: &mut [Self::Value]) -> &mut [Self] {
54 assert!(mem::align_of::<Self>() <= mem::align_of::<Self::Value>());
55 assert!(
56 buf.len() % Self::WIDTH == 0,
57 "Slice length (got {}) must be a multiple of packed field width ({}).",
58 buf.len(),
59 Self::WIDTH
60 );
61 let buf_ptr = buf.as_mut_ptr().cast::<Self>();
62 let n = buf.len() / Self::WIDTH;
63 unsafe { slice::from_raw_parts_mut(buf_ptr, n) }
64 }
65
66 fn pack_slice_with_suffix_mut(buf: &mut [Self::Value]) -> (&mut [Self], &mut [Self::Value]) {
67 let (packed, suffix) = buf.split_at_mut(buf.len() - buf.len() % Self::WIDTH);
68 (Self::pack_slice_mut(packed), suffix)
69 }
70
71 fn unpack_slice(buf: &[Self]) -> &[Self::Value] {
72 assert!(mem::align_of::<Self>() >= mem::align_of::<Self::Value>());
73 let buf_ptr = buf.as_ptr().cast::<Self::Value>();
74 let n = buf.len() * Self::WIDTH;
75 unsafe { slice::from_raw_parts(buf_ptr, n) }
76 }
77}
78
79pub unsafe trait PackedField: AbstractField<F = Self::Scalar>
82 + PackedValue<Value = Self::Scalar>
83 + From<Self::Scalar>
84 + Add<Self::Scalar, Output = Self>
85 + AddAssign<Self::Scalar>
86 + Sub<Self::Scalar, Output = Self>
87 + SubAssign<Self::Scalar>
88 + Mul<Self::Scalar, Output = Self>
89 + MulAssign<Self::Scalar>
90 + Div<Self::Scalar, Output = Self>
92{
93 type Scalar: Field + Add<Self, Output = Self> + Mul<Self, Output = Self> + Sub<Self, Output = Self>;
94
95
96
97 fn interleave(&self, other: Self, block_len: usize) -> (Self, Self);
132}
133
134unsafe impl<T: Packable> PackedValue for T {
135 type Value = Self;
136
137 const WIDTH: usize = 1;
138
139 fn from_slice(slice: &[Self::Value]) -> &Self {
140 &slice[0]
141 }
142
143 fn from_slice_mut(slice: &mut [Self::Value]) -> &mut Self {
144 &mut slice[0]
145 }
146
147 fn from_fn<Fn>(mut f: Fn) -> Self
148 where
149 Fn: FnMut(usize) -> Self::Value,
150 {
151 f(0)
152 }
153
154 fn as_slice(&self) -> &[Self::Value] {
155 slice::from_ref(self)
156 }
157
158 fn as_slice_mut(&mut self) -> &mut [Self::Value] {
159 slice::from_mut(self)
160 }
161}
162
163unsafe impl<F: Field> PackedField for F {
164 type Scalar = Self;
165
166 fn interleave(&self, other: Self, block_len: usize) -> (Self, Self) {
167 match block_len {
168 1 => (*self, other),
169 _ => panic!("unsupported block length"),
170 }
171 }
172}
173
174impl Packable for u8 {}
175
176impl Packable for u16 {}
177
178impl Packable for u32 {}
179
180impl Packable for u64 {}
181
182impl Packable for u128 {}