# HG changeset patch # User alfadur # Date 1566925757 -10800 # Node ID d6b4586b271f1189d9ec6d9dd15b1fd9939ed77a # Parent 381c828865e72b84f04001ed31c9bda93aa1e5bb make sure component slice order corresponds to the type args diff -r 381c828865e7 -r d6b4586b271f rust/hwphysics/src/data.rs --- a/rust/hwphysics/src/data.rs Tue Aug 27 14:37:39 2019 +0200 +++ b/rust/hwphysics/src/data.rs Tue Aug 27 20:09:17 2019 +0300 @@ -3,14 +3,14 @@ any::TypeId, mem::{size_of, MaybeUninit}, num::NonZeroU16, - ptr::{copy_nonoverlapping, NonNull}, + ptr::{copy_nonoverlapping, NonNull, null_mut}, slice, }; pub unsafe trait TypeTuple: Sized { fn len() -> usize; fn get_types(dest: &mut Vec); - unsafe fn iter(slices: &[NonNull], count: usize, mut f: F) + unsafe fn iter(slices: &[*mut u8], count: usize, mut f: F) where F: FnMut(Self); } @@ -24,11 +24,11 @@ dest.push(TypeId::of::()); } - unsafe fn iter(slices: &[NonNull], count: usize, mut f: F) + unsafe fn iter(slices: &[*mut u8], count: usize, mut f: F) where F: FnMut(Self), { - let slice1 = slice::from_raw_parts(slices[0].as_ptr() as *const T, count); + let slice1 = slice::from_raw_parts(slices[0] as *const T, count); for i in 0..count { f((slice1.get_unchecked(i),)); } @@ -254,35 +254,33 @@ } } - fn create_selector(&self, types: &[TypeId]) -> u64 { - let mut selector = 0; - for (i, typ) in self.types.iter().enumerate() { - if types.contains(&typ) { - selector |= 1 << (i as u64) + pub fn iter(&self, mut f: F) { + let mut arg_types = Vec::with_capacity(64); + T::get_types(&mut arg_types); + + let mut type_indices = vec![-1i8; arg_types.len()]; + let mut selector = 0u64; + + for (arg_index, type_id) in arg_types.iter().enumerate() { + match self.types.iter().position(|t| t == type_id) { + Some(i) if selector & 1 << i as u64 != 0 => panic!("Duplicate type"), + Some(i) => { + type_indices[arg_index] = i as i8; + selector &= 1 << i as u64; + }, + None => panic!("Unregistered type") } } - selector - } - pub fn iter(&self, mut f: F) { - let mut types = vec![]; - T::get_types(&mut types); - debug_assert!(types.iter().all(|t| self.types.contains(t))); - - let types_count = types.len(); - let selector = self.create_selector(&types); - - let mut slices = Vec::with_capacity(64); + let mut slices = vec![null_mut(); arg_types.len()]; for (block_index, mask) in self.block_masks.iter().enumerate() { if mask & selector == selector { - slices.clear(); let block = &self.blocks[block_index]; - for (i, ptr_opt) in block.component_blocks.iter().cloned().enumerate() { - if let Some(ptr) = ptr_opt { - slices.push(ptr); - } + for (arg_index, type_index) in type_indices.iter().cloned().enumerate() { + slices[arg_index as usize] = + block.component_blocks[type_index as usize].unwrap().as_ptr() } unsafe {