//! Helper traits for tupling/untupling use crate::stats::Distribution; /// Any tuple: `(A, B, ..)` pub trait Tuple: Sized { /// A tuple of distributions associated with this tuple type Distributions: TupledDistributions; /// A tuple of vectors associated with this tuple type Builder: TupledDistributionsBuilder; } /// A tuple of distributions: `(Distribution, Distribution, ..)` pub trait TupledDistributions: Sized { /// A tuple that can be pushed/inserted into the tupled distributions type Item: Tuple; } /// A tuple of vecs used to build distributions. pub trait TupledDistributionsBuilder: Sized { /// A tuple that can be pushed/inserted into the tupled distributions type Item: Tuple; /// Creates a new tuple of vecs fn new(size: usize) -> Self; /// Push one element into each of the vecs fn push(&mut self, tuple: Self::Item); /// Append one tuple of vecs to this one, leaving the vecs in the other tuple empty fn extend(&mut self, other: &mut Self); /// Convert the tuple of vectors into a tuple of distributions fn complete(self) -> ::Distributions; } impl Tuple for (A,) where A: Copy, { type Distributions = (Distribution,); type Builder = (Vec,); } impl TupledDistributions for (Distribution,) where A: Copy, { type Item = (A,); } impl TupledDistributionsBuilder for (Vec,) where A: Copy, { type Item = (A,); fn new(size: usize) -> (Vec,) { (Vec::with_capacity(size),) } fn push(&mut self, tuple: (A,)) { (self.0).push(tuple.0); } fn extend(&mut self, other: &mut (Vec,)) { (self.0).append(&mut other.0); } fn complete(self) -> (Distribution,) { (Distribution(self.0.into_boxed_slice()),) } } impl Tuple for (A, B) where A: Copy, B: Copy, { type Distributions = (Distribution, Distribution); type Builder = (Vec, Vec); } impl TupledDistributions for (Distribution, Distribution) where A: Copy, B: Copy, { type Item = (A, B); } impl TupledDistributionsBuilder for (Vec, Vec) where A: Copy, B: Copy, { type Item = (A, B); fn new(size: usize) -> (Vec, Vec) { (Vec::with_capacity(size), Vec::with_capacity(size)) } fn push(&mut self, tuple: (A, B)) { (self.0).push(tuple.0); (self.1).push(tuple.1); } fn extend(&mut self, other: &mut (Vec, Vec)) { (self.0).append(&mut other.0); (self.1).append(&mut other.1); } fn complete(self) -> (Distribution, Distribution) { ( Distribution(self.0.into_boxed_slice()), Distribution(self.1.into_boxed_slice()), ) } } impl Tuple for (A, B, C) where A: Copy, B: Copy, C: Copy, { type Distributions = (Distribution, Distribution, Distribution); type Builder = (Vec, Vec, Vec); } impl TupledDistributions for (Distribution, Distribution, Distribution) where A: Copy, B: Copy, C: Copy, { type Item = (A, B, C); } impl TupledDistributionsBuilder for (Vec, Vec, Vec) where A: Copy, B: Copy, C: Copy, { type Item = (A, B, C); fn new(size: usize) -> (Vec, Vec, Vec) { ( Vec::with_capacity(size), Vec::with_capacity(size), Vec::with_capacity(size), ) } fn push(&mut self, tuple: (A, B, C)) { (self.0).push(tuple.0); (self.1).push(tuple.1); (self.2).push(tuple.2); } fn extend(&mut self, other: &mut (Vec, Vec, Vec)) { (self.0).append(&mut other.0); (self.1).append(&mut other.1); (self.2).append(&mut other.2); } fn complete(self) -> (Distribution, Distribution, Distribution) { ( Distribution(self.0.into_boxed_slice()), Distribution(self.1.into_boxed_slice()), Distribution(self.2.into_boxed_slice()), ) } } impl Tuple for (A, B, C, D) where A: Copy, B: Copy, C: Copy, D: Copy, { type Distributions = ( Distribution, Distribution, Distribution, Distribution, ); type Builder = (Vec, Vec, Vec, Vec); } impl TupledDistributions for ( Distribution, Distribution, Distribution, Distribution, ) where A: Copy, B: Copy, C: Copy, D: Copy, { type Item = (A, B, C, D); } impl TupledDistributionsBuilder for (Vec, Vec, Vec, Vec) where A: Copy, B: Copy, C: Copy, D: Copy, { type Item = (A, B, C, D); fn new(size: usize) -> (Vec, Vec, Vec, Vec) { ( Vec::with_capacity(size), Vec::with_capacity(size), Vec::with_capacity(size), Vec::with_capacity(size), ) } fn push(&mut self, tuple: (A, B, C, D)) { (self.0).push(tuple.0); (self.1).push(tuple.1); (self.2).push(tuple.2); (self.3).push(tuple.3); } fn extend(&mut self, other: &mut (Vec, Vec, Vec, Vec)) { (self.0).append(&mut other.0); (self.1).append(&mut other.1); (self.2).append(&mut other.2); (self.3).append(&mut other.3); } fn complete( self, ) -> ( Distribution, Distribution, Distribution, Distribution, ) { ( Distribution(self.0.into_boxed_slice()), Distribution(self.1.into_boxed_slice()), Distribution(self.2.into_boxed_slice()), Distribution(self.3.into_boxed_slice()), ) } }