-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
enhancementNew feature or requestNew feature or request
Description
While safer (and avoids issues with mistakenly deriving SoAble on a type with Drop), it may be less efficient (depending on compiler optimisations) and at the very least more redundant to rely on the SoAble::to_tuple / SoAble::from_tuple methods for moving between T and "T inside SoAVec allocation".
A more optimal but unsafe choice would be a method SoAble::get_field_pointers that takes an exclusive reference to possibly uninitialised T, and returns T::TupleRepr::Pointers pointing at the fields of T. This API can be used to then efficiently either copy data out of T (when moving from T to "T inside SoAVec allocation") field by field, or to initialise the fields of T (when doing the reverse).
fn push(value: T) {
let mut value = MaybeUninit::new(value); // moves value into MU; dropping the MU does not drop `value` anymore.
let field_pointers = unsafe { T::get_field_pointers(&mut value) }; // probably unsafe to do this, gotta think on it
let soa_pointers = T::TupleRepr::get_pointers(self.buf.as_ptr(), self.capacity(), self.len());
T::TupleRepr::copy(field_pointers, soa_pointers, 1); // copy field pointers into soa
}
fn pop() -> Option<T> {
if self.is_empty() {
return None;
}
let mut value: MaybeUninit::uninit();
let field_pointers = T::get_field_pointers(&mut value);
self.set_len(self.len() - 1);
let soa_pointers = T::TupleRepr::get_pointers(self.buf.as_ptr(), self.capacity(), self.len());
T::TupleRepr::copy(soa_pointers, field_pointers, 1); // copy soa pointers into value; this initialises it
Some(value.assume_init())
}Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request