Skip to content

Commit ef5da14

Browse files
committed
libcore: Add NonZero lang item and implement some methods.
1 parent 46e7376 commit ef5da14

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

src/libcore/ptr.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
use mem;
9191
use clone::Clone;
9292
use intrinsics;
93+
use kinds::Copy;
9394
use option::Option;
9495
use option::Option::{Some, None};
9596
use kinds::{Send, Sync};
@@ -109,6 +110,15 @@ pub use intrinsics::copy_memory;
109110
#[experimental = "uncertain about naming and semantics"]
110111
pub use intrinsics::set_memory;
111112

113+
114+
/// A wrapper type for raw pointers and integers that will never be
115+
/// NULL or 0 that might allow certain optimizations.
116+
#[lang="non_zero"]
117+
#[deriving(Clone, PartialEq, Eq, PartialOrd)]
118+
pub struct NonZero<T>(pub T);
119+
120+
impl<T: Copy> Copy for NonZero<T> {}
121+
112122
/// Creates a null raw pointer.
113123
///
114124
/// # Examples
@@ -313,6 +323,32 @@ impl<T> RawPtr<T> for *const T {
313323
}
314324
}
315325

326+
impl<T> RawPtr<T> for NonZero<*const T> {
327+
#[inline]
328+
fn null() -> NonZero<*const T> { NonZero(null()) }
329+
330+
#[inline]
331+
fn is_null(&self) -> bool { false }
332+
333+
#[inline]
334+
fn to_uint(&self) -> uint {
335+
let NonZero(p) = *self;
336+
p as uint
337+
}
338+
339+
#[inline]
340+
unsafe fn offset(self, count: int) -> NonZero<*const T> {
341+
let NonZero(p) = self;
342+
NonZero(intrinsics::offset(p, count))
343+
}
344+
345+
#[inline]
346+
unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
347+
let NonZero(p) = *self;
348+
Some(&*p)
349+
}
350+
}
351+
316352
impl<T> RawPtr<T> for *mut T {
317353
#[inline]
318354
fn null() -> *mut T { null_mut() }
@@ -338,6 +374,32 @@ impl<T> RawPtr<T> for *mut T {
338374
}
339375
}
340376

377+
impl<T> RawPtr<T> for NonZero<*mut T> {
378+
#[inline]
379+
fn null() -> NonZero<*mut T> { NonZero(null_mut()) }
380+
381+
#[inline]
382+
fn is_null(&self) -> bool { false }
383+
384+
#[inline]
385+
fn to_uint(&self) -> uint {
386+
let NonZero(p) = *self;
387+
p as uint
388+
}
389+
390+
#[inline]
391+
unsafe fn offset(self, count: int) -> NonZero<*mut T> {
392+
let NonZero(p) = self;
393+
NonZero(intrinsics::offset(p as *const T, count) as *mut T)
394+
}
395+
396+
#[inline]
397+
unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
398+
let NonZero(p) = *self;
399+
Some(&*p)
400+
}
401+
}
402+
341403
impl<T> RawMutPtr<T> for *mut T {
342404
#[inline]
343405
unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> {
@@ -349,6 +411,14 @@ impl<T> RawMutPtr<T> for *mut T {
349411
}
350412
}
351413

414+
impl<T> RawMutPtr<T> for NonZero<*mut T> {
415+
#[inline]
416+
unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> {
417+
let NonZero(p) = *self;
418+
Some(&mut *p)
419+
}
420+
}
421+
352422
// Equality for pointers
353423
impl<T> PartialEq for *const T {
354424
#[inline]

0 commit comments

Comments
 (0)