Rewrite Unique<T>
so that it is covariant in T, implies NonZero
and ownership,
and also follows the API of `NonZero` a bit more closely. More to do here I think (including perhaps a new name).
This commit is contained in:
parent
8c841f2a31
commit
801bc48939
3 changed files with 38 additions and 27 deletions
|
@ -10,15 +10,14 @@
|
|||
|
||||
//! Exposes the NonZero lang item which provides optimization hints.
|
||||
|
||||
use marker::{Sized, MarkerTrait};
|
||||
use ops::Deref;
|
||||
use ptr::Unique;
|
||||
|
||||
/// Unsafe trait to indicate what types are usable with the NonZero struct
|
||||
pub unsafe trait Zeroable {}
|
||||
pub unsafe trait Zeroable : MarkerTrait {}
|
||||
|
||||
unsafe impl<T> Zeroable for *const T {}
|
||||
unsafe impl<T> Zeroable for *mut T {}
|
||||
unsafe impl<T> Zeroable for Unique<T> { }
|
||||
unsafe impl<T:?Sized> Zeroable for *const T {}
|
||||
unsafe impl<T:?Sized> Zeroable for *mut T {}
|
||||
unsafe impl Zeroable for isize {}
|
||||
unsafe impl Zeroable for usize {}
|
||||
unsafe impl Zeroable for i8 {}
|
||||
|
|
|
@ -91,8 +91,10 @@
|
|||
use mem;
|
||||
use clone::Clone;
|
||||
use intrinsics;
|
||||
use ops::Deref;
|
||||
use option::Option::{self, Some, None};
|
||||
use marker::{self, Send, Sized, Sync};
|
||||
use marker::{PhantomData, Send, Sized, Sync};
|
||||
use nonzero::NonZero;
|
||||
|
||||
use cmp::{PartialEq, Eq, Ord, PartialOrd};
|
||||
use cmp::Ordering::{self, Less, Equal, Greater};
|
||||
|
@ -517,15 +519,16 @@ impl<T> PartialOrd for *mut T {
|
|||
|
||||
/// A wrapper around a raw `*mut T` that indicates that the possessor
|
||||
/// of this wrapper owns the referent. This in turn implies that the
|
||||
/// `Unique<T>` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a
|
||||
/// raw `*mut T` (which conveys no particular ownership semantics).
|
||||
/// Useful for building abstractions like `Vec<T>` or `Box<T>`, which
|
||||
/// `Unique<T>` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a raw
|
||||
/// `*mut T` (which conveys no particular ownership semantics). It
|
||||
/// also implies that the referent of the pointer should not be
|
||||
/// modified without a unique path to the `Unique` reference. Useful
|
||||
/// for building abstractions like `Vec<T>` or `Box<T>`, which
|
||||
/// internally use raw pointers to manage the memory that they own.
|
||||
#[unstable(feature = "core", reason = "recently added to this module")]
|
||||
pub struct Unique<T: ?Sized> {
|
||||
/// The wrapped `*mut T`.
|
||||
pub ptr: *mut T,
|
||||
_own: marker::PhantomData<T>,
|
||||
pub struct Unique<T:?Sized> {
|
||||
pointer: NonZero<*const T>,
|
||||
_marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
/// `Unique` pointers are `Send` if `T` is `Send` because the data they
|
||||
|
@ -542,25 +545,34 @@ unsafe impl<T: Send + ?Sized> Send for Unique<T> { }
|
|||
#[unstable(feature = "core", reason = "recently added to this module")]
|
||||
unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
|
||||
|
||||
impl<T> Unique<T> {
|
||||
/// Returns a null Unique.
|
||||
impl<T:?Sized> Unique<T> {
|
||||
/// Create a new `Unique`.
|
||||
#[unstable(feature = "core",
|
||||
reason = "recently added to this module")]
|
||||
pub fn null() -> Unique<T> {
|
||||
Unique(null_mut())
|
||||
pub unsafe fn new(ptr: *mut T) -> Unique<T> {
|
||||
Unique { pointer: NonZero::new(ptr as *const T), _marker: PhantomData }
|
||||
}
|
||||
|
||||
/// Return an (unsafe) pointer into the memory owned by `self`.
|
||||
/// Dereference the content.
|
||||
#[unstable(feature = "core",
|
||||
reason = "recently added to this module")]
|
||||
pub unsafe fn offset(self, offset: isize) -> *mut T {
|
||||
self.ptr.offset(offset)
|
||||
pub unsafe fn get(&self) -> &T {
|
||||
&**self.pointer
|
||||
}
|
||||
|
||||
/// Mutably dereference the content.
|
||||
#[unstable(feature = "core",
|
||||
reason = "recently added to this module")]
|
||||
pub unsafe fn get_mut(&mut self) -> &mut T {
|
||||
&mut ***self
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a `Unique` wrapped around `ptr`, taking ownership of the
|
||||
/// data referenced by `ptr`.
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Unique<T: ?Sized>(ptr: *mut T) -> Unique<T> {
|
||||
Unique { ptr: ptr, _own: marker::PhantomData }
|
||||
impl<T:?Sized> Deref for Unique<T> {
|
||||
type Target = *mut T;
|
||||
|
||||
#[inline]
|
||||
fn deref<'a>(&'a self) -> &'a *mut T {
|
||||
unsafe { mem::transmute(&*self.pointer) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -171,8 +171,8 @@ fn test_set_memory() {
|
|||
#[test]
|
||||
fn test_unsized_unique() {
|
||||
let xs: &mut [_] = &mut [1, 2, 3];
|
||||
let ptr = Unique(xs as *mut [_]);
|
||||
let ys = unsafe { &mut *ptr.ptr };
|
||||
let ptr = unsafe { Unique::new(xs as *mut [_]) };
|
||||
let ys = unsafe { &mut **ptr };
|
||||
let zs: &mut [_] = &mut [1, 2, 3];
|
||||
assert!(ys == zs);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue