13
13
use cast;
14
14
use libc;
15
15
use libc:: { c_void, size_t} ;
16
+ use option:: { Option , Some , None } ;
16
17
use sys;
17
18
18
19
#[ cfg( not( test) ) ] use cmp:: { Eq , Ord } ;
@@ -209,6 +210,7 @@ pub unsafe fn array_each<T>(arr: **T, cb: &fn(*T)) {
209
210
pub trait Ptr < T > {
210
211
fn is_null ( & const self ) -> bool ;
211
212
fn is_not_null ( & const self ) -> bool ;
213
+ unsafe fn to_option ( & const self ) -> Option < & T > ;
212
214
fn offset ( & self , count : uint ) -> Self ;
213
215
}
214
216
@@ -222,6 +224,23 @@ impl<T> Ptr<T> for *T {
222
224
#[ inline( always) ]
223
225
fn is_not_null ( & const self ) -> bool { is_not_null ( * self ) }
224
226
227
+ ///
228
+ /// Returns `None` if the pointer is null, or else returns the value wrapped
229
+ /// in `Some`.
230
+ ///
231
+ /// # Safety Notes
232
+ ///
233
+ /// While this method is useful for null-safety, it is important to note
234
+ /// that this is still an unsafe operation because the returned value could
235
+ /// be pointing to invalid memory.
236
+ ///
237
+ #[ inline( always) ]
238
+ unsafe fn to_option ( & const self ) -> Option < & T > {
239
+ if self . is_null ( ) { None } else {
240
+ Some ( cast:: transmute ( * self ) )
241
+ }
242
+ }
243
+
225
244
/// Calculates the offset from a pointer.
226
245
#[ inline( always) ]
227
246
fn offset ( & self , count : uint ) -> * T { offset ( * self , count) }
@@ -237,6 +256,23 @@ impl<T> Ptr<T> for *mut T {
237
256
#[ inline( always) ]
238
257
fn is_not_null ( & const self ) -> bool { is_not_null ( * self ) }
239
258
259
+ ///
260
+ /// Returns `None` if the pointer is null, or else returns the value wrapped
261
+ /// in `Some`.
262
+ ///
263
+ /// # Safety Notes
264
+ ///
265
+ /// While this method is useful for null-safety, it is important to note
266
+ /// that this is still an unsafe operation because the returned value could
267
+ /// be pointing to invalid memory.
268
+ ///
269
+ #[ inline( always) ]
270
+ unsafe fn to_option ( & const self ) -> Option < & T > {
271
+ if self . is_null ( ) { None } else {
272
+ Some ( cast:: transmute ( * self ) )
273
+ }
274
+ }
275
+
240
276
/// Calculates the offset from a mutable pointer.
241
277
#[ inline( always) ]
242
278
fn offset ( & self , count : uint ) -> * mut T { mut_offset ( * self , count) }
@@ -423,6 +459,21 @@ pub mod ptr_tests {
423
459
assert ! ( mq. is_not_null( ) ) ;
424
460
}
425
461
462
+ #[ test]
463
+ fn test_to_option ( ) {
464
+ let p: * int = null ( ) ;
465
+ // FIXME (#6641): Usage of unsafe methods in safe code doesn't cause an error.
466
+ assert_eq ! ( p. to_option( ) , None ) ;
467
+
468
+ let q: * int = & 2 ;
469
+ assert_eq ! ( q. to_option( ) . unwrap( ) , & 2 ) ; // FIXME (#6641)
470
+
471
+ let p: * mut int = mut_null ( ) ;
472
+ assert_eq ! ( p. to_option( ) , None ) ; // FIXME (#6641)
473
+
474
+ let q: * mut int = & mut 2 ;
475
+ assert_eq ! ( q. to_option( ) . unwrap( ) , & 2 ) ; // FIXME (#6641)
476
+ }
426
477
427
478
#[ test]
428
479
fn test_ptr_array_each_with_len ( ) {
0 commit comments