Skip to main content

object_rainbow/
tuple_of_arrays.rs

1use std::iter::Zip;
2
3use crate::{sequence::PlainCollection, *};
4
5#[derive(
6    ListHashes, Topological, Tagged, Size, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord,
7)]
8pub struct TupleOfArrays<A, B>(A, B);
9
10impl<A: ByteOrd + Size, B: ByteOrd> ByteOrd for TupleOfArrays<A, B> {
11    fn bytes_cmp(&self, other: &Self) -> Ordering {
12        self.0
13            .bytes_cmp(&other.0)
14            .then_with(|| self.1.bytes_cmp(&other.1))
15    }
16}
17
18impl<A: ToOutput, B: ToOutput> ToOutput for TupleOfArrays<A, B> {
19    fn to_output(&self, output: &mut impl crate::Output) {
20        self.0.to_output(output);
21        self.1.to_output(output);
22    }
23}
24
25pub fn try_divide(n: usize, k: usize) -> crate::Result<usize> {
26    if !n.is_multiple_of(k) {
27        return Err(crate::error_parse!("doesn't divide evenly"));
28    }
29    n.checked_div(k)
30        .ok_or_else(|| crate::error_parse!("division failed"))
31}
32
33impl<
34    A: Parse<I> + PlainCollection<Item = Ae>,
35    B: Parse<I> + PlainCollection<Item = Be>,
36    I: ParseInput,
37    Ae: Size,
38    Be: Size,
39> Parse<I> for TupleOfArrays<A, B>
40{
41    fn parse(input: I) -> crate::Result<Self> {
42        let (mut input, n) = input.remaining()?;
43        let n = try_divide(n, Ae::SIZE + Be::SIZE)? * Ae::SIZE;
44        Ok(Self(input.split_parse(n)?, input.parse()?))
45    }
46}
47
48impl<A: IntoIterator, B: IntoIterator> IntoIterator for TupleOfArrays<A, B> {
49    type Item = (A::Item, B::Item);
50
51    type IntoIter = Zip<A::IntoIter, B::IntoIter>;
52
53    fn into_iter(self) -> Self::IntoIter {
54        self.0.into_iter().zip(self.1)
55    }
56}
57
58impl<'a, A, B> IntoIterator for &'a TupleOfArrays<A, B>
59where
60    &'a A: IntoIterator,
61    &'a B: IntoIterator,
62{
63    type Item = (<&'a A as IntoIterator>::Item, <&'a B as IntoIterator>::Item);
64
65    type IntoIter = Zip<<&'a A as IntoIterator>::IntoIter, <&'a B as IntoIterator>::IntoIter>;
66
67    fn into_iter(self) -> Self::IntoIter {
68        self.0.into_iter().zip(&self.1)
69    }
70}
71
72impl<'a, A, B> IntoIterator for &'a mut TupleOfArrays<A, B>
73where
74    &'a mut A: IntoIterator,
75    &'a mut B: IntoIterator,
76{
77    type Item = (
78        <&'a mut A as IntoIterator>::Item,
79        <&'a mut B as IntoIterator>::Item,
80    );
81
82    type IntoIter =
83        Zip<<&'a mut A as IntoIterator>::IntoIter, <&'a mut B as IntoIterator>::IntoIter>;
84
85    fn into_iter(self) -> Self::IntoIter {
86        self.0.into_iter().zip(&mut self.1)
87    }
88}
89
90impl<A: PlainCollection, B: PlainCollection> PlainCollection for TupleOfArrays<A, B> {}
91
92impl<A: Extend<L>, B: Extend<R>, L, R> Extend<(L, R)> for TupleOfArrays<A, B> {
93    fn extend<T: IntoIterator<Item = (L, R)>>(&mut self, iter: T) {
94        let (a, b): (Vec<_>, Vec<_>) = iter.into_iter().collect();
95        self.0.extend(a);
96        self.1.extend(b);
97    }
98}
99
100impl<A: FromIterator<L>, B: FromIterator<R>, L, R> FromIterator<(L, R)> for TupleOfArrays<A, B> {
101    fn from_iter<T: IntoIterator<Item = (L, R)>>(iter: T) -> Self {
102        let (a, b): (Vec<_>, Vec<_>) = iter.into_iter().collect();
103        Self(a.into_iter().collect(), b.into_iter().collect())
104    }
105}