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: ?Sized, C: SplitProcess<X, Y, S> + ?Sized> Process<X, Y> for Split<&C, &mut S> {
19 fn process(&mut self, x: X) -> Y {
20 self.config.process(self.state, x)
21 }
22
23 fn block(&mut self, x: &[X], y: &mut [Y]) {
24 self.config.block(self.state, x, y)
25 }
26}
27
28impl<X: Copy, S: ?Sized, C: SplitInplace<X, S> + ?Sized> Inplace<X> for Split<&C, &mut S> {
29 fn inplace(&mut self, xy: &mut [X]) {
30 self.config.inplace(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 pub fn as_mut(&mut self) -> Split<&C, &mut S> {
51 Split {
52 config: &self.config,
53 state: &mut self.state,
54 }
55 }
56}
57
58#[derive(Debug, Copy, Clone, Default)]
63#[repr(transparent)]
64pub struct Unsplit<P>(pub P);
65
66impl<C> Split<Unsplit<C>, ()> {
67 pub fn stateless(config: C) -> Self {
69 Self::new(Unsplit(config), ())
70 }
71}
72
73impl<S> Split<(), Unsplit<S>> {
74 pub fn stateful(state: S) -> Self {
76 Self::new((), Unsplit(state))
77 }
78}
79
80impl<C0, C1, S0, S1> core::ops::Mul<Split<C1, S1>> for Split<C0, S0> {
82 type Output = Split<(C0, C1), (S0, S1)>;
83
84 fn mul(self, rhs: Split<C1, S1>) -> Self::Output {
85 Split::from((self, rhs))
86 }
87}
88
89impl<C0, C1, S0, S1> core::ops::Add<Split<C1, S1>> for Split<C0, S0> {
91 type Output = Split<Parallel<(C0, C1)>, (S0, S1)>;
92
93 fn add(self, rhs: Split<C1, S1>) -> Self::Output {
94 Split::from((self, rhs)).parallel()
95 }
96}
97
98impl<C0, C1, S0, S1> From<(Split<C0, S0>, Split<C1, S1>)> for Split<(C0, C1), (S0, S1)> {
100 fn from(value: (Split<C0, S0>, Split<C1, S1>)) -> Self {
101 Split::new(
102 (value.0.config, value.1.config),
103 (value.0.state, value.1.state),
104 )
105 }
106}
107
108impl<C, S, const N: usize> From<[Split<C, S>; N]> for Split<[C; N], [S; N]> {
110 fn from(splits: [Split<C, S>; N]) -> Self {
111 let mut splits = splits.map(|s| (Some(s.config), Some(s.state)));
113 Self::new(
114 from_fn(|i| splits[i].0.take().unwrap()),
115 from_fn(|i| splits[i].1.take().unwrap()),
116 )
117 }
118}
119
120impl<C, S> Split<C, S> {
121 pub fn minor<U>(self) -> Split<Minor<C, U>, S> {
123 Split::new(Minor::new(self.config), self.state)
124 }
125
126 pub fn major<U>(self) -> Split<Major<C, U>, S> {
128 Split::new(Major::new(self.config), self.state)
129 }
130
131 pub fn parallel(self) -> Split<Parallel<C>, S> {
133 Split::new(Parallel(self.config), self.state)
134 }
135
136 pub fn repeat<const N: usize>(self) -> Split<[C; N], [S; N]>
138 where
139 C: Clone,
140 S: Clone,
141 {
142 Split::new(repeat(self.config), repeat(self.state))
143 }
144
145 pub fn channels<const N: usize>(self) -> Split<Channels<C>, [S; N]>
147 where
148 S: Clone,
149 {
150 Split::new(Channels(self.config), repeat(self.state))
151 }
152
153 pub fn transpose(self) -> Split<Transpose<C>, S> {
155 Split::new(Transpose(self.config), self.state)
156 }
157}
158
159impl<C, S, U> Split<Minor<C, U>, S> {
160 pub fn inter(self) -> Split<C, S> {
162 Split::new(self.config.inner, self.state)
163 }
164}
165
166impl<C, S> Split<Parallel<C>, S> {
167 pub fn inter(self) -> Split<C, S> {
169 Split::new(self.config.0, self.state)
170 }
171}
172
173impl<C, S> Split<Transpose<C>, S> {
174 pub fn inter(self) -> Split<C, S> {
176 Split::new(self.config.0, self.state)
177 }
178}
179
180impl<C, S, B> Split<Major<C, B>, S> {
181 pub fn inter(self) -> Split<C, S> {
183 Split::new(self.config.inner, self.state)
184 }
185}
186
187impl<C0, C1, S0, S1> Split<(C0, C1), (S0, S1)> {
188 pub fn zip(self) -> (Split<C0, S0>, Split<C1, S1>) {
190 (
191 Split::new(self.config.0, self.state.0),
192 Split::new(self.config.1, self.state.1),
193 )
194 }
195}
196
197impl<C, S, const N: usize> Split<[C; N], [S; N]> {
198 pub fn zip(self) -> [Split<C, S>; N] {
200 let mut it = self.config.into_iter().zip(self.state);
201 from_fn(|_| {
202 let (c, s) = it.next().unwrap();
203 Split::new(c, s)
204 })
205 }
206}
207
208impl<'a, X: Copy, Y, P> SplitProcess<X, Y> for Unsplit<&'a P>
210where
211 &'a P: Process<X, Y>,
212{
213 fn process(&self, _state: &mut (), x: X) -> Y {
214 (&*self.0).process(x)
215 }
216
217 fn block(&self, _state: &mut (), x: &[X], y: &mut [Y]) {
218 (&*self.0).block(x, y)
219 }
220}
221
222impl<'a, X: Copy, P> SplitInplace<X> for Unsplit<&'a P>
223where
224 &'a P: Inplace<X>,
225{
226 fn inplace(&self, _state: &mut (), xy: &mut [X]) {
227 (&*self.0).inplace(xy)
228 }
229}
230
231impl<X: Copy, Y, P: Process<X, Y>> SplitProcess<X, Y, Unsplit<P>> for () {
233 fn process(&self, state: &mut Unsplit<P>, x: X) -> Y {
234 state.0.process(x)
235 }
236
237 fn block(&self, state: &mut Unsplit<P>, x: &[X], y: &mut [Y]) {
238 state.0.block(x, y)
239 }
240}
241
242impl<X: Copy, P: Inplace<X>> SplitInplace<X, Unsplit<P>> for () {
243 fn inplace(&self, state: &mut Unsplit<P>, xy: &mut [X]) {
244 state.0.inplace(xy)
245 }
246}