1use crate::{
2 LaneMajor, SplitInplace, SplitProcess, SplitViewInplace, SplitViewProcess, View, ViewMut,
3};
4use core::marker::PhantomData;
5
6impl<X: Copy, Y: Copy, C0, C1, S0, S1> SplitProcess<X, Y, (S0, S1)> for (C0, C1)
14where
15 C0: SplitProcess<X, Y, S0>,
16 C1: SplitInplace<Y, S1>,
17{
18 fn process(&self, state: &mut (S0, S1), x: X) -> Y {
19 self.1
20 .process(&mut state.1, self.0.process(&mut state.0, x))
21 }
22
23 fn block(&self, state: &mut (S0, S1), x: &[X], y: &mut [Y]) {
24 self.0.block(&mut state.0, x, y);
25 self.1.inplace(&mut state.1, y);
26 }
27}
28
29impl<X: Copy, C0, C1, S0, S1> SplitInplace<X, (S0, S1)> for (C0, C1)
30where
31 C0: SplitInplace<X, S0>,
32 C1: SplitInplace<X, S1>,
33{
34 fn inplace(&self, state: &mut (S0, S1), xy: &mut [X]) {
35 self.0.inplace(&mut state.0, xy);
36 self.1.inplace(&mut state.1, xy);
37 }
38}
39
40impl<X: Copy, C, S> SplitProcess<X, X, [S]> for [C]
44where
45 C: SplitInplace<X, S>,
46{
47 fn process(&self, state: &mut [S], x: X) -> X {
48 debug_assert_eq!(self.len(), state.len());
49 self.iter()
50 .zip(state.iter_mut())
51 .fold(x, |x, (c, s)| c.process(s, x))
52 }
53
54 fn block(&self, state: &mut [S], x: &[X], y: &mut [X]) {
55 debug_assert_eq!(self.len(), state.len());
56 if let Some(((c0, c), (s0, s))) = self.split_first().zip(state.split_first_mut()) {
57 c0.block(s0, x, y);
58 for (c, s) in c.iter().zip(s) {
59 c.inplace(s, y);
60 }
61 } else {
62 y.copy_from_slice(x);
63 }
64 }
65}
66
67impl<X: Copy, C, S> SplitInplace<X, [S]> for [C]
68where
69 C: SplitInplace<X, S>,
70{
71 fn inplace(&self, state: &mut [S], xy: &mut [X]) {
72 debug_assert_eq!(self.len(), state.len());
73 for (c, s) in self.iter().zip(state.iter_mut()) {
74 c.inplace(s, xy);
75 }
76 }
77}
78
79impl<X: Copy, Y: Copy, C, S, const N: usize> SplitProcess<X, Y, [S; N]> for [C; N]
81where
82 C: SplitProcess<X, Y, S> + SplitInplace<Y, S>,
83{
84 fn process(&self, state: &mut [S; N], x: X) -> Y {
85 const { assert!(N > 0) }
86 let Some(((c0, c), (s0, s))) = self.split_first().zip(state.split_first_mut()) else {
87 unreachable!()
88 };
89 c.iter()
90 .zip(s.iter_mut())
91 .fold(c0.process(s0, x), |x, (c, s)| c.process(s, x))
92 }
93
94 fn block(&self, state: &mut [S; N], x: &[X], y: &mut [Y]) {
95 const { assert!(N > 0) }
96 let Some(((c0, c), (s0, s))) = self.split_first().zip(state.split_first_mut()) else {
97 unreachable!()
98 };
99 c0.block(s0, x, y);
100 for (c, s) in c.iter().zip(s.iter_mut()) {
101 c.inplace(s, y)
102 }
103 }
104}
105
106impl<X: Copy, C, S, const N: usize> SplitInplace<X, [S; N]> for [C; N]
107where
108 C: SplitInplace<X, S>,
109{
110 fn inplace(&self, state: &mut [S; N], xy: &mut [X]) {
111 self.as_ref().inplace(state.as_mut(), xy)
112 }
113}
114
115#[derive(Clone, Copy, Debug, Default)]
148#[repr(transparent)]
149pub struct Minor<C: ?Sized, U> {
150 _intermediate: PhantomData<U>,
152 inner: C,
154}
155
156impl<C, U> Minor<C, U> {
157 #[must_use]
159 pub const fn new(inner: C) -> Self {
160 Self {
161 inner,
162 _intermediate: PhantomData,
163 }
164 }
165
166 #[must_use]
168 pub fn into_inner(self) -> C {
169 self.inner
170 }
171
172 #[must_use]
174 pub fn inner(&self) -> &C {
175 &self.inner
176 }
177}
178
179impl<X: Copy, U: Copy, Y, C0, C1, S0, S1> SplitProcess<X, Y, (S0, S1)> for Minor<(C0, C1), U>
180where
181 C0: SplitProcess<X, U, S0>,
182 C1: SplitProcess<U, Y, S1>,
183{
184 fn process(&self, state: &mut (S0, S1), x: X) -> Y {
185 self.inner
186 .1
187 .process(&mut state.1, self.inner.0.process(&mut state.0, x))
188 }
189}
190
191impl<X: Copy, C, S> SplitProcess<X, X, [S]> for Minor<[C], X>
193where
194 C: SplitProcess<X, X, S>,
195{
196 fn process(&self, state: &mut [S], x: X) -> X {
197 debug_assert_eq!(self.inner.len(), state.len());
198 self.inner
199 .iter()
200 .zip(state.iter_mut())
201 .fold(x, |x, (c, s)| c.process(s, x))
202 }
203}
204
205impl<X: Copy, Y: Copy, C, S, const N: usize> SplitProcess<X, Y, [S; N]> for Minor<[C; N], Y>
207where
208 C: SplitProcess<X, Y, S> + SplitProcess<Y, Y, S>,
209{
210 fn process(&self, state: &mut [S; N], x: X) -> Y {
211 const { assert!(N > 0) }
212 let Some(((c0, c), (s0, s))) = self.inner.split_first().zip(state.split_first_mut()) else {
213 unreachable!()
214 };
215 c.iter()
216 .zip(s.iter_mut())
217 .fold(c0.process(s0, x), |x, (c, s)| c.process(s, x))
218 }
219}
220
221impl<X, U, C, S> SplitInplace<X, S> for Minor<C, U>
222where
223 X: Copy,
224 Self: SplitProcess<X, X, S>,
225{
226}
227
228#[derive(Clone, Copy, Debug, Default)]
240pub struct Parallel<P>(P);
241
242impl<P> Parallel<P> {
243 #[must_use]
245 pub const fn new(inner: P) -> Self {
246 Self(inner)
247 }
248
249 #[must_use]
251 pub fn into_inner(self) -> P {
252 self.0
253 }
254}
255
256impl<X0: Copy, X1: Copy, Y0, Y1, C0, C1, S0, S1> SplitProcess<(X0, X1), (Y0, Y1), (S0, S1)>
257 for Parallel<(C0, C1)>
258where
259 C0: SplitProcess<X0, Y0, S0>,
260 C1: SplitProcess<X1, Y1, S1>,
261{
262 fn process(&self, state: &mut (S0, S1), x: (X0, X1)) -> (Y0, Y1) {
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
270impl<X: Copy, Y, C0, C1, S0, S1> SplitProcess<[X; 2], [Y; 2], (S0, S1)> for Parallel<(C0, C1)>
271where
272 C0: SplitProcess<X, Y, S0>,
273 C1: SplitProcess<X, Y, S1>,
274{
275 fn process(&self, state: &mut (S0, S1), x: [X; 2]) -> [Y; 2] {
276 [
277 self.0.0.process(&mut state.0, x[0]),
278 self.0.1.process(&mut state.1, x[1]),
279 ]
280 }
281}
282
283impl<X: Copy, Y, C, S, const N: usize> SplitProcess<[X; N], [Y; N], [S; N]> for Parallel<[C; N]>
284where
285 C: SplitProcess<X, Y, S>,
286{
287 fn process(&self, state: &mut [S; N], x: [X; N]) -> [Y; N] {
288 core::array::from_fn(|i| self.0[i].process(&mut state[i], x[i]))
290 }
291}
292
293impl<X, C, S> SplitInplace<X, S> for Parallel<C>
294where
295 X: Copy,
296 Self: SplitProcess<X, X, S>,
297{
298}
299
300#[derive(Clone, Copy, Debug, Default)]
315pub struct ByLane<C>(C);
316
317impl<C> ByLane<C> {
318 #[must_use]
320 pub const fn new(inner: C) -> Self {
321 Self(inner)
322 }
323
324 #[must_use]
326 pub fn into_inner(self) -> C {
327 self.0
328 }
329}
330
331impl<X: Copy, Y, C0, C1, S0, S1> SplitProcess<[X; 2], [Y; 2], (S0, S1)> for ByLane<(C0, C1)>
332where
333 C0: SplitProcess<X, Y, S0>,
334 C1: SplitProcess<X, Y, S1>,
335{
336 fn process(&self, state: &mut (S0, S1), x: [X; 2]) -> [Y; 2] {
337 [
338 self.0.0.process(&mut state.0, x[0]),
339 self.0.1.process(&mut state.1, x[1]),
340 ]
341 }
342}
343
344impl<'a, 'b, X: Copy, Y, C0, C1, S0, S1>
345 SplitViewProcess<View<'a, X, LaneMajor, 2>, ViewMut<'b, Y, LaneMajor, 2>, (S0, S1)>
346 for ByLane<(C0, C1)>
347where
348 C0: SplitProcess<X, Y, S0>,
349 C1: SplitProcess<X, Y, S1>,
350{
351 fn process_view(
352 &self,
353 state: &mut (S0, S1),
354 x: View<'a, X, LaneMajor, 2>,
355 mut y: ViewMut<'b, Y, LaneMajor, 2>,
356 ) {
357 debug_assert_eq!(x.frames(), y.frames());
358 self.0.0.block(&mut state.0, x.lane(0), y.lane_mut(0));
359 self.0.1.block(&mut state.1, x.lane(1), y.lane_mut(1));
360 }
361}
362
363impl<X: Copy, Y, C, S, const N: usize> SplitProcess<[X; N], [Y; N], [S; N]> for ByLane<[C; N]>
364where
365 C: SplitProcess<X, Y, S>,
366{
367 fn process(&self, state: &mut [S; N], x: [X; N]) -> [Y; N] {
368 core::array::from_fn(|i| self.0[i].process(&mut state[i], x[i]))
370 }
371}
372
373impl<'a, 'b, X: Copy, Y, C, S, const N: usize>
374 SplitViewProcess<View<'a, X, LaneMajor, N>, ViewMut<'b, Y, LaneMajor, N>, [S; N]>
375 for ByLane<[C; N]>
376where
377 C: SplitProcess<X, Y, S>,
378{
379 fn process_view(
380 &self,
381 state: &mut [S; N],
382 x: View<'a, X, LaneMajor, N>,
383 mut y: ViewMut<'b, Y, LaneMajor, N>,
384 ) {
385 debug_assert_eq!(x.frames(), y.frames());
386 for ((c, s), i) in self.0.iter().zip(state.iter_mut()).zip(0..) {
387 c.block(s, x.lane(i), y.lane_mut(i))
388 }
389 }
390}
391
392impl<X, C, S> SplitInplace<X, S> for ByLane<C>
393where
394 X: Copy,
395 Self: SplitProcess<X, X, S>,
396{
397}
398
399impl<'a, X: Copy, C0, C1, S0, S1> SplitViewInplace<ViewMut<'a, X, LaneMajor, 2>, (S0, S1)>
400 for ByLane<(C0, C1)>
401where
402 C0: SplitInplace<X, S0>,
403 C1: SplitInplace<X, S1>,
404{
405 fn inplace_view(&self, state: &mut (S0, S1), mut xy: ViewMut<'a, X, LaneMajor, 2>) {
406 self.0.0.inplace(&mut state.0, xy.lane_mut(0));
407 self.0.1.inplace(&mut state.1, xy.lane_mut(1));
408 }
409}
410
411impl<'a, X: Copy, C, S, const N: usize> SplitViewInplace<ViewMut<'a, X, LaneMajor, N>, [S; N]>
412 for ByLane<[C; N]>
413where
414 C: SplitInplace<X, S>,
415{
416 fn inplace_view(&self, state: &mut [S; N], mut xy: ViewMut<'a, X, LaneMajor, N>) {
417 for ((c, s), i) in self.0.iter().zip(state.iter_mut()).zip(0..) {
418 c.inplace(s, xy.lane_mut(i));
419 }
420 }
421}
422
423#[derive(Clone, Copy, Debug, Default)]
449pub struct Lanes<C>(C);
450
451impl<C> Lanes<C> {
452 #[must_use]
454 pub const fn new(inner: C) -> Self {
455 Self(inner)
456 }
457
458 #[must_use]
460 pub fn into_inner(self) -> C {
461 self.0
462 }
463}
464
465impl<X: Copy, Y, C, S, const N: usize> SplitProcess<[X; N], [Y; N], [S; N]> for Lanes<C>
469where
470 C: SplitProcess<X, Y, S>,
471{
472 fn process(&self, state: &mut [S; N], x: [X; N]) -> [Y; N] {
473 core::array::from_fn(|i| self.0.process(&mut state[i], x[i]))
475 }
476}
477
478impl<'a, 'b, X: Copy, Y, C, S, const N: usize>
479 SplitViewProcess<View<'a, X, LaneMajor, N>, ViewMut<'b, Y, LaneMajor, N>, [S; N]> for Lanes<C>
480where
481 C: SplitProcess<X, Y, S>,
482{
483 fn process_view(
484 &self,
485 state: &mut [S; N],
486 x: View<'a, X, LaneMajor, N>,
487 mut y: ViewMut<'b, Y, LaneMajor, N>,
488 ) {
489 debug_assert_eq!(x.frames(), y.frames());
490 for (state, i) in state.iter_mut().zip(0..) {
491 self.0.block(state, x.lane(i), y.lane_mut(i))
492 }
493 }
494}
495
496impl<X, C, S> SplitInplace<X, S> for Lanes<C>
497where
498 X: Copy,
499 Self: SplitProcess<X, X, S>,
500{
501}
502
503impl<'a, X: Copy, C, S, const N: usize> SplitViewInplace<ViewMut<'a, X, LaneMajor, N>, [S; N]>
504 for Lanes<C>
505where
506 C: SplitInplace<X, S>,
507{
508 fn inplace_view(&self, state: &mut [S; N], mut xy: ViewMut<'a, X, LaneMajor, N>) {
509 for (state, i) in state.iter_mut().zip(0..) {
510 self.0.inplace(state, xy.lane_mut(i));
511 }
512 }
513}
514
515#[derive(Debug, Clone, Copy, Default)]
540pub struct Major<P: ?Sized, U> {
541 _buf: PhantomData<U>,
543 inner: P,
545}
546impl<P, U> Major<P, U> {
547 #[must_use]
549 pub const fn new(inner: P) -> Self {
550 Self {
551 inner,
552 _buf: PhantomData,
553 }
554 }
555
556 #[must_use]
558 pub fn into_inner(self) -> P {
559 self.inner
560 }
561
562 #[must_use]
564 pub fn inner(&self) -> &P {
565 &self.inner
566 }
567}
568
569impl<X: Copy, U: Copy + Default, Y, C0, C1, S0, S1, const N: usize> SplitProcess<X, Y, (S0, S1)>
570 for Major<(C0, C1), [U; N]>
571where
572 C0: SplitProcess<X, U, S0>,
573 C1: SplitProcess<U, Y, S1>,
574{
575 fn process(&self, state: &mut (S0, S1), x: X) -> Y {
576 self.inner
577 .1
578 .process(&mut state.1, self.inner.0.process(&mut state.0, x))
579 }
580
581 fn block(&self, state: &mut (S0, S1), x: &[X], y: &mut [Y]) {
582 debug_assert_eq!(x.len(), y.len());
583 let mut u = [U::default(); N];
584 let (x, xr) = x.as_chunks::<N>();
585 let (y, yr) = y.as_chunks_mut::<N>();
586 for (x, y) in x.iter().zip(y) {
587 self.inner.0.block(&mut state.0, x, &mut u);
588 self.inner.1.block(&mut state.1, &u, y);
589 }
590 let ur = &mut u[..xr.len()];
591 self.inner.0.block(&mut state.0, xr, ur);
592 self.inner.1.block(&mut state.1, ur, yr);
593 }
594}
595
596impl<X: Copy, U: Copy + Default, C0, C1, S0, S1, const N: usize> SplitInplace<X, (S0, S1)>
597 for Major<(C0, C1), [U; N]>
598where
599 C0: SplitProcess<X, U, S0>,
600 C1: SplitProcess<U, X, S1>,
601{
602 fn inplace(&self, state: &mut (S0, S1), xy: &mut [X]) {
603 let mut u = [U::default(); N];
604 let (xy, xyr) = xy.as_chunks_mut::<N>();
605 for xy in xy {
606 self.inner.0.block(&mut state.0, xy, &mut u);
607 self.inner.1.block(&mut state.1, &u, xy);
608 }
609 let ur = &mut u[..xyr.len()];
610 self.inner.0.block(&mut state.0, xyr, ur);
611 self.inner.1.block(&mut state.1, ur, xyr);
612 }
613}