diff options
Diffstat (limited to 'zjit/src/cast.rs')
| -rw-r--r-- | zjit/src/cast.rs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/zjit/src/cast.rs b/zjit/src/cast.rs new file mode 100644 index 0000000000..52e2078cde --- /dev/null +++ b/zjit/src/cast.rs @@ -0,0 +1,64 @@ +//! Optimized [usize] casting trait. + +#![allow(clippy::wrong_self_convention)] + +/// Trait for casting to [usize] that allows you to say `.as_usize()`. +/// Implementation conditional on the cast preserving the numeric value on +/// all inputs and being inexpensive. +/// +/// [usize] is only guaranteed to be more than 16-bit wide, so we can't use +/// `.into()` to cast an `u32` or an `u64` to a `usize` even though in all +/// the platforms we support these casts are pretty much no-ops. +/// We could say `as usize` or `.try_convert().unwrap()` everywhere for these +/// casts but both options have undesirable consequences if and when we decide to +/// support 32-bit platforms. Unfortunately we can't implement [::core::convert::From] +/// for [usize] since both the trait and the type are external. Also, naming +/// the method `into()` also causes a name conflict. +pub(crate) trait IntoUsize { + /// Convert to usize. Implementation conditional on width of [usize]. + fn to_usize(self) -> usize; +} + +#[cfg(target_pointer_width = "64")] +impl IntoUsize for u64 { + fn to_usize(self) -> usize { + self as usize + } +} + +#[cfg(target_pointer_width = "64")] +impl IntoUsize for u32 { + fn to_usize(self) -> usize { + self as usize + } +} + +impl IntoUsize for u16 { + /// Alias for `.into()`. For convenience so you could use the trait for + /// all unsgined types. + fn to_usize(self) -> usize { + self.into() + } +} + +impl IntoUsize for u8 { + /// Alias for `.into()`. For convenience so you could use the trait for + /// all unsgined types. + fn to_usize(self) -> usize { + self.into() + } +} + +/// The `Into<u64>` Rust does not provide. +/// Convert to u64 with assurance that the value is preserved. +/// Currently, `usize::BITS == 64` holds for all platforms we support. +pub(crate) trait IntoU64 { + fn as_u64(self) -> u64; +} + +#[cfg(target_pointer_width = "64")] +impl IntoU64 for usize { + fn as_u64(self) -> u64 { + self as u64 + } +} |
