Skip to content

Commit

Permalink
impl<T> *const T, impl<T> *mut T
Browse files Browse the repository at this point in the history
  • Loading branch information
Jorge Aparicio committed Mar 17, 2015
1 parent 633c593 commit 8afcaab
Show file tree
Hide file tree
Showing 14 changed files with 135 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/liballoc/heap.rs
Expand Up @@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[cfg(stage0)]
#[cfg(not(test))]
use core::ptr::PtrExt;

Expand Down
3 changes: 3 additions & 0 deletions src/liballoc/rc.rs
Expand Up @@ -159,7 +159,10 @@ use core::nonzero::NonZero;
use core::ops::{Deref, Drop};
use core::option::Option;
use core::option::Option::{Some, None};
#[cfg(stage0)]
use core::ptr::{self, PtrExt};
#[cfg(not(stage0))]
use core::ptr;
use core::result::Result;
use core::result::Result::{Ok, Err};
use core::intrinsics::assume;
Expand Down
1 change: 1 addition & 0 deletions src/libcollections/slice.rs
Expand Up @@ -99,6 +99,7 @@ use core::mem;
use core::num::wrapping::WrappingOps;
use core::ops::FnMut;
use core::option::Option::{self, Some, None};
#[cfg(stage0)]
use core::ptr::PtrExt;
use core::ptr;
use core::result::Result;
Expand Down
1 change: 1 addition & 0 deletions src/libcore/prelude.rs
Expand Up @@ -42,6 +42,7 @@ pub use iter::{Extend, IteratorExt};
pub use iter::{Iterator, DoubleEndedIterator};
pub use iter::{ExactSizeIterator};
pub use option::Option::{self, Some, None};
#[cfg(stage0)]
pub use ptr::{PtrExt, MutPtrExt};
pub use result::Result::{self, Ok, Err};
pub use slice::{AsSlice, SliceExt};
Expand Down
118 changes: 118 additions & 0 deletions src/libcore/ptr.rs
Expand Up @@ -262,6 +262,7 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
intrinsics::move_val_init(&mut *dst, src)
}

#[cfg(stage0)]
/// Methods on raw pointers
#[stable(feature = "rust1", since = "1.0.0")]
pub trait PtrExt {
Expand Down Expand Up @@ -298,6 +299,7 @@ pub trait PtrExt {
unsafe fn offset(self, count: isize) -> Self where Self::Target: Sized;
}

#[cfg(stage0)]
/// Methods on mutable raw pointers
#[stable(feature = "rust1", since = "1.0.0")]
pub trait MutPtrExt {
Expand All @@ -317,6 +319,7 @@ pub trait MutPtrExt {
unsafe fn as_mut<'a>(&self) -> Option<&'a mut Self::Target>;
}

#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> PtrExt for *const T {
type Target = T;
Expand Down Expand Up @@ -344,6 +347,7 @@ impl<T: ?Sized> PtrExt for *const T {
}
}

#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> PtrExt for *mut T {
type Target = T;
Expand Down Expand Up @@ -371,6 +375,7 @@ impl<T: ?Sized> PtrExt for *mut T {
}
}

#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> MutPtrExt for *mut T {
type Target = T;
Expand All @@ -388,6 +393,119 @@ impl<T: ?Sized> MutPtrExt for *mut T {
}
}

#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
#[lang = "const_ptr"]
impl<T: ?Sized> *const T {
/// Returns true if the pointer is null.
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn is_null(self) -> bool {
self == 0 as *const T
}

/// Returns `None` if the pointer is null, or else returns a reference to
/// the value wrapped in `Some`.
///
/// # Safety
///
/// While this method and its mutable counterpart are useful for
/// null-safety, it is important to note that this is still an unsafe
/// operation because the returned value could be pointing to invalid
/// memory.
#[unstable(feature = "core",
reason = "Option is not clearly the right return type, and we may want \
to tie the return lifetime to a borrow of the raw pointer")]
#[inline]
pub unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
if self.is_null() {
None
} else {
Some(&**self)
}
}

/// Calculates the offset from a pointer. `count` is in units of T; e.g. a
/// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes.
///
/// # Safety
///
/// The offset must be in-bounds of the object, or one-byte-past-the-end.
/// Otherwise `offset` invokes Undefined Behaviour, regardless of whether
/// the pointer is used.
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub unsafe fn offset(self, count: isize) -> *const T where T: Sized {
intrinsics::offset(self, count)
}
}

#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
#[lang = "mut_ptr"]
impl<T: ?Sized> *mut T {
/// Returns true if the pointer is null.
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn is_null(self) -> bool {
self == 0 as *mut T
}

/// Returns `None` if the pointer is null, or else returns a reference to
/// the value wrapped in `Some`.
///
/// # Safety
///
/// While this method and its mutable counterpart are useful for
/// null-safety, it is important to note that this is still an unsafe
/// operation because the returned value could be pointing to invalid
/// memory.
#[unstable(feature = "core",
reason = "Option is not clearly the right return type, and we may want \
to tie the return lifetime to a borrow of the raw pointer")]
#[inline]
pub unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
if self.is_null() {
None
} else {
Some(&**self)
}
}

/// Calculates the offset from a pointer. `count` is in units of T; e.g. a
/// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes.
///
/// # Safety
///
/// The offset must be in-bounds of the object, or one-byte-past-the-end.
/// Otherwise `offset` invokes Undefined Behaviour, regardless of whether
/// the pointer is used.
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub unsafe fn offset(self, count: isize) -> *mut T where T: Sized {
intrinsics::offset(self, count) as *mut T
}

/// Returns `None` if the pointer is null, or else returns a mutable
/// reference to the value wrapped in `Some`.
///
/// # Safety
///
/// As with `as_ref`, this is unsafe because it cannot verify the validity
/// of the returned pointer.
#[unstable(feature = "core",
reason = "return value does not necessarily convey all possible \
information")]
#[inline]
pub unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> {
if self.is_null() {
None
} else {
Some(&mut **self)
}
}
}

// Equality for pointers
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> PartialEq for *const T {
Expand Down
1 change: 1 addition & 0 deletions src/libcore/slice.rs
Expand Up @@ -49,6 +49,7 @@ use option::Option::{None, Some};
use result::Result;
use result::Result::{Ok, Err};
use ptr;
#[cfg(stage0)]
use ptr::PtrExt;
use mem;
use mem::size_of;
Expand Down
1 change: 1 addition & 0 deletions src/libcore/str/mod.rs
Expand Up @@ -30,6 +30,7 @@ use mem;
use num::Int;
use ops::{Fn, FnMut};
use option::Option::{self, None, Some};
#[cfg(stage0)]
use ptr::PtrExt;
use raw::{Repr, Slice};
use result::Result::{self, Ok, Err};
Expand Down
3 changes: 3 additions & 0 deletions src/libstd/collections/hash/table.rs
Expand Up @@ -24,7 +24,10 @@ use num::wrapping::{OverflowingOps, WrappingOps};
use ops::{Deref, DerefMut, Drop};
use option::Option;
use option::Option::{Some, None};
#[cfg(stage0)]
use ptr::{self, PtrExt, Unique};
#[cfg(not(stage0))]
use ptr::{self, Unique};
use rt::heap::{allocate, deallocate, EMPTY};
use collections::hash_state::HashState;

Expand Down
1 change: 1 addition & 0 deletions src/libstd/io/mod.rs
Expand Up @@ -20,6 +20,7 @@ use iter::Iterator;
use marker::Sized;
use ops::{Drop, FnOnce};
use option::Option::{self, Some, None};
#[cfg(stage0)]
use ptr::PtrExt;
use result::Result::{Ok, Err};
use result;
Expand Down
1 change: 1 addition & 0 deletions src/libstd/old_io/extensions.rs
Expand Up @@ -26,6 +26,7 @@ use num::Int;
use ops::FnOnce;
use option::Option;
use option::Option::{Some, None};
#[cfg(stage0)]
use ptr::PtrExt;
use result::Result::{Ok, Err};
#[cfg(stage0)]
Expand Down
1 change: 1 addition & 0 deletions src/libstd/old_io/mod.rs
Expand Up @@ -935,6 +935,7 @@ impl<'a> Reader for &'a mut (Reader+'a) {
// API yet. If so, it should be a method on Vec.
unsafe fn slice_vec_capacity<'a, T>(v: &'a mut Vec<T>, start: uint, end: uint) -> &'a mut [T] {
use slice;
#[cfg(stage0)]
use ptr::PtrExt;

assert!(start <= end);
Expand Down
1 change: 1 addition & 0 deletions src/libstd/os.rs
Expand Up @@ -52,6 +52,7 @@ use option::Option::{Some, None};
use option::Option;
use old_path::{Path, GenericPath, BytesContainer};
use path::{self, PathBuf};
#[cfg(stage0)]
use ptr::PtrExt;
use ptr;
use result::Result::{Err, Ok};
Expand Down
1 change: 1 addition & 0 deletions src/libstd/prelude/v1.rs
Expand Up @@ -40,6 +40,7 @@
#[doc(no_inline)] pub use iter::{Iterator, IteratorExt, Extend};
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use option::Option::{self, Some, None};
#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] pub use ptr::{PtrExt, MutPtrExt};
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
1 change: 1 addition & 0 deletions src/libstd/rt/at_exit_imp.rs
Expand Up @@ -12,6 +12,7 @@
//!
//! Documentation can be found on the `rt::at_exit` function.

#[cfg(stage0)]
use core::prelude::*;

use boxed;
Expand Down

0 comments on commit 8afcaab

Please sign in to comment.