use super::*;
impl<S, T> ValueType for (S, T) {}
impl<S: Viewed, T: Viewed> Viewed for (S, T) {}
impl<A, B, S: Push<A>, T: Push<B>> Push<(A, B)> for (S, T) {
#[inline]
fn push(&mut self, (a, b): (A, B)) {
self.0.push(a);
self.1.push(b);
}
}
impl<S: Truncate, T: Truncate> Truncate for (S, T) {
#[inline]
fn truncate(&mut self, len: usize) {
self.0.truncate(len);
self.1.truncate(len);
}
}
impl<S: Clear, T: Clear> Clear for (S, T) {
#[inline]
fn clear(&mut self) {
self.0.clear();
self.1.clear();
}
}
impl<S: IntoStorage, T: IntoStorage> IntoStorage for (S, T) {
type StorageType = (S::StorageType, T::StorageType);
#[inline]
fn into_storage(self) -> Self::StorageType {
(self.0.into_storage(), self.1.into_storage())
}
}
impl<U, V, S: StorageInto<U>, T: StorageInto<V>> StorageInto<(U, V)> for (S, T) {
type Output = (S::Output, T::Output);
#[inline]
fn storage_into(self) -> Self::Output {
(self.0.storage_into(), self.1.storage_into())
}
}
impl<S, T, Out> MapStorage<Out> for (S, T) {
type Input = (S, T);
type Output = Out;
#[inline]
fn map_storage<F: FnOnce(Self::Input) -> Out>(self, f: F) -> Self::Output {
f(self)
}
}
impl<S, T, U> CloneWithStorage<U> for (S, T) {
type CloneType = U;
#[inline]
fn clone_with_storage(&self, storage: U) -> Self::CloneType {
storage
}
}
impl<S: IntoOwned, T: IntoOwned> IntoOwned for (S, T) {
type Owned = (S::Owned, T::Owned);
#[inline]
fn into_owned(self) -> Self::Owned {
(self.0.into_owned(), self.1.into_owned())
}
}
impl<S: IntoOwnedData, T: IntoOwnedData> IntoOwnedData for (S, T) {
type OwnedData = (S::OwnedData, T::OwnedData);
#[inline]
fn into_owned_data(self) -> Self::OwnedData {
(self.0.into_owned_data(), self.1.into_owned_data())
}
}
impl<'a, S, T> GetIndex<'a, (S, T)> for usize
where
S: Get<'a, usize>,
T: Get<'a, usize>,
{
type Output = (S::Output, T::Output);
#[inline]
fn get(self, (ref s, ref t): &(S, T)) -> Option<Self::Output> {
s.get(self)
.and_then(|s_item| t.get(self).map(|t_item| (s_item, t_item)))
}
}
impl<'a, S, T> GetIndex<'a, (S, T)> for std::ops::Range<usize>
where
S: Get<'a, std::ops::Range<usize>>,
T: Get<'a, std::ops::Range<usize>>,
{
type Output = (S::Output, T::Output);
#[inline]
fn get(self, (ref s, ref t): &(S, T)) -> Option<Self::Output> {
s.get(self.clone())
.and_then(|s_item| t.get(self).map(|t_item| (s_item, t_item)))
}
}
impl<'a, S, T, N> GetIndex<'a, (S, T)> for StaticRange<N>
where
S: Get<'a, StaticRange<N>>,
T: Get<'a, StaticRange<N>>,
N: Unsigned + Copy,
{
type Output = (S::Output, T::Output);
#[inline]
fn get(self, (ref s, ref t): &(S, T)) -> Option<Self::Output> {
s.get(self)
.and_then(|s_item| t.get(self).map(|t_item| (s_item, t_item)))
}
}
impl<'a, S, T> IsolateIndex<(S, T)> for usize
where
S: Isolate<usize>,
T: Isolate<usize>,
{
type Output = (S::Output, T::Output);
#[inline]
unsafe fn isolate_unchecked(self, (s, t): (S, T)) -> Self::Output {
(s.isolate_unchecked(self), t.isolate_unchecked(self))
}
#[inline]
fn try_isolate(self, (s, t): (S, T)) -> Option<Self::Output> {
s.try_isolate(self)
.and_then(|s_item| t.try_isolate(self).map(|t_item| (s_item, t_item)))
}
}
impl<'a, S, T> IsolateIndex<(S, T)> for std::ops::Range<usize>
where
S: Isolate<std::ops::Range<usize>>,
T: Isolate<std::ops::Range<usize>>,
{
type Output = (S::Output, T::Output);
#[inline]
unsafe fn isolate_unchecked(self, (s, t): (S, T)) -> Self::Output {
(s.isolate_unchecked(self.clone()), t.isolate_unchecked(self))
}
#[inline]
fn try_isolate(self, (s, t): (S, T)) -> Option<Self::Output> {
s.try_isolate(self.clone())
.and_then(|s_item| t.try_isolate(self).map(|t_item| (s_item, t_item)))
}
}
impl<S: Set, T: Set> Set for (S, T) {
type Elem = (S::Elem, T::Elem);
type Atom = (S::Atom, T::Atom);
#[inline]
fn len(&self) -> usize {
debug_assert_eq!(self.0.len(), self.1.len());
self.0.len()
}
}
impl<'a, S: View<'a>, T: View<'a>> View<'a> for (S, T) {
type Type = (S::Type, T::Type);
#[inline]
fn view(&'a self) -> Self::Type {
(self.0.view(), self.1.view())
}
}
impl<'a, S: ViewMut<'a>, T: ViewMut<'a>> ViewMut<'a> for (S, T) {
type Type = (S::Type, T::Type);
#[inline]
fn view_mut(&'a mut self) -> Self::Type {
(self.0.view_mut(), self.1.view_mut())
}
}
impl<S, T> SplitAt for (S, T)
where
S: SplitAt,
T: SplitAt,
{
#[inline]
fn split_at(self, mid: usize) -> (Self, Self) {
let (s, t) = self;
let (s_l, s_r) = s.split_at(mid);
let (t_l, t_r) = t.split_at(mid);
((s_l, t_l), (s_r, t_r))
}
}
impl<S, T> SplitOff for (S, T)
where
S: SplitOff,
T: SplitOff,
{
#[inline]
fn split_off(&mut self, mid: usize) -> Self {
let (s, t) = self;
let s_r = s.split_off(mid);
let t_r = t.split_off(mid);
(s_r, t_r)
}
}
impl<S, T, N> SplitPrefix<N> for (S, T)
where
S: SplitPrefix<N>,
T: SplitPrefix<N>,
{
type Prefix = (S::Prefix, T::Prefix);
#[inline]
fn split_prefix(self) -> Option<(Self::Prefix, Self)> {
let (s, t) = self;
s.split_prefix().and_then(|(s_prefix, s_rest)| {
t.split_prefix()
.map(|(t_prefix, t_rest)| ((s_prefix, t_prefix), (s_rest, t_rest)))
})
}
}
impl<S, T> SplitFirst for (S, T)
where
S: SplitFirst,
T: SplitFirst,
{
type First = (S::First, T::First);
#[inline]
fn split_first(self) -> Option<(Self::First, Self)> {
let (s, t) = self;
s.split_first().and_then(|(s_first, s_rest)| {
t.split_first()
.map(|(t_first, t_rest)| ((s_first, t_first), (s_rest, t_rest)))
})
}
}
impl<S: Storage<Storage = S>, T: Storage<Storage = T>> Storage for (S, T) {
type Storage = (S, T);
#[inline]
fn storage(&self) -> &Self::Storage {
self
}
}
impl<S: StorageMut<Storage = S>, T: StorageMut<Storage = T>> StorageMut for (S, T) {
#[inline]
fn storage_mut(&mut self) -> &mut Self::Storage {
self
}
}
impl<S: Dummy, T: Dummy> Dummy for (S, T) {
#[inline]
unsafe fn dummy() -> Self {
(S::dummy(), T::dummy())
}
}
impl<S: RemovePrefix, T: RemovePrefix> RemovePrefix for (S, T) {
#[inline]
fn remove_prefix(&mut self, n: usize) {
self.0.remove_prefix(n);
self.1.remove_prefix(n);
}
}
impl<N, S, T> IntoStaticChunkIterator<N> for (S, T)
where
S: IntoStaticChunkIterator<N>,
T: IntoStaticChunkIterator<N>,
N: Unsigned,
{
type Item = (S::Item, T::Item);
type IterType = std::iter::Zip<S::IterType, T::IterType>;
#[inline]
fn into_static_chunk_iter(self) -> Self::IterType {
self.0
.into_static_chunk_iter()
.zip(self.1.into_static_chunk_iter())
}
}
impl<N, S: UniChunkable<N>, T: UniChunkable<N>> UniChunkable<N> for (S, T) {
type Chunk = (S::Chunk, T::Chunk);
}
impl<S: PushChunk<N>, T: PushChunk<N>, N> PushChunk<N> for (S, T) {
#[inline]
fn push_chunk(&mut self, chunk: Self::Chunk) {
self.0.push_chunk(chunk.0);
self.1.push_chunk(chunk.1);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn unichunked_tuple() {
let a = vec![1, 2, 3, 4];
let b = vec![6, 7, 8, 9];
let chunked_a_b = Chunked2::from_flat((a, b));
assert_eq!(chunked_a_b.view().at(0), (&[1, 2], &[6, 7]));
let mut iter = chunked_a_b.iter();
assert_eq!(iter.next().unwrap(), (&[1, 2], &[6, 7]));
assert_eq!(iter.next().unwrap(), (&[3, 4], &[8, 9]));
assert_eq!(iter.next(), None);
}
#[test]
fn chunked_tuple() {
let sizes = vec![1, 2, 2];
let a = vec![1, 2, 3, 4, 5];
let b = vec![6, 7, 8, 9, 10];
let chunked_a_b = Chunked::from_sizes(sizes, (a, b));
let mut iter = chunked_a_b.iter();
assert_eq!(iter.next().unwrap(), (&[1][..], &[6][..]));
assert_eq!(iter.next().unwrap(), (&[2, 3][..], &[7, 8][..]));
assert_eq!(iter.next().unwrap(), (&[4, 5][..], &[9, 10][..]));
assert_eq!(iter.next(), None);
}
#[test]
fn chunked_unichunked_tuple_push() {
let sizes = vec![1, 2];
let a = vec![1, 2, 3, 4, 5, 6];
let b = vec![7, 8, 9, 10, 11, 12];
let mut a_b = Chunked::from_sizes(sizes, Chunked2::from_flat((a, b)));
a_b.push_iter(std::iter::once(([1, 2], [3, 4])));
let mut iter = a_b.iter();
assert_eq!(
iter.next().unwrap(),
Chunked2::from_flat((&[1, 2][..], &[7, 8][..]))
);
assert_eq!(
iter.next().unwrap(),
Chunked2::from_flat((&[3, 4, 5, 6][..], &[9, 10, 11, 12][..]))
);
assert_eq!(
iter.next().unwrap(),
Chunked2::from_flat((&[1, 2][..], &[3, 4][..]))
);
assert_eq!(iter.next(), None);
}
#[cfg(feature = "sparse")]
#[test]
fn sparse_chunked_tuple() {
let idx = vec![0, 3, 4];
let sizes = vec![1, 2, 2];
let a = vec![1, 2, 3, 4, 5];
let b = vec![6, 7, 8, 9, 10];
let a_b = Sparse::from_dim(idx, 5, Chunked::from_sizes(sizes, (a, b)));
let mut iter = a_b.iter();
assert_eq!(iter.next().unwrap(), (0, (&[1][..], &[6][..]), 0));
assert_eq!(iter.next().unwrap(), (3, (&[2, 3][..], &[7, 8][..]), 3));
assert_eq!(iter.next().unwrap(), (4, (&[4, 5][..], &[9, 10][..]), 4));
assert_eq!(iter.next(), None);
}
}