impl more traits for ptr::Alignment, add mask method
This commit is contained in:
parent
547ace8051
commit
114873dc19
@ -42,6 +42,7 @@ impl Alignment {
|
|||||||
/// This provides the same numerical value as [`mem::align_of`],
|
/// This provides the same numerical value as [`mem::align_of`],
|
||||||
/// but in an `Alignment` instead of a `usize`.
|
/// but in an `Alignment` instead of a `usize`.
|
||||||
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
|
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
|
||||||
|
#[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn of<T>() -> Self {
|
pub const fn of<T>() -> Self {
|
||||||
// SAFETY: rustc ensures that type alignment is always a power of two.
|
// SAFETY: rustc ensures that type alignment is always a power of two.
|
||||||
@ -53,6 +54,7 @@ pub const fn of<T>() -> Self {
|
|||||||
///
|
///
|
||||||
/// Note that `0` is not a power of two, nor a valid alignment.
|
/// Note that `0` is not a power of two, nor a valid alignment.
|
||||||
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
|
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
|
||||||
|
#[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn new(align: usize) -> Option<Self> {
|
pub const fn new(align: usize) -> Option<Self> {
|
||||||
if align.is_power_of_two() {
|
if align.is_power_of_two() {
|
||||||
@ -98,6 +100,7 @@ pub const fn as_usize(self) -> usize {
|
|||||||
|
|
||||||
/// Returns the alignment as a [`NonZeroUsize`]
|
/// Returns the alignment as a [`NonZeroUsize`]
|
||||||
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
|
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
|
||||||
|
#[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn as_nonzero(self) -> NonZeroUsize {
|
pub const fn as_nonzero(self) -> NonZeroUsize {
|
||||||
// SAFETY: All the discriminants are non-zero.
|
// SAFETY: All the discriminants are non-zero.
|
||||||
@ -118,10 +121,42 @@ pub const fn as_nonzero(self) -> NonZeroUsize {
|
|||||||
/// assert_eq!(Alignment::new(1024).unwrap().log2(), 10);
|
/// assert_eq!(Alignment::new(1024).unwrap().log2(), 10);
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
|
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
|
||||||
|
#[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn log2(self) -> u32 {
|
pub const fn log2(self) -> u32 {
|
||||||
self.as_nonzero().trailing_zeros()
|
self.as_nonzero().trailing_zeros()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a bit mask that can be used to match this alignment.
|
||||||
|
///
|
||||||
|
/// This is equivalent to `!(self.as_usize() - 1)`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(ptr_alignment_type)]
|
||||||
|
/// #![feature(ptr_mask)]
|
||||||
|
/// use std::ptr::{Alignment, NonNull};
|
||||||
|
///
|
||||||
|
/// #[repr(align(1))] struct Align1(u8);
|
||||||
|
/// #[repr(align(2))] struct Align2(u16);
|
||||||
|
/// #[repr(align(4))] struct Align4(u32);
|
||||||
|
/// let one = <NonNull<Align1>>::dangling().as_ptr();
|
||||||
|
/// let two = <NonNull<Align2>>::dangling().as_ptr();
|
||||||
|
/// let four = <NonNull<Align4>>::dangling().as_ptr();
|
||||||
|
///
|
||||||
|
/// assert_eq!(four.mask(Alignment::of::<Align1>().mask()), four);
|
||||||
|
/// assert_eq!(four.mask(Alignment::of::<Align2>().mask()), four);
|
||||||
|
/// assert_eq!(four.mask(Alignment::of::<Align4>().mask()), four);
|
||||||
|
/// assert_ne!(one.mask(Alignment::of::<Align4>().mask()), one);
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
|
||||||
|
#[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")]
|
||||||
|
#[inline]
|
||||||
|
pub const fn mask(self) -> usize {
|
||||||
|
// SAFETY: The alignment is always nonzero, and therefore decrementing won't overflow.
|
||||||
|
!(unsafe { self.as_usize().unchecked_sub(1) })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
|
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
|
||||||
@ -193,6 +228,14 @@ fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns [`Alignment::MIN`], which is valid for any type.
|
||||||
|
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
|
||||||
|
impl Default for Alignment {
|
||||||
|
fn default() -> Alignment {
|
||||||
|
Alignment::MIN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_pointer_width = "16")]
|
#[cfg(target_pointer_width = "16")]
|
||||||
type AlignmentEnum = AlignmentEnum16;
|
type AlignmentEnum = AlignmentEnum16;
|
||||||
#[cfg(target_pointer_width = "32")]
|
#[cfg(target_pointer_width = "32")]
|
||||||
|
Loading…
Reference in New Issue
Block a user