# HG changeset patch # User alfadur # Date 1566939863 -10800 # Node ID 445138f388d46b4cb7fed7b269ccd4d3f2f5101e # Parent d6b4586b271f1189d9ec6d9dd15b1fd9939ed77a expand iteration implementation to larger tuples diff -r d6b4586b271f -r 445138f388d4 rust/hwphysics/src/data.rs --- a/rust/hwphysics/src/data.rs Tue Aug 27 20:09:17 2019 +0300 +++ b/rust/hwphysics/src/data.rs Wed Aug 28 00:04:23 2019 +0300 @@ -3,38 +3,64 @@ any::TypeId, mem::{size_of, MaybeUninit}, num::NonZeroU16, - ptr::{copy_nonoverlapping, NonNull, null_mut}, + ptr::{copy_nonoverlapping, null_mut, NonNull}, slice, }; -pub unsafe trait TypeTuple: Sized { +pub trait TypeTuple: Sized { fn len() -> usize; fn get_types(dest: &mut Vec); - unsafe fn iter(slices: &[*mut u8], count: usize, mut f: F) - where - F: FnMut(Self); + unsafe fn iter(slices: &[*mut u8], count: usize, mut f: F); } -unsafe impl TypeTuple for (&T,) { - fn len() -> usize { - 1 - } +macro_rules! type_typle_impl { + ($($n: literal: $t: ident),*) => { + impl<$($t: 'static),*> TypeTuple for ($(&$t),*,) { + fn len() -> usize { + [$({TypeId::of::<$t>(); 1}),*].iter().sum() + } + + fn get_types(types: &mut Vec) { + $(types.push(TypeId::of::<$t>()));* + } - fn get_types(dest: &mut Vec) { - dest.push(TypeId::of::()); - } + unsafe fn iter(slices: &[*mut u8], count: usize, mut f: F) + { + for i in 0..count { + unsafe { + f(($(&*(*slices.get_unchecked($n) as *mut $t).add(i)),*,)); + } + } + } + } - unsafe fn iter(slices: &[*mut u8], count: usize, mut f: F) - where - F: FnMut(Self), - { - let slice1 = slice::from_raw_parts(slices[0] as *const T, count); - for i in 0..count { - f((slice1.get_unchecked(i),)); + impl<$($t: 'static),*> TypeTuple for ($(&mut $t),*,) { + fn len() -> usize { + [$({TypeId::of::<$t>(); 1}),*].iter().sum() + } + + fn get_types(types: &mut Vec) { + $(types.push(TypeId::of::<$t>()));* + } + + unsafe fn iter(slices: &[*mut u8], count: usize, mut f: F) + { + for i in 0..count { + unsafe { + f(($(&mut *(*slices.get_unchecked($n) as *mut $t).add(i)),*,)); + } + } + } } } } +type_typle_impl!(0: A); +type_typle_impl!(0: A, 1: B); +type_typle_impl!(0: A, 1: B, 2: C); +type_typle_impl!(0: A, 1: B, 2: C, 3: D); +type_typle_impl!(0: A, 1: B, 2: C, 3: D, 4: E); + const BLOCK_SIZE: usize = 32768; struct DataBlock { @@ -267,8 +293,8 @@ Some(i) => { type_indices[arg_index] = i as i8; selector &= 1 << i as u64; - }, - None => panic!("Unregistered type") + } + None => panic!("Unregistered type"), } } @@ -279,8 +305,9 @@ let block = &self.blocks[block_index]; 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() + slices[arg_index as usize] = block.component_blocks[type_index as usize] + .unwrap() + .as_ptr() } unsafe { @@ -312,7 +339,10 @@ let mut sum = 0; manager.iter(|(d,): (&Datum,)| sum += d.value); + assert_eq!(sum, 15); - assert_eq!(sum, 15); + manager.iter(|(d,): (&mut Datum,)| d.value += 1); + manager.iter(|(d,): (&Datum,)| sum += d.value); + assert_eq!(sum, 35); } }