Skip to content

Instantly share code, notes, and snippets.

@lovely-error
Last active March 23, 2025 15:23
Show Gist options
  • Save lovely-error/f8e40be14118d8334b9e68f679996e53 to your computer and use it in GitHub Desktop.
Save lovely-error/f8e40be14118d8334b9e68f679996e53 to your computer and use it in GitHub Desktop.
Separate stride and size in rust
#![feature(decl_macro)]
trait MemLayout where Self:Sized {
// size, excluding trailing padding
fn size() -> usize {
core::mem::size_of::<Self>()
}
/// highest alignment among the members
/// of the product
fn alignment() -> usize;
/// space taken by one instance of this type in linear addressing
fn stride() -> usize {
Self::size().next_multiple_of(Self::alignment())
}
}
macro defstruct_fine_layout(
struct $name:ident {
$($field_name:ident : $ty:ty),*
}
) {
#[repr(packed)]
struct $name {
$($field_name : $ty),*
}
impl MemLayout for $name {
fn alignment() -> usize {
const {
let aligns = [
$(core::mem::align_of::<$ty>()),*
];
// let names = [
// $(stringify!($field_name)),*
// ];
// hint: core::intrinsics::const_allocate ?
if let Some(faulty_member) = check_field_seqv_aligned_ok(aligns) {
let err_msg = concat!(
"Member ",
// stringify!(names[faulty_member]),
"with index ",
stringify!(faulty_member),
" of struct ",
stringify!($name),
" does not follow next member in decreasing alignment order"
);
panic!("{}",err_msg);
}
compute_highest_seqv_alignment(aligns)
}
}
}
}
const fn check_field_seqv_aligned_ok<const LEN:usize>(
aligns: [usize;LEN]
) -> Option<usize> {
let mut current_index = 0;
loop {
if current_index + 1 >= LEN { break }
let this = aligns[current_index];
let next = aligns[current_index + 1];
if this < next { return Some(current_index) }
current_index += 1;
}
return None
}
const fn compute_highest_seqv_alignment<const LEN:usize>(
aligns: [usize;LEN]
) -> usize {
let end_index = LEN;
let mut current_index = 0;
let mut max_align_size = 1;
loop {
if current_index == end_index { break }
let align = aligns[current_index];
if align > max_align_size {
max_align_size = align;
}
current_index += 1;
}
return max_align_size
}
defstruct_fine_layout! {
struct Test {
_m1: u32,
_m2: u16,
_m3: u8
}
}
fn main() {
println!("size is {:?}", Test::size());
println!("alignment is {:?}", Test::alignment());
println!("stride is {:?}", Test::stride());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment