diff options
author | Nathan Ringo <nathan@remexre.com> | 2024-08-31 20:23:24 -0500 |
---|---|---|
committer | Nathan Ringo <nathan@remexre.com> | 2024-08-31 20:23:24 -0500 |
commit | e9a79a0ed79609c1e293c7b221fce577200b2eb7 (patch) | |
tree | e097115f4b4435caa2a26186652cbfffefb2cb28 /crates/utils | |
parent | 4617f96a99c0e5dfac1b45b3cff037306e4edc63 (diff) |
The start of a new librarified organization.
Diffstat (limited to 'crates/utils')
-rw-r--r-- | crates/utils/Cargo.toml | 8 | ||||
-rw-r--r-- | crates/utils/src/lib.rs | 3 | ||||
-rw-r--r-- | crates/utils/src/pin.rs | 25 |
3 files changed, 36 insertions, 0 deletions
diff --git a/crates/utils/Cargo.toml b/crates/utils/Cargo.toml new file mode 100644 index 0000000..5b55a5c --- /dev/null +++ b/crates/utils/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "vernos_utils" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] +contracts = { version = "0.6.3", default-features = false } diff --git a/crates/utils/src/lib.rs b/crates/utils/src/lib.rs new file mode 100644 index 0000000..57143bc --- /dev/null +++ b/crates/utils/src/lib.rs @@ -0,0 +1,3 @@ +//! Common utilities. + +pub mod pin; diff --git a/crates/utils/src/pin.rs b/crates/utils/src/pin.rs new file mode 100644 index 0000000..202904d --- /dev/null +++ b/crates/utils/src/pin.rs @@ -0,0 +1,25 @@ +//! Utilities having to do with pinning. I sure hope these are sound! + +use contracts::requires; +use core::pin::Pin; +use std::ptr::NonNull; + +/// Iterates over projections of elements out of a pinned slice. +pub fn pin_project_slice_mut_iter<T>(slice: Pin<&mut [T]>) -> impl Iterator<Item = Pin<&mut T>> { + let base_ptr: NonNull<T> = NonNull::from(slice.as_ref().get_ref()).cast(); + (0..slice.len()).map(move |i| { + // SAFETY: This is in-bounds, since the original slice was valid. No other references to + // the data can exist, since we visit each index once and have an exclusive borrow on the + // slice. + let ptr = unsafe { base_ptr.add(i).as_mut() }; + // SAFETY: This is not certainly sound; see https://github.com/rust-lang/rust/issues/104108 + unsafe { Pin::new_unchecked(ptr) } + }) +} + +/// Projects a single element out of a pinned slice. +#[requires(index < slice.len())] +pub fn pin_project_slice_mut<T>(slice: Pin<&mut [T]>, index: usize) -> Pin<&mut T> { + // SAFETY: This is not certainly sound; see https://github.com/rust-lang/rust/issues/104108 + unsafe { slice.map_unchecked_mut(|slice| &mut slice[index]) } +} |