object_rainbow/
tuple_of_arrays.rs1use 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}