diff options
-rw-r--r-- | src/lib.rs | 45 |
1 files changed, 45 insertions, 0 deletions
@@ -116,6 +116,8 @@ where } /// Returns a field of the item with the given index. + /// + /// This function is equivalant to doing `.get_all().get(index)` pub fn get<FieldSel>( &self, index: usize, @@ -138,6 +140,18 @@ where Some(unsafe { field_ptr.cast().as_ref() }) } + /// Returns a slice containing the specified field of all items. + pub fn get_all<FieldSel>(&self) -> &[<FieldSel as ItemFieldSelection<ItemT>>::Field] + where + FieldSel: ItemFieldSelection<ItemT>, + { + let field_arr_byte_offset = self.field_arr_byte_offsets[FieldSel::INDEX]; + + let field_arr_ptr = unsafe { self.ptr.byte_add(field_arr_byte_offset) }; + + unsafe { std::slice::from_raw_parts(field_arr_ptr.as_ptr().cast(), self.len()) } + } + /// Returns the number of items stored in this `MultiVec`. pub fn len(&self) -> usize { @@ -707,4 +721,35 @@ mod tests [9090, 2233, u16::MAX - 75, 8182] ); } + + #[test] + fn get_all_works() + { + let mut multi_vec = MultiVec::<Foo>::new(); + + #[repr(packed)] + #[allow(dead_code)] + struct Data + { + num_a: [u32; 3], + num_b: [u16; 3], + } + + let data = Data { + num_a: [u32::MAX - 3000, 901, 5560000], + num_b: [20210, 7120, 1010], + }; + + multi_vec.ptr = NonNull::from(&data).cast(); + multi_vec.field_arr_byte_offsets = vec![0, size_of::<u32>() * 3]; + multi_vec.length = 3; + multi_vec.capacity = 3; + + assert_eq!( + multi_vec.get_all::<FooFieldNumA>(), + [u32::MAX - 3000, 901, 5560000] + ); + + assert_eq!(multi_vec.get_all::<FooFieldNumB>(), [20210, 7120, 1010]); + } } |