|
1 | 1 | 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}; |
4 | 4 |
|
5 | 5 | /// Custom pointer type which contains one immutable (input) and one mutable |
6 | 6 | /// (output) pointer, which are either equal or non-overlapping. |
@@ -151,6 +151,36 @@ impl<'inp, 'out, T, N: ArraySize> InOut<'inp, 'out, Array<T, N>> { |
151 | 151 | } |
152 | 152 | } |
153 | 153 |
|
| 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 | + T: core::fmt::Debug, |
| 162 | +{ |
| 163 | + fn from(buf: InOut<'inp, 'out, Array<T, Prod<N, M>>>) -> Self { |
| 164 | + let split_point = N::USIZE; |
| 165 | + let mut out = Array::<MaybeUninit<InOut<Array<T, N>>>, M>::uninit(); |
| 166 | + let (mut tail_in_ptr, mut tail_out_ptr) = (buf.in_ptr as *const T, buf.out_ptr as *mut T); |
| 167 | + |
| 168 | + for i in 0..M::USIZE { |
| 169 | + let el = InOut { |
| 170 | + in_ptr: tail_in_ptr as *const Array<T, N>, |
| 171 | + out_ptr: tail_out_ptr as *mut Array<T, N>, |
| 172 | + _pd: PhantomData, |
| 173 | + }; |
| 174 | + out[i].write(el); |
| 175 | + |
| 176 | + (tail_in_ptr, tail_out_ptr) = |
| 177 | + unsafe { (tail_in_ptr.add(split_point), tail_out_ptr.add(split_point)) }; |
| 178 | + } |
| 179 | + |
| 180 | + unsafe { out.assume_init() } |
| 181 | + } |
| 182 | +} |
| 183 | + |
154 | 184 | impl<N: ArraySize> InOut<'_, '_, Array<u8, N>> { |
155 | 185 | /// XOR `data` with values behind the input slice and write |
156 | 186 | /// result to the output slice. |
|
0 commit comments