diff options
author | HampusM <hampus@hampusmat.com> | 2024-08-27 20:30:11 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2024-08-27 20:30:11 +0200 |
commit | 43b5892cf99c29ce75a365ae001b3ec6dd6cb688 (patch) | |
tree | 65724d1b5d4e7176ce0bba3849858519be4d8ff8 /src | |
parent | 8ad76813f7c82e4b35991f9ca40a443e4357e17a (diff) |
feat: make MultiVec implement FromIterator
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 60 |
1 files changed, 60 insertions, 0 deletions
@@ -271,6 +271,33 @@ where } } +impl<ItemT> FromIterator<ItemT> for MultiVec<ItemT> +where + ItemT: Item, +{ + fn from_iter<ItemIter: IntoIterator<Item = ItemT>>(iter: ItemIter) -> Self + { + let iter = iter.into_iter(); + + let initial_capacity = + max(Self::MIN_NON_ZERO_CAP, iter.size_hint().0.saturating_add(1)); + + let mut this = Self::with_capacity(initial_capacity); + + for item in iter { + if this.capacity == this.length { + this.grow_amortized(1); + } + + this.write_item(this.length, item); + + this.length += 1; + } + + this + } +} + impl<ItemT> Drop for MultiVec<ItemT> where ItemT: Item, @@ -647,4 +674,37 @@ mod tests assert_eq!(multi_vec.get::<FooFieldNumA>(2).copied(), Some(5560000)); assert_eq!(multi_vec.get::<FooFieldNumB>(2).copied(), Some(1010)); } + + #[test] + fn from_iter_works() + { + let multi_vec = MultiVec::<Foo>::from_iter([ + Foo { num_a: 456456, num_b: 9090 }, + Foo { num_a: 79541, num_b: 2233 }, + Foo { num_a: 1761919, num_b: u16::MAX - 75 }, + Foo { num_a: u32::MAX / 9, num_b: 8182 }, + ]); + + assert_eq!(multi_vec.length, 4); + assert_eq!(multi_vec.capacity, 5); + + assert_eq!(multi_vec.field_arr_byte_offsets, [0, size_of::<u32>() * 5]); + + assert_eq!( + unsafe { + std::slice::from_raw_parts::<u32>(multi_vec.ptr.as_ptr().cast(), 4) + }, + [456456, 79541, 1761919, u32::MAX / 9] + ); + + assert_eq!( + unsafe { + std::slice::from_raw_parts::<u16>( + multi_vec.ptr.as_ptr().byte_add(size_of::<u32>() * 5).cast(), + 4, + ) + }, + [9090, 2233, u16::MAX - 75, 8182] + ); + } } |