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