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> = EitherRow<First::Row<'a>, Second::Row<'a>> where Self: 'a;
36
37 fn get(&self, r: usize, c: usize) -> T {
38 if r < self.first.height() {
39 self.first.get(r, c)
40 } else {
41 self.second.get(r - self.first.height(), c)
42 }
43 }
44
45 fn row(&self, r: usize) -> Self::Row<'_> {
46 if r < self.first.height() {
47 EitherRow::Left(self.first.row(r))
48 } else {
49 EitherRow::Right(self.second.row(r - self.first.height()))
50 }
51 }
52
53 fn row_slice(&self, r: usize) -> impl Deref<Target = [T]> {
54 if r < self.first.height() {
55 EitherRow::Left(self.first.row_slice(r))
56 } else {
57 EitherRow::Right(self.second.row_slice(r - self.first.height()))
58 }
59 }
60}
61
62#[derive(Debug)]
64pub enum EitherRow<L, R> {
65 Left(L),
66 Right(R),
67}
68
69impl<T, L, R> Iterator for EitherRow<L, R>
70where
71 L: Iterator<Item = T>,
72 R: Iterator<Item = T>,
73{
74 type Item = T;
75
76 fn next(&mut self) -> Option<Self::Item> {
77 match self {
78 EitherRow::Left(l) => l.next(),
79 EitherRow::Right(r) => r.next(),
80 }
81 }
82}
83
84impl<T, L, R> Deref for EitherRow<L, R>
85where
86 L: Deref<Target = [T]>,
87 R: Deref<Target = [T]>,
88{
89 type Target = [T];
90 fn deref(&self) -> &Self::Target {
91 match self {
92 EitherRow::Left(l) => l,
93 EitherRow::Right(r) => r,
94 }
95 }
96}