1use crate::paired::Paired;
2use crate::side::Side;
3use std::{
4 convert::From,
5 ops::{Index, IndexMut},
6};
7
8#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
9pub struct Pair<T>([T; 2]);
10
11impl<T> Paired for Pair<T> {
12 type Item = T;
13 fn swap(&mut self) {
14 let data_ptr = self.0.as_mut_ptr();
15 unsafe {
16 std::ptr::swap(data_ptr.add(0), data_ptr.add(1));
17 }
18 }
19
20 fn get_left(&self) -> &Self::Item {
21 unsafe { self.0.get_unchecked(0) }
22 }
23
24 fn get_right(&self) -> &Self::Item {
25 unsafe { self.0.get_unchecked(1) }
26 }
27
28 fn get_left_mut(&mut self) -> &mut Self::Item {
29 unsafe { self.0.get_unchecked_mut(0) }
30 }
31
32 fn get_right_mut(&mut self) -> &mut Self::Item {
33 unsafe { self.0.get_unchecked_mut(1) }
34 }
35}
36
37impl<T> Pair<T> {
38 pub fn new(left: T, right: T) -> Self {
39 Self([left, right])
40 }
41
42 pub fn iter(&self) -> std::slice::Iter<T> {
43 self.0.iter()
44 }
45
46 pub fn iter_mut(&mut self) -> std::slice::IterMut<T> {
47 self.0.iter_mut()
48 }
49
50 pub fn map<U, F>(self, f: F) -> Pair<U>
51 where
52 F: Fn(T) -> U,
53 {
54 self.0.map(f).into()
55 }
56
57 pub fn zip<U>(self, other: Pair<U>) -> Pair<(T, U)> {
58 let [l1, r1] = self.0;
59 let [l2, r2]: [U; 2] = other.into();
60 [(l1, l2), (r1, r2)].into()
61 }
62
63 pub fn compare<'a, U>(self, other: &'a Pair<U>) -> Pair<(T, &'a U)> {
64 let [l1, r1] = self.0;
65 [(l1, other.get_left()), (r1, other.get_right())].into()
66 }
67
68 pub fn merge<U, V, F>(self, other: Pair<U>, f: F) -> Pair<V>
69 where
70 F: Fn(T, U) -> V,
71 {
72 self.zip(other).map(|(t, u)| f(t, u))
73 }
74
75 pub fn apply<U, V, F>(self, other: &Pair<U>, f: F) -> Pair<V>
76 where
77 F: Fn(T, &U) -> V,
78 {
79 self.compare(other).map(|(t, u)| f(t, u))
80 }
81}
82
83impl<T> Index<Side> for Pair<T> {
84 type Output = T;
85
86 fn index<'a>(&'a self, index: Side) -> &'a Self::Output {
87 self.get(index)
88 }
89}
90
91impl<T> IndexMut<Side> for Pair<T> {
92 fn index_mut<'a>(&'a mut self, index: Side) -> &'a mut T {
93 self.get_mut(index)
94 }
95}
96
97impl<T> IntoIterator for Pair<T> {
98 type Item = T;
99 type IntoIter = std::array::IntoIter<T, 2>;
100
101 fn into_iter(self) -> Self::IntoIter {
102 self.0.into_iter()
103 }
104}
105
106impl<T> AsRef<[T; 2]> for Pair<T> {
107 fn as_ref(&self) -> &[T; 2] {
108 &self.0
109 }
110}
111
112impl<T> AsMut<[T; 2]> for Pair<T> {
113 fn as_mut(&mut self) -> &mut [T; 2] {
114 &mut self.0
115 }
116}
117
118impl<T> From<[T; 2]> for Pair<T> {
119 fn from(arr: [T; 2]) -> Self {
120 Pair(arr)
121 }
122}
123
124impl<T> From<Pair<T>> for [T; 2] {
125 fn from(pair: Pair<T>) -> Self {
126 pair.0
127 }
128}
129
130impl<T> From<Pair<T>> for Pair<Option<T>> {
131 fn from(pair: Pair<T>) -> Self {
132 let [left, right]: [T; 2] = pair.into();
133 Self::from([Some(left), Some(right)])
134 }
135}
136
137impl<T> Pair<Option<T>> {
138 pub fn both(&self) -> bool {
139 self.get_left().is_some() && self.get_right().is_some()
140 }
141
142 pub fn none(&self) -> bool {
143 self.get_left().is_none() && self.get_right().is_none()
144 }
145
146 pub fn any(&self) -> bool {
147 self.get_left().is_some() || self.get_right().is_some()
148 }
149
150 pub fn one(&self) -> bool {
151 if self.get_left().is_some() {
152 self.get_right().is_none()
153 } else {
154 self.get_right().is_some()
155 }
156 }
157
158 pub fn map_some<U, F>(self, f: F) -> Pair<Option<U>>
159 where
160 F: Fn(T) -> U,
161 {
162 self.map(|i| i.map(|v| f(v)))
163 }
164}
165
166#[cfg(test)]
167mod tests {
168 use super::*;
169
170 #[test]
171 fn from_into_array() {
172 let (left, right) = (0, 1);
173 let pair = Pair::from([left, right]);
174 assert_eq!(pair[Side::L], left);
175 assert_eq!(pair[Side::R], right);
176
177 let arr: [i32; 2] = pair.into();
178 assert_eq!(arr, [left, right]);
179 }
180
181 #[test]
182 fn index_by_side() {
183 let (left, right) = (0, 1);
184 let mut pair = Pair::new(left, right);
185
186 assert_eq!(pair[Side::L], left);
187 assert_eq!(pair[Side::R], right);
188
189 let (new_left, new_right) = (0, 1);
190 pair[Side::L] = new_left;
191 pair[Side::R] = new_right;
192
193 assert_eq!(pair[Side::L], new_left);
194 assert_eq!(pair[Side::R], new_right);
195 }
196
197 #[test]
198 fn swap() {
199 let (left, right) = (0, 1);
200 let mut pair = Pair::new(left, right);
201 pair.swap();
202
203 assert_eq!(pair, Pair::from([right, left]));
204 }
205
206 #[test]
207 fn into_iter() {
208 let (left, right) = (0, 1);
209 let pair = Pair::new(left, right);
210
211 let mut it = pair.into_iter();
212
213 assert_eq!(it.next().unwrap(), left);
214 assert_eq!(it.next().unwrap(), right);
215 assert_eq!(it.next(), None);
216 }
217
218 #[test]
219 fn option() {
220 let (left, right) = (Some(0), Some(1));
221 let both_pair = Pair::new(left, right);
222 let none_pair: Pair<Option<()>> = Pair::new(None, None);
223 let left_pair = Pair::new(left, None);
224 let right_pair = Pair::new(None, right);
225
226 assert!(both_pair.both());
227 assert!(both_pair.any());
228 assert!(!both_pair.none());
229 assert!(!both_pair.one());
230
231 assert!(!none_pair.both());
232 assert!(!none_pair.any());
233 assert!(none_pair.none());
234 assert!(!none_pair.one());
235
236 assert!(!left_pair.both());
237 assert!(left_pair.any());
238 assert!(!left_pair.none());
239 assert!(left_pair.one());
240
241 assert!(!right_pair.both());
242 assert!(right_pair.any());
243 assert!(!right_pair.none());
244 assert!(right_pair.one());
245 }
246}