mirror of
https://github.com/Noratrieb/stuff.git
synced 2026-01-14 16:35:08 +01:00
This is now a safe interface!
This commit is contained in:
parent
7d95a7dfaf
commit
22aaf91cc1
3 changed files with 10 additions and 14 deletions
|
|
@ -54,6 +54,7 @@ mod backend_size_asserts {
|
||||||
const _: () = assert_same_size::<usize, <usize as Backend>::Stored>();
|
const _: () = assert_same_size::<usize, <usize as Backend>::Stored>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SAFETY: We are careful around provenance
|
||||||
unsafe impl Backend for usize {
|
unsafe impl Backend for usize {
|
||||||
type Stored = *mut ();
|
type Stored = *mut ();
|
||||||
|
|
||||||
|
|
@ -72,6 +73,7 @@ unsafe impl Backend for usize {
|
||||||
|
|
||||||
#[cfg(target_pointer_width = "64")]
|
#[cfg(target_pointer_width = "64")]
|
||||||
/// on 64 bit, we can just treat u64/usize interchangeably, because uintptr_t == size_t in Rust
|
/// on 64 bit, we can just treat u64/usize interchangeably, because uintptr_t == size_t in Rust
|
||||||
|
// SAFETY: We are careful around provenance
|
||||||
unsafe impl Backend for u64 {
|
unsafe impl Backend for u64 {
|
||||||
type Stored = *mut ();
|
type Stored = *mut ();
|
||||||
|
|
||||||
|
|
@ -90,6 +92,7 @@ unsafe impl Backend for u64 {
|
||||||
|
|
||||||
macro_rules! impl_backend_2_tuple {
|
macro_rules! impl_backend_2_tuple {
|
||||||
(impl for $ty:ty { (*mut (), $int:ident), $num:expr }) => {
|
(impl for $ty:ty { (*mut (), $int:ident), $num:expr }) => {
|
||||||
|
// SAFETY: We are careful around provenance
|
||||||
unsafe impl Backend for $ty {
|
unsafe impl Backend for $ty {
|
||||||
// this one keeps the MSB in the pointer address, and the LSB in the integer
|
// this one keeps the MSB in the pointer address, and the LSB in the integer
|
||||||
|
|
||||||
|
|
@ -117,6 +120,7 @@ macro_rules! impl_backend_2_tuple {
|
||||||
#[cfg_attr(target_pointer_width = "64", allow(unused))] // not required on 64 bit
|
#[cfg_attr(target_pointer_width = "64", allow(unused))] // not required on 64 bit
|
||||||
macro_rules! impl_backend_3_tuple {
|
macro_rules! impl_backend_3_tuple {
|
||||||
(impl for $ty:ty { (*mut (), $int1:ident, $int2:ident), $num1:expr, $num2:expr }) => {
|
(impl for $ty:ty { (*mut (), $int1:ident, $int2:ident), $num1:expr, $num2:expr }) => {
|
||||||
|
// SAFETY: We are careful around provenance
|
||||||
unsafe impl Backend for $ty {
|
unsafe impl Backend for $ty {
|
||||||
// this one keeps the MSB in the pointer address, ISB in int1 and the LSB in the int2
|
// this one keeps the MSB in the pointer address, ISB in int1 and the LSB in the int2
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
//! // implementation detail of NaN boxing, the sign bit of an f64
|
//! // implementation detail of NaN boxing, the sign bit of an f64
|
||||||
//! const SIGN_BIT: u64 = 0x8000000000000000;
|
//! const SIGN_BIT: u64 = 0x8000000000000000;
|
||||||
//!
|
//!
|
||||||
//! unsafe impl StuffingStrategy<u64> for NanBoxStrategy {
|
//! impl StuffingStrategy<u64> for NanBoxStrategy {
|
||||||
//! type Other = f64;
|
//! type Other = f64;
|
||||||
//!
|
//!
|
||||||
//! fn stuff_other(inner: Self::Other) -> u64 {
|
//! fn stuff_other(inner: Self::Other) -> u64 {
|
||||||
|
|
|
||||||
|
|
@ -10,15 +10,7 @@ use crate::{Backend, Unstuffed};
|
||||||
/// if possible.
|
/// if possible.
|
||||||
///
|
///
|
||||||
/// The generic parameter `B` stands for the [`Backend`](`crate::Backend`) used by the strategy.
|
/// The generic parameter `B` stands for the [`Backend`](`crate::Backend`) used by the strategy.
|
||||||
///
|
pub trait StuffingStrategy<B> {
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// If [`StuffingStrategy::is_other`] returns true for a value, then
|
|
||||||
/// [`StuffingStrategy::extract_other`] *must* return a valid `Other` for that same value.
|
|
||||||
///
|
|
||||||
/// For [`StuffingStrategy::stuff_ptr`] and [`StuffingStrategy::extract_ptr`],
|
|
||||||
/// `ptr == extract_ptr(stuff_ptr(ptr))` *must* hold true.
|
|
||||||
pub unsafe trait StuffingStrategy<B> {
|
|
||||||
/// The type of the other.
|
/// The type of the other.
|
||||||
type Other: Copy;
|
type Other: Copy;
|
||||||
|
|
||||||
|
|
@ -40,7 +32,7 @@ pub unsafe trait StuffingStrategy<B> {
|
||||||
fn stuff_ptr(addr: usize) -> B;
|
fn stuff_ptr(addr: usize) -> B;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<B> StuffingStrategy<B> for ()
|
impl<B> StuffingStrategy<B> for ()
|
||||||
where
|
where
|
||||||
B: Backend + Default + TryInto<usize>,
|
B: Backend + Default + TryInto<usize>,
|
||||||
usize: TryInto<B>,
|
usize: TryInto<B>,
|
||||||
|
|
@ -75,7 +67,7 @@ pub(crate) mod test_strategies {
|
||||||
macro_rules! impl_usize_max_zst {
|
macro_rules! impl_usize_max_zst {
|
||||||
($ty:ident) => {
|
($ty:ident) => {
|
||||||
// this one lives in usize::MAX
|
// this one lives in usize::MAX
|
||||||
unsafe impl StuffingStrategy<usize> for $ty {
|
impl StuffingStrategy<usize> for $ty {
|
||||||
type Other = Self;
|
type Other = Self;
|
||||||
|
|
||||||
#[allow(clippy::forget_copy)]
|
#[allow(clippy::forget_copy)]
|
||||||
|
|
@ -96,7 +88,7 @@ pub(crate) mod test_strategies {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl StuffingStrategy<u64> for $ty {
|
impl StuffingStrategy<u64> for $ty {
|
||||||
type Other = Self;
|
type Other = Self;
|
||||||
|
|
||||||
#[allow(clippy::forget_copy)]
|
#[allow(clippy::forget_copy)]
|
||||||
|
|
@ -117,7 +109,7 @@ pub(crate) mod test_strategies {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl StuffingStrategy<u128> for $ty {
|
impl StuffingStrategy<u128> for $ty {
|
||||||
type Other = Self;
|
type Other = Self;
|
||||||
|
|
||||||
#[allow(clippy::forget_copy)]
|
#[allow(clippy::forget_copy)]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue