提交 adaae45c 编写于 作者: B bors

auto merge of #6604 : bjz/rust/ptr-to-option, r=brson

...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
use cast; use cast;
use libc; use libc;
use libc::{c_void, size_t}; use libc::{c_void, size_t};
use option::{Option, Some, None};
use sys; use sys;
#[cfg(not(test))] use cmp::{Eq, Ord}; #[cfg(not(test))] use cmp::{Eq, Ord};
...@@ -209,6 +210,7 @@ pub unsafe fn array_each<T>(arr: **T, cb: &fn(*T)) { ...@@ -209,6 +210,7 @@ pub unsafe fn array_each<T>(arr: **T, cb: &fn(*T)) {
pub trait Ptr<T> { pub trait Ptr<T> {
fn is_null(&const self) -> bool; fn is_null(&const self) -> bool;
fn is_not_null(&const self) -> bool; fn is_not_null(&const self) -> bool;
unsafe fn to_option(&const self) -> Option<&T>;
fn offset(&self, count: uint) -> Self; fn offset(&self, count: uint) -> Self;
} }
...@@ -222,6 +224,23 @@ fn is_null(&const self) -> bool { is_null(*self) } ...@@ -222,6 +224,23 @@ fn is_null(&const self) -> bool { is_null(*self) }
#[inline(always)] #[inline(always)]
fn is_not_null(&const self) -> bool { is_not_null(*self) } fn is_not_null(&const self) -> bool { is_not_null(*self) }
///
/// Returns `None` if the pointer is null, or else returns the value wrapped
/// in `Some`.
///
/// # Safety Notes
///
/// While this method is 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.
///
#[inline(always)]
unsafe fn to_option(&const self) -> Option<&T> {
if self.is_null() { None } else {
Some(cast::transmute(*self))
}
}
/// Calculates the offset from a pointer. /// Calculates the offset from a pointer.
#[inline(always)] #[inline(always)]
fn offset(&self, count: uint) -> *T { offset(*self, count) } fn offset(&self, count: uint) -> *T { offset(*self, count) }
...@@ -237,6 +256,23 @@ fn is_null(&const self) -> bool { is_null(*self) } ...@@ -237,6 +256,23 @@ fn is_null(&const self) -> bool { is_null(*self) }
#[inline(always)] #[inline(always)]
fn is_not_null(&const self) -> bool { is_not_null(*self) } fn is_not_null(&const self) -> bool { is_not_null(*self) }
///
/// Returns `None` if the pointer is null, or else returns the value wrapped
/// in `Some`.
///
/// # Safety Notes
///
/// While this method is 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.
///
#[inline(always)]
unsafe fn to_option(&const self) -> Option<&T> {
if self.is_null() { None } else {
Some(cast::transmute(*self))
}
}
/// Calculates the offset from a mutable pointer. /// Calculates the offset from a mutable pointer.
#[inline(always)] #[inline(always)]
fn offset(&self, count: uint) -> *mut T { mut_offset(*self, count) } fn offset(&self, count: uint) -> *mut T { mut_offset(*self, count) }
...@@ -423,6 +459,21 @@ fn test_is_null() { ...@@ -423,6 +459,21 @@ fn test_is_null() {
assert!(mq.is_not_null()); assert!(mq.is_not_null());
} }
#[test]
fn test_to_option() {
let p: *int = null();
// FIXME (#6641): Usage of unsafe methods in safe code doesn't cause an error.
assert_eq!(p.to_option(), None);
let q: *int = &2;
assert_eq!(q.to_option().unwrap(), &2); // FIXME (#6641)
let p: *mut int = mut_null();
assert_eq!(p.to_option(), None); // FIXME (#6641)
let q: *mut int = &mut 2;
assert_eq!(q.to_option().unwrap(), &2); // FIXME (#6641)
}
#[test] #[test]
fn test_ptr_array_each_with_len() { fn test_ptr_array_each_with_len() {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册