use reg_map::RegMap; #[repr(C)] #[derive(RegMap, Default)] pub struct Simple { field1: u64, field2: u64, } #[repr(C)] #[derive(RegMap)] struct Nested { field1: u64, field2: NestedInner, } #[repr(C)] #[derive(RegMap)] struct NestedInner { inner1: u64, } #[repr(C)] #[derive(RegMap, Default)] struct Array { field1: u64, field2: [u64; 32], } #[repr(C)] #[derive(RegMap)] struct MixedU { one: u8, two: u16, four: u32, eight: u64, sixteen: u128, } #[repr(C)] #[derive(RegMap)] struct MixedI { one: i8, two: i16, four: i32, eight: i64, sixteen: i128, } #[repr(C)] #[derive(RegMap)] struct MixedReverse { sixteen: u128, eight: u64, four: u32, two: u16, one: u8, } const LENGTH: usize = 2; #[repr(C)] #[derive(RegMap, Default)] struct ComplexArray { field1: [SubArray; LENGTH * 2], } #[repr(C)] #[derive(RegMap, Default)] struct SubArray { field1: u64, } #[repr(C)] #[derive(RegMap, Default)] struct CAOuter { outer: [CAInner; 7], } #[repr(C)] #[derive(RegMap, Default)] struct CAInner { inner: [u64; 11], } #[repr(C)] #[derive(RegMap, Default)] struct Array4d { data: [[[[u64; 2]; 3]; 5]; 7], } #[repr(C)] #[derive(RegMap, Default)] struct Array4dComplex { data: [[[[Simple; 2]; 3]; 5]; 7], } #[test] fn simple() { let mut regs = Simple { field1: 23, field2: 45, }; let ptr = SimplePtr::from_mut(&mut regs); assert_eq!(ptr.field1().read(), 23); assert_eq!(ptr.field2().read(), 45); ptr.field1().write(32); ptr.field2().write(54); assert_eq!(ptr.field1().read(), 32); assert_eq!(ptr.field2().read(), 54); assert_eq!(regs.field1, 32); assert_eq!(regs.field2, 54); } #[test] fn nested() { let mut regs = Nested { field1: 1, field2: NestedInner { inner1: 2 }, }; let ptr = NestedPtr::from_mut(&mut regs); assert_eq!(ptr.field1().read(), 1); assert_eq!(ptr.field2().inner1().read(), 2); ptr.field1().write(10); ptr.field2().inner1().write(20); assert_eq!(ptr.field1().read(), 10); assert_eq!(ptr.field2().inner1().read(), 20); assert_eq!(regs.field1, 10); assert_eq!(regs.field2.inner1, 20); } #[test] fn array_idx() { let mut regs = Array::default(); let ptr = ArrayPtr::from_mut(&mut regs); assert_eq!(ptr.field2().len(), 32); ptr.field1().write(42); for i in 0..ptr.field2().len() { ptr.field2().idx(i).write(i as u64 * 2 + 1); } assert_eq!(ptr.field1().read(), 42); for i in 0..ptr.field2().len() { assert_eq!(ptr.field2().idx(i).read(), i as u64 * 2 + 1); } assert_eq!(regs.field1, 42); for (i, v) in regs.field2.into_iter().enumerate() { assert_eq!(v, i as u64 * 2 + 1); } } #[test] fn array_iter() { let mut regs = Array::default(); let ptr = ArrayPtr::from_mut(&mut regs); assert_eq!(ptr.field2().len(), 32); ptr.field1().write(42); for (i, elem) in ptr.field2().iter().enumerate() { elem.write(i as u64 * 2 + 1); } assert_eq!(ptr.field1().read(), 42); for (i, elem) in ptr.field2().iter().enumerate() { assert_eq!(elem.read(), i as u64 * 2 + 1); } assert_eq!(regs.field1, 42); for (i, v) in regs.field2.into_iter().enumerate() { assert_eq!(v, i as u64 * 2 + 1); } } #[test] fn mixed() { let mut regs_u = MixedU { one: 1, two: 2, four: 4, eight: 8, sixteen: 16, }; let mut regs_i = MixedI { one: -1, two: -2, four: -4, eight: -8, sixteen: -16, }; let ptr_u = MixedUPtr::from_mut(&mut regs_u); let ptr_i = MixedIPtr::from_mut(&mut regs_i); assert_eq!(ptr_u.one().read(), 1u8); assert_eq!(ptr_u.two().read(), 2u16); assert_eq!(ptr_u.four().read(), 4u32); assert_eq!(ptr_u.eight().read(), 8u64); assert_eq!(ptr_u.sixteen().read(), 16u128); assert_eq!(ptr_i.one().read(), -1i8); assert_eq!(ptr_i.two().read(), -2i16); assert_eq!(ptr_i.four().read(), -4i32); assert_eq!(ptr_i.eight().read(), -8i64); assert_eq!(ptr_i.sixteen().read(), -16i128); ptr_u.one().write(10u8); ptr_u.two().write(20u16); ptr_u.four().write(40u32); ptr_u.eight().write(80u64); ptr_u.sixteen().write(160u128); ptr_i.one().write(-10i8); ptr_i.two().write(-20i16); ptr_i.four().write(-40i32); ptr_i.eight().write(-80i64); ptr_i.sixteen().write(-160i128); assert_eq!(ptr_u.one().read(), 10u8); assert_eq!(ptr_u.two().read(), 20u16); assert_eq!(ptr_u.four().read(), 40u32); assert_eq!(ptr_u.eight().read(), 80u64); assert_eq!(ptr_u.sixteen().read(), 160u128); assert_eq!(ptr_i.one().read(), -10i8); assert_eq!(ptr_i.two().read(), -20i16); assert_eq!(ptr_i.four().read(), -40i32); assert_eq!(ptr_i.eight().read(), -80i64); assert_eq!(ptr_i.sixteen().read(), -160i128); assert_eq!(regs_u.one, 10u8); assert_eq!(regs_u.two, 20u16); assert_eq!(regs_u.four, 40u32); assert_eq!(regs_u.eight, 80u64); assert_eq!(regs_u.sixteen, 160u128); assert_eq!(regs_i.one, -10i8); assert_eq!(regs_i.two, -20i16); assert_eq!(regs_i.four, -40i32); assert_eq!(regs_i.eight, -80i64); assert_eq!(regs_i.sixteen, -160i128); } #[test] fn mixed_reverse() { let mut regs = MixedReverse { one: 1, two: 2, four: 4, eight: 8, sixteen: 16, }; let ptr = MixedReversePtr::from_mut(&mut regs); assert_eq!(ptr.one().read(), 1u8); assert_eq!(ptr.two().read(), 2u16); assert_eq!(ptr.four().read(), 4u32); assert_eq!(ptr.eight().read(), 8u64); assert_eq!(ptr.sixteen().read(), 16u128); ptr.one().write(10u8); ptr.two().write(20u16); ptr.four().write(40u32); ptr.eight().write(80u64); ptr.sixteen().write(160u128); assert_eq!(ptr.one().read(), 10u8); assert_eq!(ptr.two().read(), 20u16); assert_eq!(ptr.four().read(), 40u32); assert_eq!(ptr.eight().read(), 80u64); assert_eq!(ptr.sixteen().read(), 160u128); assert_eq!(regs.one, 10u8); assert_eq!(regs.two, 20u16); assert_eq!(regs.four, 40u32); assert_eq!(regs.eight, 80u64); assert_eq!(regs.sixteen, 160u128); } #[test] fn leak() { let ptr = { let regs = Box::new(Simple::default()); let ptr = SimplePtr::from_mut(Box::leak(regs)); ptr.field1().write(2); ptr }; assert_eq!(ptr.field1().read(), 2); let regs = unsafe { let raw = ptr.as_ptr(); #[allow(clippy::drop_non_drop)] drop(ptr); Box::from_raw(raw) }; drop(regs); } #[test] fn complex_array_idx() { let mut regs = ComplexArray::default(); let ptr = ComplexArrayPtr::from_mut(&mut regs); for i in 0..ptr.field1().len() { ptr.field1().idx(i).field1().write(1 << i); } for i in 0..ptr.field1().len() { assert_eq!(ptr.field1().idx(i).field1().read(), 1 << i); } for (i, v) in regs.field1.iter().enumerate() { assert_eq!(v.field1, 1 << i); } } #[test] fn complex_array_iter() { let mut regs = ComplexArray::default(); let ptr = ComplexArrayPtr::from_mut(&mut regs); for (i, elem) in ptr.field1().iter().enumerate() { elem.field1().write(1 << i); } for (i, elem) in ptr.field1().iter().enumerate() { assert_eq!(elem.field1().read(), 1 << i); } for (i, v) in regs.field1.iter().enumerate() { assert_eq!(v.field1, 1 << i); } } #[test] fn complex_array_slice() { let mut regs = ComplexArray::default(); let ptr = ComplexArrayPtr::from_mut(&mut regs); for (i, elem) in ptr.field1().iter_slice(0, 4).enumerate() { elem.field1().write(1 << i); } for (i, elem) in ptr.field1().iter_slice(0, 4).enumerate() { assert_eq!(elem.field1().read(), 1 << i); } for (i, v) in regs.field1.iter().enumerate() { assert_eq!(v.field1, 1 << i); } } #[test] fn nested_complex_array_idx() { let mut regs = CAOuter::default(); let ptr = CAOuterPtr::from_mut(&mut regs); let outer = ptr.outer(); for i in 0..outer.len() { let inner = outer.idx(i).inner(); for j in 0..inner.len() { inner.idx(j).write(((i as u64) << 32) + j as u64); } } let outer = ptr.outer(); for i in 0..outer.len() { let inner = outer.idx(i).inner(); for j in 0..inner.len() { assert_eq!(inner.idx(j).read(), ((i as u64) << 32) + j as u64); } } for (i, outer) in regs.outer.iter().enumerate() { for (j, &inner) in outer.inner.iter().enumerate() { assert_eq!(inner, ((i as u64) << 32) + j as u64); } } } #[test] fn nested_complex_array_iter() { let mut regs = CAOuter::default(); let ptr = CAOuterPtr::from_mut(&mut regs); for (i, outer) in ptr.outer().iter().enumerate() { for (j, inner) in outer.inner().iter().enumerate() { inner.write(((i as u64) << 32) + j as u64); } } for (i, outer) in ptr.outer().iter().enumerate() { for (j, inner) in outer.inner().iter().enumerate() { assert_eq!(inner.read(), ((i as u64) << 32) + j as u64); } } for (i, outer) in regs.outer.iter().enumerate() { for (j, &inner) in outer.inner.iter().enumerate() { assert_eq!(inner, ((i as u64) << 32) + j as u64); } } } #[test] fn nested_complex_array_slice() { let mut regs = CAOuter::default(); let ptr = CAOuterPtr::from_mut(&mut regs); for (i, outer) in ptr.outer().iter_slice(1, 6).enumerate() { for (j, inner) in outer.inner().iter_slice(2, 9).enumerate() { inner.write(((i as u64) << 32) + j as u64); } } for (i, outer) in ptr.outer().iter_slice(1, 6).enumerate() { for (j, inner) in outer.inner().iter_slice(2, 9).enumerate() { assert_eq!(inner.read(), ((i as u64) << 32) + j as u64); } } for (i, outer) in regs.outer[1..6].iter().enumerate() { for (j, &inner) in outer.inner[2..9].iter().enumerate() { assert_eq!(inner, ((i as u64) << 32) + j as u64); } } } #[test] fn let_iter_regarr() { let mut regs = Array::default(); let ptr = ArrayPtr::from_mut(&mut regs); let mut it = ptr.field2().iter(); for i in 0..ptr.field2().len() { it.next().unwrap().write(i as u64 * 2 + 1); } assert!(it.next().is_none()); for (i, elem) in ptr.field2().iter().enumerate() { assert_eq!(elem.read(), i as u64 * 2 + 1); } } #[test] fn let_iter_ptrarr() { let mut regs = ComplexArray::default(); let ptr = ComplexArrayPtr::from_mut(&mut regs); let mut it = ptr.field1().iter(); for i in 0..ptr.field1().len() { it.next().unwrap().field1().write(i as u64 * 2 + 1); } assert!(it.next().is_none()); for (i, elem) in ptr.field1().iter().enumerate() { assert_eq!(elem.field1().read(), i as u64 * 2 + 1); } } #[test] fn array_4d() { let mut regs = Array4d::default(); let dim0 = regs.data.len(); let dim1 = regs.data[0].len(); let dim2 = regs.data[0][0].len(); let dim3 = regs.data[0][0][0].len(); let ptr = Array4dPtr::from_mut(&mut regs); assert_eq!(ptr.data().len(), dim0); for (i, a) in ptr.data().iter().enumerate() { assert_eq!(a.len(), dim1); for (j, b) in a.iter().enumerate() { assert_eq!(b.len(), dim2); for (k, c) in b.iter().enumerate() { assert_eq!(c.len(), dim3); for (m, d) in c.iter().enumerate() { assert_eq!(d.read(), 0); d.write((i * dim1 + j * dim2 + k * dim3 + m) as u64); } } } } for (i, a) in ptr.data().iter().enumerate() { for (j, b) in a.iter().enumerate() { for (k, c) in b.iter().enumerate() { for (m, d) in c.iter().enumerate() { assert_eq!(d.read(), (i * dim1 + j * dim2 + k * dim3 + m) as u64); } } } } for (i, a) in regs.data.iter().enumerate() { for (j, b) in a.iter().enumerate() { for (k, c) in b.iter().enumerate() { for (m, d) in c.iter().enumerate() { assert_eq!(*d, (i * dim1 + j * dim2 + k * dim3 + m) as u64); } } } } } #[test] fn array_4d_complex() { let mut regs = Array4dComplex::default(); let dim0 = regs.data.len(); let dim1 = regs.data[0].len(); let dim2 = regs.data[0][0].len(); let dim3 = regs.data[0][0][0].len(); let ptr = Array4dComplexPtr::from_mut(&mut regs); assert_eq!(ptr.data().len(), dim0); for (i, a) in ptr.data().iter().enumerate() { assert_eq!(a.len(), dim1); for (j, b) in a.iter().enumerate() { assert_eq!(b.len(), dim2); for (k, c) in b.iter().enumerate() { assert_eq!(c.len(), dim3); for (m, d) in c.iter().enumerate() { let field1 = d.field1(); let field2 = d.field2(); assert_eq!(field1.read(), 0); assert_eq!(field2.read(), 0); field1.write((i * dim1 + j * dim2 + k * dim3 + m) as u64); field2.write(!(i * dim1 + j * dim2 + k * dim3 + m) as u64); } } } } for (i, a) in ptr.data().iter().enumerate() { for (j, b) in a.iter().enumerate() { for (k, c) in b.iter().enumerate() { for (m, d) in c.iter().enumerate() { let field1 = d.field1(); let field2 = d.field2(); assert_eq!(field1.read(), (i * dim1 + j * dim2 + k * dim3 + m) as u64); assert_eq!(field2.read(), !(i * dim1 + j * dim2 + k * dim3 + m) as u64); } } } } for (i, a) in regs.data.iter().enumerate() { for (j, b) in a.iter().enumerate() { for (k, c) in b.iter().enumerate() { for (m, d) in c.iter().enumerate() { assert_eq!(d.field1, (i * dim1 + j * dim2 + k * dim3 + m) as u64); assert_eq!(d.field2, !(i * dim1 + j * dim2 + k * dim3 + m) as u64); } } } } }