4 releases (2 breaking)

0.2.1 May 13, 2020
0.2.0 May 13, 2020
0.1.0 Aug 1, 2019
0.0.0 Jul 11, 2019

#17 in #aligned

Download history 74/week @ 2023-12-18 98/week @ 2023-12-25 258/week @ 2024-01-01 428/week @ 2024-01-08 205/week @ 2024-01-15 160/week @ 2024-01-22 381/week @ 2024-01-29 229/week @ 2024-02-05 211/week @ 2024-02-12 283/week @ 2024-02-19 261/week @ 2024-02-26 240/week @ 2024-03-04 234/week @ 2024-03-11 447/week @ 2024-03-18 506/week @ 2024-03-25 957/week @ 2024-04-01

2,172 downloads per month
Used in 6 crates (4 directly)

MIT/Apache

27KB
536 lines

Maligned

A memory alignment library

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.


lib.rs:

A library for getting aligned vectors, slices, and arrays of bytes or any other type

The A* structs are aligned as indicated and hold a single array of bytes of the same size. These implement the Alignment trait that can be used for always aligned byte arrays for faster memory copies or copies by hardware. The arrays are accessible as slices using as_bytes() or as_bytes_mut() or by dereferencing the struct.

let alignment_256 = A256::default();

assert_eq!(std::mem::size_of::<A256>(), std::mem::size_of_val(alignment_256.as_bytes()));
assert_eq!(alignment_256.as_bytes().as_ptr() as usize % std::mem::size_of::<A256>(), 0);

If you need more than a single Alignment of bytes you can create a vector of them and that can be converted into a normal byte slice that always has the first byte aligned.

let mut v = vec![A512::default(); 100];
assert_eq!(v.as_bytes().len(), std::mem::size_of::<A512>() * 100);
assert_eq!(v.as_bytes().as_ptr() as usize % std::mem::align_of::<A512>(), 0);

v.as_bytes_mut()[512] = 42;
assert_eq!(v[1][0], 42);

There is also a wrapper Aligned that aligns any type to a specified alignment

// aligned() is an alias for Aligned::new()
let a: Aligned<A32, [u8; 24]> = aligned([0; 24]);
assert_eq!(std::mem::align_of_val(&a), 32);
assert_eq!(&*a as *const u8 as usize % std::mem::align_of::<A32>(), 0);

If the alloc feature is enabled (it is by default) then there are a few more functions available. align_first returns an empty Vec with a capacity of at least capacity bytes. Two type parameters are currently required, though the first can be set to _, because of the current interaction between impl traits and generics.

let v: Vec<u8> = align_first::<u8, A256>(1009);
assert_eq!(v.as_ptr() as usize % 256, 0);
assert_eq!(v.capacity(), 1009);

align_first_boxed, align_first_boxed_default, and align_first_boxed_cloned all return a Box<[T]> with the first element aligned to at least Alignment bytes.

// 3 type parameters. The last one should always be _ until impl traits and generics interact better
let boxed: Box<[Option<u128>]> = align_first_boxed::<_, A512, _>(101, |_|Some(42));
let defaulted: Box<[Option<u128>]> = align_first_boxed_default::<_, A128>(101);
let cloned: Box<[Option<u128>]> = align_first_boxed_cloned::<_, Bit512>(101, Some(42));

assert_eq!(&*boxed, &vec![Some(42); 101][..]);
assert_eq!(&boxed, &cloned);
assert_eq!(boxed.len(), 101);
assert_eq!(defaulted.len(), 101);
assert_eq!(cloned.len(), 101);
assert_eq!(&*defaulted, &vec![None; 101][..]);

No runtime deps

Features