Skip to main content

columnar/
tuple.rs

1#![allow(non_snake_case)]
2
3use alloc::{vec::Vec, string::String};
4use crate::{Columnar, Container, Borrow, Len, Clear, Index, IndexMut, Push};
5
6// Implementations for tuple types.
7// These are all macro based, because the implementations are very similar.
8// The macro requires two names, one for the store and one for pushable types.
9macro_rules! tuple_impl {
10    ( $($name:ident,$name2:ident,$idx:tt)+) => (
11
12        impl<$($name: Columnar),*> Columnar for ($($name,)*) {
13            #[inline(always)]
14            fn copy_from<'a>(&mut self, other: crate::Ref<'a, Self>) {
15                let ($($name,)*) = self;
16                let ($($name2,)*) = other;
17                $(crate::Columnar::copy_from($name, $name2);)*
18            }
19            #[inline(always)]
20            fn into_owned<'a>(other: crate::Ref<'a, Self>) -> Self {
21                let ($($name2,)*) = other;
22                ($($name::into_owned($name2),)*)
23            }
24            type Container = ($($name::Container,)*);
25        }
26        impl<$($name2: Borrow,)*> Borrow for ($($name2,)*) {
27            type Ref<'a> = ($($name2::Ref<'a>,)*) where $($name2: 'a,)*;
28            type Borrowed<'a> = ($($name2::Borrowed<'a>,)*) where $($name2: 'a,)*;
29            #[inline(always)]
30            fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
31                let ($($name,)*) = self;
32                ($($name.borrow(),)*)
33            }
34            #[inline(always)]
35            fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> where $($name2: 'a,)* {
36                let ($($name,)*) = thing;
37                ($($name2::reborrow($name),)*)
38            }
39            #[inline(always)]
40            fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> where Self: 'a {
41                let ($($name2,)*) = thing;
42                ($($name2::reborrow_ref($name2),)*)
43            }
44        }
45        impl<$($name2: Container,)*> Container for ($($name2,)*) {
46            #[inline(always)]
47            fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: core::ops::Range<usize>) {
48                let ($($name,)*) = self;
49                let ($($name2,)*) = other;
50                $( $name.extend_from_self($name2, range.clone()); )*
51            }
52
53            fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
54                let ($($name,)*) = self;
55                $( $name.reserve_for(selves.clone().map(|x| x.$idx)); )*
56            }
57        }
58
59        #[allow(non_snake_case)]
60        impl<'a, $($name: crate::AsBytes<'a>),*> crate::AsBytes<'a> for ($($name,)*) {
61            const SLICE_COUNT: usize = 0 $(+ $name::SLICE_COUNT)*;
62            #[inline]
63            fn get_byte_slice(&self, index: usize) -> (u64, &'a [u8]) {
64                debug_assert!(index < Self::SLICE_COUNT);
65                let ($($name,)*) = self;
66                let mut _offset = 0;
67                $(
68                    if index < _offset + $name::SLICE_COUNT {
69                        return $name.get_byte_slice(index - _offset);
70                    }
71                    _offset += $name::SLICE_COUNT;
72                )*
73                panic!("get_byte_slice: index out of bounds")
74            }
75        }
76        impl<'a, $($name: crate::FromBytes<'a>),*> crate::FromBytes<'a> for ($($name,)*) {
77            const SLICE_COUNT: usize = 0 $(+ $name::SLICE_COUNT)*;
78            #[inline(always)]
79            #[allow(non_snake_case)]
80            fn from_bytes(bytes: &mut impl Iterator<Item=&'a [u8]>) -> Self {
81                $(let $name = crate::FromBytes::from_bytes(bytes);)*
82                ($($name,)*)
83            }
84            #[inline(always)]
85            #[allow(non_snake_case)]
86            fn from_store(store: &crate::bytes::indexed::DecodedStore<'a>, offset: &mut usize) -> Self {
87                $(let $name = $name::from_store(store, offset);)*
88                ($($name,)*)
89            }
90            fn element_sizes(sizes: &mut Vec<usize>) -> Result<(), String> {
91                $($name::element_sizes(sizes)?;)*
92                Ok(())
93            }
94        }
95
96        impl<$($name: Len),*> Len for ($($name,)*) {
97            #[inline(always)]
98            fn len(&self) -> usize {
99                self.0.len()
100            }
101        }
102        impl<$($name: Clear),*> Clear for ($($name,)*) {
103            #[inline(always)]
104            fn clear(&mut self) {
105                let ($($name,)*) = self;
106                $($name.clear();)*
107            }
108        }
109        impl<$($name: Index),*> Index for ($($name,)*) {
110            type Ref = ($($name::Ref,)*);
111            #[inline(always)]
112            fn get(&self, index: usize) -> Self::Ref {
113                let ($($name,)*) = self;
114                ($($name.get(index),)*)
115            }
116        }
117        impl<'a, $($name),*> Index for &'a ($($name,)*) where $( &'a $name: Index),* {
118            type Ref = ($(<&'a $name as Index>::Ref,)*);
119            #[inline(always)]
120            fn get(&self, index: usize) -> Self::Ref {
121                let ($($name,)*) = self;
122                ($($name.get(index),)*)
123            }
124        }
125
126        impl<$($name: IndexMut),*> IndexMut for ($($name,)*) {
127            type IndexMut<'a> = ($($name::IndexMut<'a>,)*) where $($name: 'a),*;
128            #[inline(always)]
129            fn get_mut(&mut self, index: usize) -> Self::IndexMut<'_> {
130                let ($($name,)*) = self;
131                ($($name.get_mut(index),)*)
132            }
133        }
134        impl<$($name2, $name: Push<$name2>),*> Push<($($name2,)*)> for ($($name,)*) {
135            #[inline]
136            fn push(&mut self, item: ($($name2,)*)) {
137                let ($($name,)*) = self;
138                let ($($name2,)*) = item;
139                $($name.push($name2);)*
140            }
141        }
142        impl<'a, $($name2, $name: Push<&'a $name2>),*> Push<&'a ($($name2,)*)> for ($($name,)*) {
143            #[inline]
144            fn push(&mut self, item: &'a ($($name2,)*)) {
145                let ($($name,)*) = self;
146                let ($($name2,)*) = item;
147                $($name.push($name2);)*
148            }
149        }
150    )
151}
152
153tuple_impl!(A,AA,0);
154tuple_impl!(A,AA,0 B,BB,1);
155tuple_impl!(A,AA,0 B,BB,1 C,CC,2);
156tuple_impl!(A,AA,0 B,BB,1 C,CC,2 D,DD,3);
157tuple_impl!(A,AA,0 B,BB,1 C,CC,2 D,DD,3 E,EE,4);
158tuple_impl!(A,AA,0 B,BB,1 C,CC,2 D,DD,3 E,EE,4 F,FF,5);
159tuple_impl!(A,AA,0 B,BB,1 C,CC,2 D,DD,3 E,EE,4 F,FF,5 G,GG,6);
160tuple_impl!(A,AA,0 B,BB,1 C,CC,2 D,DD,3 E,EE,4 F,FF,5 G,GG,6 H,HH,7);
161tuple_impl!(A,AA,0 B,BB,1 C,CC,2 D,DD,3 E,EE,4 F,FF,5 G,GG,6 H,HH,7 I,II,8);
162tuple_impl!(A,AA,0 B,BB,1 C,CC,2 D,DD,3 E,EE,4 F,FF,5 G,GG,6 H,HH,7 I,II,8 J,JJ,9);
163
164#[cfg(test)]
165mod test {
166    use alloc::string::{String, ToString};
167    #[test]
168    fn round_trip() {
169
170        use crate::common::{Index, Push, Len};
171
172        let mut column: crate::ContainerOf<(u64, u8, String)> = Default::default();
173        for i in 0..100 {
174            column.push((i, i as u8, &i.to_string()));
175            column.push((i, i as u8, &"".to_string()));
176        }
177
178        assert_eq!(column.len(), 200);
179
180        for i in 0..100u64 {
181            assert_eq!((&column).get((2*i+0) as usize), (&i, &(i as u8), i.to_string().as_bytes()));
182            assert_eq!((&column).get((2*i+1) as usize), (&i, &(i as u8), &b""[..]));
183        }
184
185    }
186}