1use core::mem;
2
3#[allow(dead_code)]
5#[repr(C)]
6#[cfg_attr(target_pointer_width = "64", repr(align(16)))]
7struct ObjectHeader {
8 f1: *mut (),
9 f2: *mut (),
10 #[cfg(feature = "systematic_testing")]
11 f3: *mut (),
12}
13
14const SIZEOF_OBJECT_HEADER: usize = mem::size_of::<ObjectHeader>();
15const OBJECT_ALIGNMENT: usize = mem::align_of::<ObjectHeader>();
16
17pub const fn vsizeof<T>() -> usize {
22 align_up(mem::size_of::<T>() + SIZEOF_OBJECT_HEADER, OBJECT_ALIGNMENT)
24}
25
26const fn align_up(value: usize, alignment: usize) -> usize {
27 assert!(alignment.is_power_of_two());
29 let align_1 = alignment - 1;
30 (value + align_1) & !align_1
31}
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36
37 extern "C" {
38 fn boxcar_vsizeof_info(sizeof_object_header: &mut usize, object_alignment: &mut usize);
39 fn boxcar_vsizeof_examples(
40 bool: &mut usize,
41 i32: &mut usize,
42 voidstar: &mut usize,
43 charx17: &mut usize,
44 );
45 }
46
47 #[test]
48 fn metadata() {
49 let mut sizeof_object_header = 0;
50 let mut object_alignment = 0;
51
52 unsafe {
53 boxcar_vsizeof_info(&mut sizeof_object_header, &mut object_alignment);
54 }
55
56 assert_eq!(sizeof_object_header, SIZEOF_OBJECT_HEADER);
57 assert_eq!(object_alignment, OBJECT_ALIGNMENT)
58 }
59
60 #[test]
61 fn examples() {
62 let mut bool_ = 0;
63 let mut i32_ = 0;
64 let mut voidstar = 0;
65 let mut charx17_ = 0;
66
67 unsafe { boxcar_vsizeof_examples(&mut bool_, &mut i32_, &mut voidstar, &mut charx17_) }
68
69 assert_eq!(bool_, vsizeof::<bool>());
70 assert_eq!(i32_, vsizeof::<i32>());
71 assert_eq!(voidstar, vsizeof::<*mut ()>());
72 assert_eq!(charx17_, vsizeof::<[u8; 17]>());
73 }
74}