1use core::array::{from_fn, repeat};
2
3use crate::{
4 Channels, Inplace, Major, Minor, Parallel, Process, SplitInplace, SplitProcess, Transpose,
5};
6
7#[derive(Debug, Copy, Clone, Default)]
11pub struct Split<C, S> {
12 pub config: C,
14 pub state: S,
16}
17
18impl<X: Copy, Y, S, C: SplitProcess<X, Y, S>> Process<X, Y> for Split<C, S> {
19 fn process(&mut self, x: X) -> Y {
20 self.config.process(&mut self.state, x)
21 }
22
23 fn block(&mut self, x: &[X], y: &mut [Y]) {
24 self.config.block(&mut self.state, x, y)
25 }
26}
27
28impl<X: Copy, S, C: SplitInplace<X, S>> Inplace<X> for Split<C, S> {
29 fn inplace(&mut self, xy: &mut [X]) {
30 self.config.inplace(&mut self.state, xy);
31 }
32}
33
34impl<C, S> Split<C, S> {
35 pub const fn new(config: C, state: S) -> Self {
37 Self { config, state }
38 }
39
40 pub const fn assert_process<X: Copy, Y>(&self)
42 where
43 Self: Process<X, Y>,
44 {
45 }
46}
47
48#[derive(Debug, Copy, Clone, Default)]
53#[repr(transparent)]
54pub struct Unsplit<P>(pub P);
55
56impl<C> Split<C, ()> {
57 pub fn stateless(config: C) -> Self {
59 Self::new(config, ())
60 }
61}
62
63impl<S> Split<(), Unsplit<S>> {
64 pub fn stateful(state: S) -> Self {
66 Self::new((), Unsplit(state))
67 }
68}
69
70impl<C0, C1, S0, S1> core::ops::Mul<Split<C1, S1>> for Split<C0, S0> {
72 type Output = Split<(C0, C1), (S0, S1)>;
73
74 fn mul(self, rhs: Split<C1, S1>) -> Self::Output {
75 Split::from((self, rhs))
76 }
77}
78
79impl<C0, C1, S0, S1> core::ops::Add<Split<C1, S1>> for Split<C0, S0> {
81 type Output = Split<Parallel<(C0, C1)>, (S0, S1)>;
82
83 fn add(self, rhs: Split<C1, S1>) -> Self::Output {
84 Split::from((self, rhs)).parallel()
85 }
86}
87
88impl<C0, C1, S0, S1> From<(Split<C0, S0>, Split<C1, S1>)> for Split<(C0, C1), (S0, S1)> {
90 fn from(value: (Split<C0, S0>, Split<C1, S1>)) -> Self {
91 Split::new(
92 (value.0.config, value.1.config),
93 (value.0.state, value.1.state),
94 )
95 }
96}
97
98impl<C, S, const N: usize> From<[Split<C, S>; N]> for Split<[C; N], [S; N]> {
100 fn from(splits: [Split<C, S>; N]) -> Self {
101 let mut splits = splits.map(|s| (Some(s.config), Some(s.state)));
103 Self::new(
104 from_fn(|i| splits[i].0.take().unwrap()),
105 from_fn(|i| splits[i].1.take().unwrap()),
106 )
107 }
108}
109
110impl<C, S> Split<C, S> {
111 pub fn minor<U>(self) -> Split<Minor<C, U>, S> {
113 Split::new(Minor::new(self.config), self.state)
114 }
115
116 pub fn major<U>(self) -> Split<Major<C, U>, S> {
118 Split::new(Major::new(self.config), self.state)
119 }
120
121 pub fn parallel(self) -> Split<Parallel<C>, S> {
123 Split::new(Parallel(self.config), self.state)
124 }
125
126 pub fn repeat<const N: usize>(self) -> Split<[C; N], [S; N]>
128 where
129 C: Clone,
130 S: Clone,
131 {
132 Split::new(repeat(self.config), repeat(self.state))
133 }
134
135 pub fn channels<const N: usize>(self) -> Split<Channels<C>, [S; N]>
137 where
138 S: Clone,
139 {
140 Split::new(Channels(self.config), repeat(self.state))
141 }
142
143 pub fn transpose(self) -> Split<Transpose<C>, S> {
145 Split::new(Transpose(self.config), self.state)
146 }
147}
148
149impl<C, S, U> Split<Minor<C, U>, S> {
150 pub fn inter(self) -> Split<C, S> {
152 Split::new(self.config.inner, self.state)
153 }
154}
155
156impl<C, S> Split<Parallel<C>, S> {
157 pub fn inter(self) -> Split<C, S> {
159 Split::new(self.config.0, self.state)
160 }
161}
162
163impl<C, S> Split<Transpose<C>, S> {
164 pub fn inter(self) -> Split<C, S> {
166 Split::new(self.config.0, self.state)
167 }
168}
169
170impl<C, S, B> Split<Major<C, B>, S> {
171 pub fn inter(self) -> Split<C, S> {
173 Split::new(self.config.inner, self.state)
174 }
175}
176
177impl<C0, C1, S0, S1> Split<(C0, C1), (S0, S1)> {
178 pub fn zip(self) -> (Split<C0, S0>, Split<C1, S1>) {
180 (
181 Split::new(self.config.0, self.state.0),
182 Split::new(self.config.1, self.state.1),
183 )
184 }
185}
186
187impl<C, S, const N: usize> Split<[C; N], [S; N]> {
188 pub fn zip(self) -> [Split<C, S>; N] {
190 let mut it = self.config.into_iter().zip(self.state);
191 from_fn(|_| {
192 let (c, s) = it.next().unwrap();
193 Split::new(c, s)
194 })
195 }
196}
197
198impl<X: Copy, Y, P: Process<X, Y>> SplitProcess<X, Y, Unsplit<P>> for () {
200 fn process(&self, state: &mut Unsplit<P>, x: X) -> Y {
201 state.0.process(x)
202 }
203
204 fn block(&self, state: &mut Unsplit<P>, x: &[X], y: &mut [Y]) {
205 state.0.block(x, y)
206 }
207}
208
209impl<X: Copy, P: Inplace<X>> SplitInplace<X, Unsplit<P>> for () {
210 fn inplace(&self, state: &mut Unsplit<P>, xy: &mut [X]) {
211 state.0.inplace(xy)
212 }
213}