smallbox 0.8.8

`Small Box` optimization: store small item on stack and fallback to heap for large item.
Documentation
use std::ptr;

#[allow(dead_code)]
struct Sample(usize);

trait SomeTrait {
    fn call_me(&self) -> bool {
        true
    }
}

impl SomeTrait for Sample {}

fn layout_broken(what: &str) {
    panic!(
        concat!(
            "Assumptions on layout are broken, this crate relies on ",
            "`unsafe code guidelines` layout specification, ",
            "now layout of {:?} is broken, report about it on github"
        ),
        what
    );
}

/// Tests some layout assumptions, these cases as of now:
///
/// 1. data pointer and vtable pointer location of trait objects
/// 2. data pointer and size location of slice objects
fn test_ptr_layouts() {
    // Test for dyn object
    {
        #[repr(C)]
        struct DynObj {
            data_ptr: *const u8,
            vtable: *const u8,
        }

        let sample = Box::new(Sample(100));
        let data_ptr = Box::into_raw(sample);

        let trait_obj: *const dyn SomeTrait = data_ptr;
        let dyn_obj_repr: DynObj = unsafe { ptr::read(ptr::addr_of!(trait_obj) as *const DynObj) };

        if dyn_obj_repr.data_ptr != data_ptr as *const u8 {
            layout_broken("trait objects");
        }
        let out = unsafe { Box::from_raw(data_ptr) };
        out.call_me();
    }

    // Test for slice object
    {
        let array = [1, 2, 3];
        let slice: &[u8] = &array;

        #[repr(C)]
        struct Slice {
            data_ptr: *const u8,
            size: usize,
        }

        let slice_repr: Slice = unsafe { ptr::read(ptr::addr_of!(slice) as *const Slice) };

        if slice_repr.data_ptr != slice.as_ptr() || slice_repr.size != slice.len() {
            layout_broken("slices");
        }
    }
}

fn main() {
    // NOTE: this will not protect from every possible case,
    // for example, rust may add one more fat pointer type which this test
    // will not check, host layout may be different from target layout,
    // and probably more.
    test_ptr_layouts();
}