summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib.rs60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 1fc7803..e55d8ec 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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]
+ );
+ }
}