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
///! Taken from the ///! [librustc_target](https://github.com/rust-lang/rust/tree/master/src/librustc_target) crate. use super::Size; /// Alignment of a type in bytes (always a power of two). #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub struct Align { pow2: u8, } impl Align { pub fn from_bits(bits: u64) -> Result<Align, String> { Align::from_bytes(Size::from_bits(bits).bytes()) } pub fn from_bytes(align: u64) -> Result<Align, String> { // Treat an alignment of 0 bytes like 1-byte alignment. if align == 0 { return Ok(Align { pow2: 0 }); } let mut bytes = align; let mut pow2: u8 = 0; while (bytes & 1) == 0 { pow2 += 1; bytes >>= 1; } if bytes != 1 { return Err(format!("`{}` is not a power of 2", align)); } if pow2 > 29 { return Err(format!("`{}` is too large", align)); } Ok(Align { pow2 }) } // pub fn bytes(self) -> u64 { // 1 << self.pow2 // } // // pub fn bits(self) -> u64 { // self.bytes() * 8 // } // // /// Computes the best alignment possible for the given offset // /// (the largest power of two that the offset is a multiple of). // /// // /// N.B., for an offset of `0`, this happens to return `2^64`. // pub fn max_for_offset(offset: Size) -> Align { // Align { // pow2: offset.bytes().trailing_zeros() as u8, // } // } // // /// Lower the alignment, if necessary, such that the given offset // /// is aligned to it (the offset is a multiple of the alignment). // pub fn restrict_for_offset(self, offset: Size) -> Align { // self.min(Align::max_for_offset(offset)) // } }