Skip to content

Commit 7560ec8

Browse files
authored
inout: add From impl for splitting [T; N * M] into [[T; N]; M] (#1170)
1 parent c7e6555 commit 7560ec8

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

inout/src/inout.rs

+24-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, 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,28 @@ 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 in_ptr: *const Array<T, N> = buf.in_ptr.cast();
164+
let out_ptr: *mut Array<T, N> = buf.out_ptr.cast();
165+
166+
Array::from_fn(|i| unsafe {
167+
InOut {
168+
in_ptr: in_ptr.add(i),
169+
out_ptr: out_ptr.add(i),
170+
_pd: PhantomData,
171+
}
172+
})
173+
}
174+
}
175+
154176
impl<N: ArraySize> InOut<'_, '_, Array<u8, N>> {
155177
/// XOR `data` with values behind the input slice and write
156178
/// 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)