1use crate::{SplitInplace, SplitProcess};
2use core::marker::PhantomData;
3
4impl<X: Copy, Y: Copy, C0, C1, S0, S1> SplitProcess<X, Y, (S0, S1)> for (C0, C1)
10where
11 C0: SplitProcess<X, Y, S0>,
12 C1: SplitInplace<Y, S1>,
13{
14 fn process(&self, state: &mut (S0, S1), x: X) -> Y {
15 self.1
16 .process(&mut state.1, self.0.process(&mut state.0, x))
17 }
18
19 fn block(&self, state: &mut (S0, S1), x: &[X], y: &mut [Y]) {
20 self.0.block(&mut state.0, x, y);
21 self.1.inplace(&mut state.1, y);
22 }
23}
24
25impl<X: Copy, C0, C1, S0, S1> SplitInplace<X, (S0, S1)> for (C0, C1)
26where
27 C0: SplitInplace<X, S0>,
28 C1: SplitInplace<X, S1>,
29{
30 fn inplace(&self, state: &mut (S0, S1), xy: &mut [X]) {
31 self.0.inplace(&mut state.0, xy);
32 self.1.inplace(&mut state.1, xy);
33 }
34}
35
36impl<X: Copy, C, S> SplitProcess<X, X, [S]> for [C]
43where
44 C: SplitInplace<X, S>,
45{
46 fn process(&self, state: &mut [S], x: X) -> X {
47 debug_assert_eq!(self.len(), state.len());
48 self.iter()
49 .zip(state.iter_mut())
50 .fold(x, |x, (c, s)| c.process(s, x))
51 }
52
53 fn block(&self, state: &mut [S], x: &[X], y: &mut [X]) {
54 debug_assert_eq!(self.len(), state.len());
55 if let Some(((c0, c), (s0, s))) = self.split_first().zip(state.split_first_mut()) {
56 c0.block(s0, x, y);
57 for (c, s) in c.iter().zip(s) {
58 c.inplace(s, y);
59 }
60 } else {
61 y.copy_from_slice(x);
62 }
63 }
64}
65
66impl<X: Copy, C, S> SplitInplace<X, [S]> for [C]
67where
68 C: SplitInplace<X, S>,
69{
70 fn inplace(&self, state: &mut [S], xy: &mut [X]) {
71 debug_assert_eq!(self.len(), state.len());
72 for (c, s) in self.iter().zip(state.iter_mut()) {
73 c.inplace(s, xy);
74 }
75 }
76}
77
78impl<X: Copy, Y: Copy, C, S, const N: usize> SplitProcess<X, Y, [S; N]> for [C; N]
82where
83 C: SplitProcess<X, Y, S> + SplitInplace<Y, S>,
84{
85 fn process(&self, state: &mut [S; N], x: X) -> Y {
86 const { assert!(N > 0) }
87 let Some(((c0, c), (s0, s))) = self.split_first().zip(state.split_first_mut()) else {
88 unreachable!()
89 };
90 c.iter()
91 .zip(s.iter_mut())
92 .fold(c0.process(s0, x), |x, (c, s)| c.process(s, x))
93 }
94
95 fn block(&self, state: &mut [S; N], x: &[X], y: &mut [Y]) {
96 const { assert!(N > 0) }
97 let Some(((c0, c), (s0, s))) = self.split_first().zip(state.split_first_mut()) else {
98 unreachable!()
99 };
100 c0.block(s0, x, y);
101 for (c, s) in c.iter().zip(s.iter_mut()) {
102 c.inplace(s, y)
103 }
104 }
105}
106
107impl<X: Copy, C, S, const N: usize> SplitInplace<X, [S; N]> for [C; N]
108where
109 C: SplitInplace<X, S>,
110{
111 fn inplace(&self, state: &mut [S; N], xy: &mut [X]) {
112 self.as_ref().inplace(state.as_mut(), xy)
113 }
114}
115
116#[derive(Clone, Copy, Debug, Default)]
132#[repr(transparent)]
133pub struct Minor<C: ?Sized, U> {
134 _intermediate: PhantomData<U>,
136 pub inner: C,
138}
139
140impl<C, U> Minor<C, U> {
141 pub const fn new(inner: C) -> Self {
143 Self {
144 inner,
145 _intermediate: PhantomData,
146 }
147 }
148}
149
150impl<X: Copy, U: Copy, Y, C0, C1, S0, S1> SplitProcess<X, Y, (S0, S1)> for Minor<(C0, C1), U>
151where
152 C0: SplitProcess<X, U, S0>,
153 C1: SplitProcess<U, Y, S1>,
154{
155 fn process(&self, state: &mut (S0, S1), x: X) -> Y {
156 self.inner
157 .1
158 .process(&mut state.1, self.inner.0.process(&mut state.0, x))
159 }
160}
161
162impl<X: Copy, C, S> SplitProcess<X, X, [S]> for Minor<[C], X>
164where
165 C: SplitProcess<X, X, S>,
166{
167 fn process(&self, state: &mut [S], x: X) -> X {
168 debug_assert_eq!(self.inner.len(), state.len());
169 self.inner
170 .iter()
171 .zip(state.iter_mut())
172 .fold(x, |x, (c, s)| c.process(s, x))
173 }
174}
175
176impl<X: Copy, Y: Copy, C, S, const N: usize> SplitProcess<X, Y, [S; N]> for Minor<[C; N], Y>
178where
179 C: SplitProcess<X, Y, S> + SplitProcess<Y, Y, S>,
180{
181 fn process(&self, state: &mut [S; N], x: X) -> Y {
182 const { assert!(N > 0) }
183 let Some(((c0, c), (s0, s))) = self.inner.split_first().zip(state.split_first_mut()) else {
184 unreachable!()
185 };
186 c.iter()
187 .zip(s.iter_mut())
188 .fold(c0.process(s0, x), |x, (c, s)| c.process(s, x))
189 }
190}
191
192impl<X: Copy, U, C, S> SplitInplace<X, S> for Minor<C, U> where Self: SplitProcess<X, X, S> {}
193
194#[derive(Clone, Copy, Debug, Default)]
198pub struct Parallel<P>(pub P);
199
200impl<X0: Copy, X1: Copy, Y0, Y1, C0, C1, S0, S1> SplitProcess<(X0, X1), (Y0, Y1), (S0, S1)>
201 for Parallel<(C0, C1)>
202where
203 C0: SplitProcess<X0, Y0, S0>,
204 C1: SplitProcess<X1, Y1, S1>,
205{
206 fn process(&self, state: &mut (S0, S1), x: (X0, X1)) -> (Y0, Y1) {
207 (
208 self.0.0.process(&mut state.0, x.0),
209 self.0.1.process(&mut state.1, x.1),
210 )
211 }
212}
213
214impl<X: Copy, Y, C0, C1, S0, S1> SplitProcess<[X; 2], [Y; 2], (S0, S1)> for Parallel<(C0, C1)>
215where
216 C0: SplitProcess<X, Y, S0>,
217 C1: SplitProcess<X, Y, S1>,
218{
219 fn process(&self, state: &mut (S0, S1), x: [X; 2]) -> [Y; 2] {
220 [
221 self.0.0.process(&mut state.0, x[0]),
222 self.0.1.process(&mut state.1, x[1]),
223 ]
224 }
225}
226
227impl<X: Copy, Y: Copy + Default, C, S, const N: usize> SplitProcess<[X; N], [Y; N], [S; N]>
228 for Parallel<[C; N]>
229where
230 C: SplitProcess<X, Y, S>,
231{
232 fn process(&self, state: &mut [S; N], x: [X; N]) -> [Y; N] {
233 let mut y = [Y::default(); N];
234 for ((c, s), (x, y)) in self
235 .0
236 .iter()
237 .zip(state.iter_mut())
238 .zip(x.into_iter().zip(y.iter_mut()))
239 {
240 *y = c.process(s, x);
241 }
242 y
243 }
244}
245
246impl<X: Copy, C, S> SplitInplace<X, S> for Parallel<C> where Self: SplitProcess<X, X, S> {}
247
248#[derive(Clone, Copy, Debug, Default)]
255pub struct Transpose<C>(pub C);
256
257impl<X: Copy, Y, C0, C1, S0, S1> SplitProcess<[X; 2], [Y; 2], (S0, S1)> for Transpose<(C0, C1)>
258where
259 C0: SplitProcess<X, Y, S0>,
260 C1: SplitProcess<X, Y, S1>,
261{
262 fn process(&self, state: &mut (S0, S1), x: [X; 2]) -> [Y; 2] {
263 [
264 self.0.0.process(&mut state.0, x[0]),
265 self.0.1.process(&mut state.1, x[1]),
266 ]
267 }
268
269 fn block(&self, state: &mut (S0, S1), x: &[[X; 2]], y: &mut [[Y; 2]]) {
270 debug_assert_eq!(x.len(), y.len());
271 let n = x.len();
272 let (x0, x1) = x.as_flattened().split_at(n);
273 let (y0, y1) = y.as_flattened_mut().split_at_mut(n);
274 self.0.0.block(&mut state.0, x0, y0);
275 self.0.1.block(&mut state.1, x1, y1);
276 }
277}
278
279impl<X: Copy, C0, C1, S0, S1> SplitInplace<[X; 2], (S0, S1)> for Transpose<(C0, C1)>
280where
281 C0: SplitInplace<X, S0>,
282 C1: SplitInplace<X, S1>,
283{
284 fn inplace(&self, state: &mut (S0, S1), xy: &mut [[X; 2]]) {
285 let n = xy.len();
286 let (xy0, xy1) = xy.as_flattened_mut().split_at_mut(n);
287 self.0.0.inplace(&mut state.0, xy0);
288 self.0.1.inplace(&mut state.1, xy1);
289 }
290}
291
292impl<X: Copy, Y: Copy + Default, C, S, const N: usize> SplitProcess<[X; N], [Y; N], [S; N]>
293 for Transpose<[C; N]>
294where
295 C: SplitProcess<X, Y, S>,
296{
297 fn process(&self, state: &mut [S; N], x: [X; N]) -> [Y; N] {
298 let mut y = [Y::default(); N];
299 for ((c, s), (x, y)) in self
300 .0
301 .iter()
302 .zip(state.iter_mut())
303 .zip(x.into_iter().zip(y.iter_mut()))
304 {
305 *y = c.process(s, x);
306 }
307 y
308 }
309
310 fn block(&self, state: &mut [S; N], x: &[[X; N]], y: &mut [[Y; N]]) {
311 debug_assert_eq!(x.len(), y.len());
312 let n = x.len();
313 for ((c, s), (x, y)) in self.0.iter().zip(state.iter_mut()).zip(
314 x.as_flattened()
315 .chunks_exact(n)
316 .zip(y.as_flattened_mut().chunks_exact_mut(n)),
317 ) {
318 c.block(s, x, y)
319 }
320 }
321}
322
323impl<X: Copy + Default, C, S, const N: usize> SplitInplace<[X; N], [S; N]> for Transpose<[C; N]>
324where
325 C: SplitInplace<X, S>,
326{
327 fn inplace(&self, state: &mut [S; N], xy: &mut [[X; N]]) {
328 let n = xy.len();
329 for ((c, s), xy) in self
330 .0
331 .iter()
332 .zip(state.iter_mut())
333 .zip(xy.as_flattened_mut().chunks_exact_mut(n))
334 {
335 c.inplace(s, xy)
336 }
337 }
338}
339
340#[derive(Clone, Copy, Debug, Default)]
344pub struct Channels<C>(pub C);
345
346impl<X: Copy, Y: Copy + Default, C, S, const N: usize> SplitProcess<[X; N], [Y; N], [S; N]>
351 for Channels<C>
352where
353 C: SplitProcess<X, Y, S>,
354{
355 fn process(&self, state: &mut [S; N], x: [X; N]) -> [Y; N] {
356 let mut y = [Y::default(); N];
357 for ((x, y), state) in x.into_iter().zip(y.iter_mut()).zip(state.iter_mut()) {
358 *y = self.0.process(state, x);
359 }
360 y
361 }
362
363 fn block(&self, state: &mut [S; N], x: &[[X; N]], y: &mut [[Y; N]]) {
364 debug_assert_eq!(x.len(), y.len());
365 let n = x.len();
366 for ((x, y), state) in x
367 .as_flattened()
368 .chunks_exact(n)
369 .zip(y.as_flattened_mut().chunks_exact_mut(n))
370 .zip(state.iter_mut())
371 {
372 self.0.block(state, x, y)
373 }
374 }
375}
376
377impl<X: Copy + Default, C, S, const N: usize> SplitInplace<[X; N], [S; N]> for Channels<C>
378where
379 C: SplitInplace<X, S>,
380{
381 fn inplace(&self, state: &mut [S; N], xy: &mut [[X; N]]) {
382 let n = xy.len();
383 for (xy, state) in xy
384 .as_flattened_mut()
385 .chunks_exact_mut(n)
386 .zip(state.iter_mut())
387 {
388 self.0.inplace(state, xy)
389 }
390 }
391}
392
393#[derive(Debug, Clone, Copy, Default)]
400pub struct Major<P: ?Sized, U> {
401 _buf: PhantomData<U>,
403 pub inner: P,
405}
406impl<P, U> Major<P, U> {
407 pub const fn new(inner: P) -> Self {
409 Self {
410 inner,
411 _buf: PhantomData,
412 }
413 }
414}
415
416impl<X: Copy, U: Copy + Default, Y, C0, C1, S0, S1, const N: usize> SplitProcess<X, Y, (S0, S1)>
417 for Major<(C0, C1), [U; N]>
418where
419 C0: SplitProcess<X, U, S0>,
420 C1: SplitProcess<U, Y, S1>,
421{
422 fn process(&self, state: &mut (S0, S1), x: X) -> Y {
423 self.inner
424 .1
425 .process(&mut state.1, self.inner.0.process(&mut state.0, x))
426 }
427
428 fn block(&self, state: &mut (S0, S1), x: &[X], y: &mut [Y]) {
429 let mut u = [U::default(); N];
430 let (x, xr) = x.as_chunks::<N>();
431 let (y, yr) = y.as_chunks_mut::<N>();
432 for (x, y) in x.iter().zip(y) {
433 self.inner.0.block(&mut state.0, x, &mut u);
434 self.inner.1.block(&mut state.1, &u, y);
435 }
436 debug_assert_eq!(xr.len(), yr.len());
437 let ur = &mut u[..xr.len()];
438 self.inner.0.block(&mut state.0, xr, ur);
439 self.inner.1.block(&mut state.1, ur, yr);
440 }
441}
442
443impl<X: Copy, U: Copy + Default, C0, C1, S0, S1, const N: usize> SplitInplace<X, (S0, S1)>
444 for Major<(C0, C1), [U; N]>
445where
446 C0: SplitProcess<X, U, S0>,
447 C1: SplitProcess<U, X, S1>,
448{
449 fn inplace(&self, state: &mut (S0, S1), xy: &mut [X]) {
450 let mut u = [U::default(); N];
451 let (xy, xyr) = xy.as_chunks_mut::<N>();
452 for xy in xy {
453 self.inner.0.block(&mut state.0, xy, &mut u);
454 self.inner.1.block(&mut state.1, &u, xy);
455 }
456 let ur = &mut u[..xyr.len()];
457 self.inner.0.block(&mut state.0, xyr, ur);
458 self.inner.1.block(&mut state.1, ur, xyr);
459 }
460}