1//! Helper traits for tupling/untupling
2
3use crate::stats::Distribution;
4
5/// Any tuple: `(A, B, ..)`
6pub trait Tuple: Sized {
7 /// A tuple of distributions associated with this tuple
8 type Distributions: TupledDistributions<Item = Self>;
9
10 /// A tuple of vectors associated with this tuple
11 type Builder: TupledDistributionsBuilder<Item = Self>;
12}
13
14/// A tuple of distributions: `(Distribution<A>, Distribution<B>, ..)`
15pub trait TupledDistributions: Sized {
16 /// A tuple that can be pushed/inserted into the tupled distributions
17 type Item: Tuple<Distributions = Self>;
18}
19
20/// A tuple of vecs used to build distributions.
21pub trait TupledDistributionsBuilder: Sized {
22 /// A tuple that can be pushed/inserted into the tupled distributions
23 type Item: Tuple<Builder = Self>;
24
25 /// Creates a new tuple of vecs
26 fn new(size: usize) -> Self;
27
28 /// Push one element into each of the vecs
29 fn push(&mut self, tuple: Self::Item);
30
31 /// Append one tuple of vecs to this one, leaving the vecs in the other tuple empty
32 fn extend(&mut self, other: &mut Self);
33
34 /// Convert the tuple of vectors into a tuple of distributions
35 fn complete(self) -> <Self::Item as Tuple>::Distributions;
36}
37
38impl<A> Tuple for (A,)
39where
40 A: Copy,
41{
42 type Distributions = (Distribution<A>,);
43 type Builder = (Vec<A>,);
44}
45
46impl<A> TupledDistributions for (Distribution<A>,)
47where
48 A: Copy,
49{
50 type Item = (A,);
51}
52impl<A> TupledDistributionsBuilder for (Vec<A>,)
53where
54 A: Copy,
55{
56 type Item = (A,);
57
58 fn new(size: usize) -> (Vec<A>,) {
59 (Vec::with_capacity(size),)
60 }
61
62 fn push(&mut self, tuple: (A,)) {
63 (self.0).push(tuple.0);
64 }
65
66 fn extend(&mut self, other: &mut (Vec<A>,)) {
67 (self.0).append(&mut other.0);
68 }
69
70 fn complete(self) -> (Distribution<A>,) {
71 (Distribution(self.0.into_boxed_slice()),)
72 }
73}
74
75impl<A, B> Tuple for (A, B)
76where
77 A: Copy,
78 B: Copy,
79{
80 type Distributions = (Distribution<A>, Distribution<B>);
81 type Builder = (Vec<A>, Vec<B>);
82}
83
84impl<A, B> TupledDistributions for (Distribution<A>, Distribution<B>)
85where
86 A: Copy,
87 B: Copy,
88{
89 type Item = (A, B);
90}
91impl<A, B> TupledDistributionsBuilder for (Vec<A>, Vec<B>)
92where
93 A: Copy,
94 B: Copy,
95{
96 type Item = (A, B);
97
98 fn new(size: usize) -> (Vec<A>, Vec<B>) {
99 (Vec::with_capacity(size), Vec::with_capacity(size))
100 }
101
102 fn push(&mut self, tuple: (A, B)) {
103 (self.0).push(tuple.0);
104 (self.1).push(tuple.1);
105 }
106
107 fn extend(&mut self, other: &mut (Vec<A>, Vec<B>)) {
108 (self.0).append(&mut other.0);
109 (self.1).append(&mut other.1);
110 }
111
112 fn complete(self) -> (Distribution<A>, Distribution<B>) {
113 (
114 Distribution(self.0.into_boxed_slice()),
115 Distribution(self.1.into_boxed_slice()),
116 )
117 }
118}
119
120impl<A, B, C> Tuple for (A, B, C)
121where
122 A: Copy,
123 B: Copy,
124 C: Copy,
125{
126 type Distributions = (Distribution<A>, Distribution<B>, Distribution<C>);
127 type Builder = (Vec<A>, Vec<B>, Vec<C>);
128}
129
130impl<A, B, C> TupledDistributions for (Distribution<A>, Distribution<B>, Distribution<C>)
131where
132 A: Copy,
133 B: Copy,
134 C: Copy,
135{
136 type Item = (A, B, C);
137}
138impl<A, B, C> TupledDistributionsBuilder for (Vec<A>, Vec<B>, Vec<C>)
139where
140 A: Copy,
141 B: Copy,
142 C: Copy,
143{
144 type Item = (A, B, C);
145
146 fn new(size: usize) -> (Vec<A>, Vec<B>, Vec<C>) {
147 (
148 Vec::with_capacity(size),
149 Vec::with_capacity(size),
150 Vec::with_capacity(size),
151 )
152 }
153
154 fn push(&mut self, tuple: (A, B, C)) {
155 (self.0).push(tuple.0);
156 (self.1).push(tuple.1);
157 (self.2).push(tuple.2);
158 }
159
160 fn extend(&mut self, other: &mut (Vec<A>, Vec<B>, Vec<C>)) {
161 (self.0).append(&mut other.0);
162 (self.1).append(&mut other.1);
163 (self.2).append(&mut other.2);
164 }
165
166 fn complete(self) -> (Distribution<A>, Distribution<B>, Distribution<C>) {
167 (
168 Distribution(self.0.into_boxed_slice()),
169 Distribution(self.1.into_boxed_slice()),
170 Distribution(self.2.into_boxed_slice()),
171 )
172 }
173}
174
175impl<A, B, C, D> Tuple for (A, B, C, D)
176where
177 A: Copy,
178 B: Copy,
179 C: Copy,
180 D: Copy,
181{
182 type Distributions = (
183 Distribution<A>,
184 Distribution<B>,
185 Distribution<C>,
186 Distribution<D>,
187 );
188 type Builder = (Vec<A>, Vec<B>, Vec<C>, Vec<D>);
189}
190
191impl<A, B, C, D> TupledDistributions
192 for (
193 Distribution<A>,
194 Distribution<B>,
195 Distribution<C>,
196 Distribution<D>,
197 )
198where
199 A: Copy,
200 B: Copy,
201 C: Copy,
202 D: Copy,
203{
204 type Item = (A, B, C, D);
205}
206impl<A, B, C, D> TupledDistributionsBuilder for (Vec<A>, Vec<B>, Vec<C>, Vec<D>)
207where
208 A: Copy,
209 B: Copy,
210 C: Copy,
211 D: Copy,
212{
213 type Item = (A, B, C, D);
214
215 fn new(size: usize) -> (Vec<A>, Vec<B>, Vec<C>, Vec<D>) {
216 (
217 Vec::with_capacity(size),
218 Vec::with_capacity(size),
219 Vec::with_capacity(size),
220 Vec::with_capacity(size),
221 )
222 }
223
224 fn push(&mut self, tuple: (A, B, C, D)) {
225 (self.0).push(tuple.0);
226 (self.1).push(tuple.1);
227 (self.2).push(tuple.2);
228 (self.3).push(tuple.3);
229 }
230
231 fn extend(&mut self, other: &mut (Vec<A>, Vec<B>, Vec<C>, Vec<D>)) {
232 (self.0).append(&mut other.0);
233 (self.1).append(&mut other.1);
234 (self.2).append(&mut other.2);
235 (self.3).append(&mut other.3);
236 }
237
238 fn complete(
239 self,
240 ) -> (
241 Distribution<A>,
242 Distribution<B>,
243 Distribution<C>,
244 Distribution<D>,
245 ) {
246 (
247 Distribution(self.0.into_boxed_slice()),
248 Distribution(self.1.into_boxed_slice()),
249 Distribution(self.2.into_boxed_slice()),
250 Distribution(self.3.into_boxed_slice()),
251 )
252 }
253}
254