-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f937b96
commit 627c5de
Showing
8 changed files
with
142 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
/// A wrapper around a raw non-null `*mut T` that indicates that the possessor | ||
/// of this wrapper owns the referent. Useful for building abstractions like | ||
/// `Box<T>`, `Vec<T>`, `String`, and `HashMap<K, V>`. | ||
/// | ||
/// Unlike `*mut T`, `Unique<T>` behaves "as if" it were an instance of `T`. | ||
/// It implements `Send`/`Sync` if `T` is `Send`/`Sync`. It also implies | ||
/// the kind of strong aliasing guarantees an instance of `T` can expect: | ||
/// the referent of the pointer should not be modified without a unique path to | ||
/// its owning Unique. | ||
/// | ||
/// If you're uncertain of whether it's correct to use `Unique` for your purposes, | ||
/// consider using `NonNull`, which has weaker semantics. | ||
/// | ||
/// Unlike `*mut T`, the pointer must always be non-null, even if the pointer | ||
/// is never dereferenced. This is so that enums may use this forbidden value | ||
/// as a discriminant -- `Option<Unique<T>>` has the same size as `Unique<T>`. | ||
/// However the pointer may still dangle if it isn't dereferenced. | ||
/// | ||
/// Unlike `*mut T`, `Unique<T>` is covariant over `T`. This should always be correct | ||
/// for any type which upholds Unique's aliasing requirements. | ||
#[repr(transparent)] | ||
pub(crate) struct Unique<T: ?Sized> { | ||
pointer: NonNull<T>, | ||
_marker: PhantomData<T>, | ||
} | ||
|
||
/// `Unique` pointers are `Send` if `T` is `Send` because the data they | ||
/// reference is unaliased. Note that this aliasing invariant is | ||
/// unenforced by the type system; the abstraction using the | ||
/// `Unique` must enforce it. | ||
unsafe impl<T: Send + ?Sized> Send for Unique<T> {} | ||
|
||
/// `Unique` pointers are `Sync` if `T` is `Sync` because the data they | ||
/// reference is unaliased. Note that this aliasing invariant is | ||
/// unenforced by the type system; the abstraction using the | ||
/// `Unique` must enforce it. | ||
unsafe impl<T: Sync + ?Sized> Sync for Unique<T> {} | ||
|
||
impl<T: ?Sized> Unique<T> { | ||
/// Creates a new `Unique`. | ||
/// | ||
/// # Safety | ||
/// | ||
/// `ptr` must be non-null. | ||
#[inline] | ||
pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { | ||
// SAFETY: the caller must guarantee that `ptr` is non-null. | ||
unsafe { | ||
Unique { | ||
pointer: NonNull::new_unchecked(ptr), | ||
_marker: PhantomData, | ||
} | ||
} | ||
} | ||
|
||
/// Acquires the underlying `*mut` pointer. | ||
#[must_use = "`self` will be dropped if the result is not used"] | ||
#[inline] | ||
pub const fn as_ptr(self) -> *mut T { | ||
self.pointer.as_ptr() | ||
} | ||
|
||
/// Acquires the underlying `*mut` pointer. | ||
#[must_use = "`self` will be dropped if the result is not used"] | ||
#[inline] | ||
pub const fn as_non_null_ptr(self) -> NonNull<T> { | ||
self.pointer | ||
} | ||
|
||
/// Dereferences the content. | ||
/// | ||
/// The resulting lifetime is bound to self so this behaves "as if" | ||
/// it were actually an instance of T that is getting borrowed. If a longer | ||
/// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`. | ||
#[must_use] | ||
#[inline] | ||
pub const unsafe fn as_ref(&self) -> &T { | ||
// SAFETY: the caller must guarantee that `self` meets all the | ||
// requirements for a reference. | ||
unsafe { self.pointer.as_ref() } | ||
} | ||
|
||
/// Mutably dereferences the content. | ||
/// | ||
/// The resulting lifetime is bound to self so this behaves "as if" | ||
/// it were actually an instance of T that is getting borrowed. If a longer | ||
/// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`. | ||
#[must_use] | ||
#[inline] | ||
pub unsafe fn as_mut(&mut self) -> &mut T { | ||
// SAFETY: the caller must guarantee that `self` meets all the | ||
// requirements for a mutable reference. | ||
unsafe { self.pointer.as_mut() } | ||
} | ||
} | ||
|
||
impl<T: ?Sized> Clone for Unique<T> { | ||
#[inline] | ||
fn clone(&self) -> Self { | ||
*self | ||
} | ||
} | ||
|
||
impl<T: ?Sized> Copy for Unique<T> {} | ||
|
||
use core::{marker::PhantomData, ptr::NonNull}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters