Skip to content

Commit c5547a9

Browse files
committed
inout: split a buffer in equal chunks
1 parent 0966d23 commit c5547a9

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

inout/src/inout.rs

+31-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::InOutBuf;
2-
use core::{marker::PhantomData, ptr};
3-
use hybrid_array::{Array, ArraySize};
2+
use core::{marker::PhantomData, mem::MaybeUninit, ops::Mul, ptr};
3+
use hybrid_array::{Array, ArraySize, typenum::Prod};
44

55
/// Custom pointer type which contains one immutable (input) and one mutable
66
/// (output) pointer, which are either equal or non-overlapping.
@@ -151,6 +151,35 @@ impl<'inp, 'out, T, N: ArraySize> InOut<'inp, 'out, Array<T, N>> {
151151
}
152152
}
153153

154+
impl<'inp, 'out, T, N, M> From<InOut<'inp, 'out, Array<T, Prod<N, M>>>>
155+
for Array<InOut<'inp, 'out, Array<T, N>>, M>
156+
where
157+
N: ArraySize,
158+
M: ArraySize,
159+
N: Mul<M>,
160+
Prod<N, M>: ArraySize,
161+
{
162+
fn from(buf: InOut<'inp, 'out, Array<T, Prod<N, M>>>) -> Self {
163+
let split_point = N::USIZE;
164+
let mut out = Array::<MaybeUninit<InOut<Array<T, N>>>, M>::uninit();
165+
let (mut tail_in_ptr, mut tail_out_ptr) = (buf.in_ptr as *const T, buf.out_ptr as *mut T);
166+
167+
for i in 0..M::USIZE {
168+
let el = InOut {
169+
in_ptr: tail_in_ptr as *const Array<T, N>,
170+
out_ptr: tail_out_ptr as *mut Array<T, N>,
171+
_pd: PhantomData,
172+
};
173+
out[i].write(el);
174+
175+
(tail_in_ptr, tail_out_ptr) =
176+
unsafe { (tail_in_ptr.add(split_point), tail_out_ptr.add(split_point)) };
177+
}
178+
179+
unsafe { out.assume_init() }
180+
}
181+
}
182+
154183
impl<N: ArraySize> InOut<'_, '_, Array<u8, N>> {
155184
/// XOR `data` with values behind the input slice and write
156185
/// result to the output slice.

inout/tests/split-inout.rs

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use hybrid_array::{
2+
Array,
3+
sizes::{U2, U4, U8},
4+
};
5+
use inout::{InOut, InOutBuf};
6+
7+
#[test]
8+
fn test_split() {
9+
let mut buf = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
10+
let inout: InOutBuf<'_, '_, u8> = buf.as_mut_slice().into();
11+
12+
let expected: Vec<&[u8]> = vec![
13+
&[1, 2],
14+
&[3, 4],
15+
&[5, 6],
16+
&[7, 8],
17+
&[9, 10],
18+
&[11, 12],
19+
&[13, 14],
20+
&[15, 16],
21+
];
22+
let mut expected = expected.into_iter();
23+
24+
let (blocks, _tail) = inout.into_chunks::<U8>();
25+
for block in blocks.into_iter() {
26+
type SubBlock = Array<u8, U2>;
27+
28+
let subblocks = Array::<InOut<'_, '_, SubBlock>, U4>::from(block);
29+
30+
for subblock in subblocks {
31+
assert_eq!(Some(subblock.get_in().as_slice()), expected.next());
32+
}
33+
}
34+
}

0 commit comments

Comments
 (0)