1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
//! 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](align::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()](align::AsBytes::as_bytes) or //! [as_bytes_mut()](align::AsBytesMut::as_bytes_mut) or by dereferencing the struct. //! ``` //! # use maligned::*; //! 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](align::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. //! //! ``` //! # use maligned::*; //! 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](align::Aligned) that aligns any type to a specified alignment //! ``` //! # use maligned::*; //! // 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](heap::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. //! ``` //! # use maligned::*; //! 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](heap::align_first_boxed), [align_first_boxed_default](heap::align_first_boxed_default), //! and [align_first_boxed_cloned](heap::align_first_boxed_cloned) all return a [Box<\[T\]>](alloc::boxed::Box) with the //! first element aligned to at least [Alignment](align::Alignment) bytes. //! ``` //! # use maligned::*; //! // 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_std] #![cfg_attr(all(not(test), feature = "clippy"), deny(warnings, clippy::all, clippy::pedantic))] #![deny(unsafe_code, missing_docs)] #![allow(clippy::doc_markdown)] #[cfg(feature = "alloc")] extern crate alloc; #[cfg(test)] #[macro_use] extern crate std; mod align; pub use align::*; #[cfg(feature = "alloc")] mod heap; #[cfg(feature = "alloc")] pub use heap::*; /// allow * imports pub mod prelude { pub use super::*; }