1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
pub trait Unzip3<A, B, C> { fn unzip3<FromA, FromB, FromC>(self) -> (FromA, FromB, FromC) where FromA: Default + Extend<A>, FromB: Default + Extend<B>, FromC: Default + Extend<C>; } impl<I, A, B, C> Unzip3<A, B, C> for I where I: Sized + Iterator<Item=(A, B, C)> { fn unzip3<FromA, FromB, FromC>(self) -> (FromA, FromB, FromC) where FromA: Default + Extend<A>, FromB: Default + Extend<B>, FromC: Default + Extend<C>, { struct SizeHint<A>(usize, Option<usize>, std::marker::PhantomData<A>); impl<A> Iterator for SizeHint<A> { type Item = A; fn next(&mut self) -> Option<A> { None } fn size_hint(&self) -> (usize, Option<usize>) { (self.0, self.1) } } let (lo, hi) = self.size_hint(); let mut ts: FromA = Default::default(); let mut us: FromB = Default::default(); let mut vs: FromC = Default::default(); ts.extend(SizeHint(lo, hi, std::marker::PhantomData)); us.extend(SizeHint(lo, hi, std::marker::PhantomData)); vs.extend(SizeHint(lo, hi, std::marker::PhantomData)); for (t, u, v) in self { ts.extend(Some(t)); us.extend(Some(u)); vs.extend(Some(v)); } (ts, us, vs) } } #[test] fn it_works() { let (a, b, c): (Vec<_>, Vec<_>, Vec<_>) = vec![(1,2,3),(4,5,6)].iter().cloned().unzip3(); assert_eq!(vec![1,4], a); assert_eq!(vec![2,5], b); assert_eq!(vec![3,6], c); }