1use super::*;
5
6impl<S, T> ValueType for (S, T) {}
8impl<S: Viewed, T: Viewed> Viewed for (S, T) {}
9
10impl<A, B, S: Push<A>, T: Push<B>> Push<(A, B)> for (S, T) {
11 #[inline]
12 fn push(&mut self, (a, b): (A, B)) {
13 self.0.push(a);
14 self.1.push(b);
15 }
16}
17
18impl<S: Truncate, T: Truncate> Truncate for (S, T) {
19 #[inline]
20 fn truncate(&mut self, len: usize) {
21 self.0.truncate(len);
22 self.1.truncate(len);
23 }
24}
25
26impl<S: Clear, T: Clear> Clear for (S, T) {
27 #[inline]
28 fn clear(&mut self) {
29 self.0.clear();
30 self.1.clear();
31 }
32}
33
34impl<S: IntoStorage, T: IntoStorage> IntoStorage for (S, T) {
35 type StorageType = (S::StorageType, T::StorageType);
36
37 #[inline]
38 fn into_storage(self) -> Self::StorageType {
39 (self.0.into_storage(), self.1.into_storage())
40 }
41}
42
43impl<U, V, S: StorageInto<U>, T: StorageInto<V>> StorageInto<(U, V)> for (S, T) {
44 type Output = (S::Output, T::Output);
45 #[inline]
46 fn storage_into(self) -> Self::Output {
47 (self.0.storage_into(), self.1.storage_into())
48 }
49}
50
51impl<S, T, Out> MapStorage<Out> for (S, T) {
52 type Input = (S, T);
53 type Output = Out;
54 #[inline]
55 fn map_storage<F: FnOnce(Self::Input) -> Out>(self, f: F) -> Self::Output {
56 f(self)
57 }
58}
59
60impl<S, T, U> CloneWithStorage<U> for (S, T) {
61 type CloneType = U;
62 #[inline]
63 fn clone_with_storage(&self, storage: U) -> Self::CloneType {
64 storage
65 }
66}
67
68impl<S: IntoOwned, T: IntoOwned> IntoOwned for (S, T) {
69 type Owned = (S::Owned, T::Owned);
70 #[inline]
71 fn into_owned(self) -> Self::Owned {
72 (self.0.into_owned(), self.1.into_owned())
73 }
74}
75
76impl<S: IntoOwnedData, T: IntoOwnedData> IntoOwnedData for (S, T) {
77 type OwnedData = (S::OwnedData, T::OwnedData);
78 #[inline]
79 fn into_owned_data(self) -> Self::OwnedData {
80 (self.0.into_owned_data(), self.1.into_owned_data())
81 }
82}
83
84impl<'a, S, T> GetIndex<'a, (S, T)> for usize
85where
86 S: Get<'a, usize>,
87 T: Get<'a, usize>,
88{
89 type Output = (S::Output, T::Output);
90 #[inline]
91 fn get(self, (ref s, ref t): &(S, T)) -> Option<Self::Output> {
92 s.get(self)
93 .and_then(|s_item| t.get(self).map(|t_item| (s_item, t_item)))
94 }
95}
96
97impl<'a, S, T> GetIndex<'a, (S, T)> for std::ops::Range<usize>
98where
99 S: Get<'a, std::ops::Range<usize>>,
100 T: Get<'a, std::ops::Range<usize>>,
101{
102 type Output = (S::Output, T::Output);
103 #[inline]
104 fn get(self, (ref s, ref t): &(S, T)) -> Option<Self::Output> {
105 s.get(self.clone())
106 .and_then(|s_item| t.get(self).map(|t_item| (s_item, t_item)))
107 }
108}
109
110impl<'a, S, T, N> GetIndex<'a, (S, T)> for StaticRange<N>
111where
112 S: Get<'a, StaticRange<N>>,
113 T: Get<'a, StaticRange<N>>,
114 N: Unsigned + Copy,
115{
116 type Output = (S::Output, T::Output);
117 #[inline]
118 fn get(self, (ref s, ref t): &(S, T)) -> Option<Self::Output> {
119 s.get(self)
120 .and_then(|s_item| t.get(self).map(|t_item| (s_item, t_item)))
121 }
122}
123
124impl<'a, S, T> IsolateIndex<(S, T)> for usize
125where
126 S: Isolate<usize>,
127 T: Isolate<usize>,
128{
129 type Output = (S::Output, T::Output);
130 #[inline]
131 unsafe fn isolate_unchecked(self, (s, t): (S, T)) -> Self::Output {
132 (s.isolate_unchecked(self), t.isolate_unchecked(self))
133 }
134 #[inline]
135 fn try_isolate(self, (s, t): (S, T)) -> Option<Self::Output> {
136 s.try_isolate(self)
137 .and_then(|s_item| t.try_isolate(self).map(|t_item| (s_item, t_item)))
138 }
139}
140
141impl<'a, S, T> IsolateIndex<(S, T)> for std::ops::Range<usize>
142where
143 S: Isolate<std::ops::Range<usize>>,
144 T: Isolate<std::ops::Range<usize>>,
145{
146 type Output = (S::Output, T::Output);
147 #[inline]
148 unsafe fn isolate_unchecked(self, (s, t): (S, T)) -> Self::Output {
149 (s.isolate_unchecked(self.clone()), t.isolate_unchecked(self))
150 }
151 #[inline]
152 fn try_isolate(self, (s, t): (S, T)) -> Option<Self::Output> {
153 s.try_isolate(self.clone())
154 .and_then(|s_item| t.try_isolate(self).map(|t_item| (s_item, t_item)))
155 }
156}
157
158impl<S: Set, T: Set> Set for (S, T) {
159 type Elem = (S::Elem, T::Elem);
160 type Atom = (S::Atom, T::Atom);
161 #[inline]
162 fn len(&self) -> usize {
163 debug_assert_eq!(self.0.len(), self.1.len());
164 self.0.len()
165 }
166}
167
168impl<'a, S: View<'a>, T: View<'a>> View<'a> for (S, T) {
169 type Type = (S::Type, T::Type);
170
171 #[inline]
172 fn view(&'a self) -> Self::Type {
173 (self.0.view(), self.1.view())
174 }
175}
176
177impl<'a, S: ViewMut<'a>, T: ViewMut<'a>> ViewMut<'a> for (S, T) {
178 type Type = (S::Type, T::Type);
179
180 #[inline]
181 fn view_mut(&'a mut self) -> Self::Type {
182 (self.0.view_mut(), self.1.view_mut())
183 }
184}
185
186impl<S, T> SplitAt for (S, T)
187where
188 S: SplitAt,
189 T: SplitAt,
190{
191 #[inline]
192 fn split_at(self, mid: usize) -> (Self, Self) {
193 let (s, t) = self;
194 let (s_l, s_r) = s.split_at(mid);
195 let (t_l, t_r) = t.split_at(mid);
196 ((s_l, t_l), (s_r, t_r))
197 }
198}
199
200impl<S, T> SplitOff for (S, T)
201where
202 S: SplitOff,
203 T: SplitOff,
204{
205 #[inline]
206 fn split_off(&mut self, mid: usize) -> Self {
207 let (s, t) = self;
208 let s_r = s.split_off(mid);
209 let t_r = t.split_off(mid);
210 (s_r, t_r)
211 }
212}
213
214impl<S, T, N> SplitPrefix<N> for (S, T)
215where
216 S: SplitPrefix<N>,
217 T: SplitPrefix<N>,
218{
219 type Prefix = (S::Prefix, T::Prefix);
220
221 #[inline]
222 fn split_prefix(self) -> Option<(Self::Prefix, Self)> {
223 let (s, t) = self;
224 s.split_prefix().and_then(|(s_prefix, s_rest)| {
225 t.split_prefix()
226 .map(|(t_prefix, t_rest)| ((s_prefix, t_prefix), (s_rest, t_rest)))
227 })
228 }
229}
230
231impl<S, T> SplitFirst for (S, T)
232where
233 S: SplitFirst,
234 T: SplitFirst,
235{
236 type First = (S::First, T::First);
237
238 #[inline]
239 fn split_first(self) -> Option<(Self::First, Self)> {
240 let (s, t) = self;
241 s.split_first().and_then(|(s_first, s_rest)| {
242 t.split_first()
243 .map(|(t_first, t_rest)| ((s_first, t_first), (s_rest, t_rest)))
244 })
245 }
246}
247
248impl<S: Storage<Storage = S>, T: Storage<Storage = T>> Storage for (S, T) {
252 type Storage = (S, T);
253 #[inline]
254 fn storage(&self) -> &Self::Storage {
255 self
256 }
257}
258
259impl<S: StorageMut<Storage = S>, T: StorageMut<Storage = T>> StorageMut for (S, T) {
260 #[inline]
261 fn storage_mut(&mut self) -> &mut Self::Storage {
262 self
263 }
264}
265
266impl<S: Dummy, T: Dummy> Dummy for (S, T) {
267 #[inline]
268 unsafe fn dummy() -> Self {
269 (S::dummy(), T::dummy())
270 }
271}
272
273impl<S: RemovePrefix, T: RemovePrefix> RemovePrefix for (S, T) {
274 #[inline]
275 fn remove_prefix(&mut self, n: usize) {
276 self.0.remove_prefix(n);
277 self.1.remove_prefix(n);
278 }
279}
280
281impl<N, S, T> IntoStaticChunkIterator<N> for (S, T)
282where
283 S: IntoStaticChunkIterator<N>,
284 T: IntoStaticChunkIterator<N>,
285 N: Unsigned,
286{
287 type Item = (S::Item, T::Item);
288 type IterType = std::iter::Zip<S::IterType, T::IterType>;
289
290 #[inline]
291 fn into_static_chunk_iter(self) -> Self::IterType {
292 self.0
293 .into_static_chunk_iter()
294 .zip(self.1.into_static_chunk_iter())
295 }
296}
297
298impl<N, S: UniChunkable<N>, T: UniChunkable<N>> UniChunkable<N> for (S, T) {
299 type Chunk = (S::Chunk, T::Chunk);
300}
301
302impl<S: PushChunk<N>, T: PushChunk<N>, N> PushChunk<N> for (S, T) {
303 #[inline]
304 fn push_chunk(&mut self, chunk: Self::Chunk) {
305 self.0.push_chunk(chunk.0);
306 self.1.push_chunk(chunk.1);
307 }
308}
309
310#[cfg(test)]
311mod tests {
312 use super::*;
313
314 #[test]
315 fn unichunked_tuple() {
316 let a = vec![1, 2, 3, 4];
317 let b = vec![6, 7, 8, 9];
318 let chunked_a_b = Chunked2::from_flat((a, b));
319 assert_eq!(chunked_a_b.view().at(0), (&[1, 2], &[6, 7]));
320 let mut iter = chunked_a_b.iter();
321 assert_eq!(iter.next().unwrap(), (&[1, 2], &[6, 7]));
322 assert_eq!(iter.next().unwrap(), (&[3, 4], &[8, 9]));
323 assert_eq!(iter.next(), None);
324 }
325
326 #[test]
327 fn chunked_tuple() {
328 let sizes = vec![1, 2, 2];
329 let a = vec![1, 2, 3, 4, 5];
330 let b = vec![6, 7, 8, 9, 10];
331 let chunked_a_b = Chunked::from_sizes(sizes, (a, b));
332 let mut iter = chunked_a_b.iter();
333 assert_eq!(iter.next().unwrap(), (&[1][..], &[6][..]));
334 assert_eq!(iter.next().unwrap(), (&[2, 3][..], &[7, 8][..]));
335 assert_eq!(iter.next().unwrap(), (&[4, 5][..], &[9, 10][..]));
336 assert_eq!(iter.next(), None);
337 }
338
339 #[test]
340 fn chunked_unichunked_tuple_push() {
341 let sizes = vec![1, 2];
342 let a = vec![1, 2, 3, 4, 5, 6];
343 let b = vec![7, 8, 9, 10, 11, 12];
344 let mut a_b = Chunked::from_sizes(sizes, Chunked2::from_flat((a, b)));
345 a_b.push_iter(std::iter::once(([1, 2], [3, 4])));
346 let mut iter = a_b.iter();
347 assert_eq!(
348 iter.next().unwrap(),
349 Chunked2::from_flat((&[1, 2][..], &[7, 8][..]))
350 );
351 assert_eq!(
352 iter.next().unwrap(),
353 Chunked2::from_flat((&[3, 4, 5, 6][..], &[9, 10, 11, 12][..]))
354 );
355 assert_eq!(
356 iter.next().unwrap(),
357 Chunked2::from_flat((&[1, 2][..], &[3, 4][..]))
358 );
359 assert_eq!(iter.next(), None);
360 }
361
362 #[cfg(feature = "sparse")]
363 #[test]
364 fn sparse_chunked_tuple() {
365 let idx = vec![0, 3, 4];
366 let sizes = vec![1, 2, 2];
367 let a = vec![1, 2, 3, 4, 5];
368 let b = vec![6, 7, 8, 9, 10];
369 let a_b = Sparse::from_dim(idx, 5, Chunked::from_sizes(sizes, (a, b)));
370
371 let mut iter = a_b.iter();
373 assert_eq!(iter.next().unwrap(), (0, (&[1][..], &[6][..]), 0));
374 assert_eq!(iter.next().unwrap(), (3, (&[2, 3][..], &[7, 8][..]), 3));
375 assert_eq!(iter.next().unwrap(), (4, (&[4, 5][..], &[9, 10][..]), 4));
376 assert_eq!(iter.next(), None);
377
378 }
381}