1use core::ops::Deref;
2
3use crate::Matrix;
4
5#[derive(Copy, Clone, Debug)]
7pub struct VerticalPair<First, Second> {
8 first: First,
9 second: Second,
10}
11
12impl<First, Second> VerticalPair<First, Second> {
13 pub fn new<T>(first: First, second: Second) -> Self
14 where
15 T: Send + Sync,
16 First: Matrix<T>,
17 Second: Matrix<T>,
18 {
19 assert_eq!(first.width(), second.width());
20 Self { first, second }
21 }
22}
23
24impl<T: Send + Sync, First: Matrix<T>, Second: Matrix<T>> Matrix<T>
25 for VerticalPair<First, Second>
26{
27 fn width(&self) -> usize {
28 self.first.width()
29 }
30
31 fn height(&self) -> usize {
32 self.first.height() + self.second.height()
33 }
34
35 type Row<'a>
36 = EitherRow<First::Row<'a>, Second::Row<'a>>
37 where
38 Self: 'a;
39
40 fn get(&self, r: usize, c: usize) -> T {
41 if r < self.first.height() {
42 self.first.get(r, c)
43 } else {
44 self.second.get(r - self.first.height(), c)
45 }
46 }
47
48 fn row(&self, r: usize) -> Self::Row<'_> {
49 if r < self.first.height() {
50 EitherRow::Left(self.first.row(r))
51 } else {
52 EitherRow::Right(self.second.row(r - self.first.height()))
53 }
54 }
55
56 fn row_slice(&self, r: usize) -> impl Deref<Target = [T]> {
57 if r < self.first.height() {
58 EitherRow::Left(self.first.row_slice(r))
59 } else {
60 EitherRow::Right(self.second.row_slice(r - self.first.height()))
61 }
62 }
63}
64
65#[derive(Debug)]
67pub enum EitherRow<L, R> {
68 Left(L),
69 Right(R),
70}
71
72impl<T, L, R> Iterator for EitherRow<L, R>
73where
74 L: Iterator<Item = T>,
75 R: Iterator<Item = T>,
76{
77 type Item = T;
78
79 fn next(&mut self) -> Option<Self::Item> {
80 match self {
81 EitherRow::Left(l) => l.next(),
82 EitherRow::Right(r) => r.next(),
83 }
84 }
85}
86
87impl<T, L, R> Deref for EitherRow<L, R>
88where
89 L: Deref<Target = [T]>,
90 R: Deref<Target = [T]>,
91{
92 type Target = [T];
93 fn deref(&self) -> &Self::Target {
94 match self {
95 EitherRow::Left(l) => l,
96 EitherRow::Right(r) => r,
97 }
98 }
99}