12
12
13
13
use ops:: Deref ;
14
14
15
+ /// Unsafe trait to indicate what types are usable with the NonZero struct
16
+ pub unsafe trait Zeroable { }
17
+
18
+ unsafe impl < T > Zeroable for * const T { }
19
+ unsafe impl < T > Zeroable for * mut T { }
20
+ unsafe impl Zeroable for int { }
21
+ unsafe impl Zeroable for uint { }
22
+ unsafe impl Zeroable for i8 { }
23
+ unsafe impl Zeroable for u8 { }
24
+ unsafe impl Zeroable for i16 { }
25
+ unsafe impl Zeroable for u16 { }
26
+ unsafe impl Zeroable for i32 { }
27
+ unsafe impl Zeroable for u32 { }
28
+ unsafe impl Zeroable for i64 { }
29
+ unsafe impl Zeroable for u64 { }
30
+
15
31
/// A wrapper type for raw pointers and integers that will never be
16
32
/// NULL or 0 that might allow certain optimizations.
17
33
#[ lang="non_zero" ]
18
34
#[ deriving( Copy , Clone , Eq , PartialEq , Ord , PartialOrd , Show ) ]
19
35
#[ experimental]
20
- pub struct NonZero < T > ( T ) ;
36
+ pub struct NonZero < T : Zeroable > ( T ) ;
21
37
22
- impl < T > NonZero < T > {
38
+ impl < T : Zeroable > NonZero < T > {
23
39
/// Create an instance of NonZero with the provided value.
24
40
/// You must indeed ensure that the value is actually "non-zero".
25
41
#[ inline( always) ]
@@ -28,10 +44,48 @@ impl<T> NonZero<T> {
28
44
}
29
45
}
30
46
31
- impl < T > Deref < T > for NonZero < T > {
47
+ impl < T : Zeroable > Deref < T > for NonZero < T > {
32
48
#[ inline]
33
49
fn deref < ' a > ( & ' a self ) -> & ' a T {
34
50
let NonZero ( ref inner) = * self ;
35
51
inner
36
52
}
37
53
}
54
+
55
+ #[ cfg( test) ]
56
+ mod test {
57
+ use super :: NonZero ;
58
+
59
+ #[ test]
60
+ fn test_create_nonzero_instance ( ) {
61
+ let _a = unsafe {
62
+ NonZero :: new ( 21 )
63
+ } ;
64
+ }
65
+
66
+ #[ test]
67
+ fn test_size_nonzero_in_option ( ) {
68
+ use mem:: size_of;
69
+ use option:: Option ;
70
+
71
+ assert_eq ! ( size_of:: <NonZero <u32 >>( ) , size_of:: <Option <NonZero <u32 >>>( ) ) ;
72
+ }
73
+
74
+ #[ test]
75
+ fn test_match_on_nonzero_option ( ) {
76
+ use option:: Some ;
77
+
78
+ let a = Some ( unsafe {
79
+ NonZero :: new ( 42 )
80
+ } ) ;
81
+ match a {
82
+ Some ( val) => assert_eq ! ( * val, 42 ) ,
83
+ None => panic ! ( "unexpected None while matching on Some(NonZero(_))" )
84
+ }
85
+
86
+ match unsafe { NonZero :: new ( 43 ) } {
87
+ Some ( val) => assert_eq ! ( * val, 43 ) ,
88
+ None => panic ! ( "unexpected None while matching on Some(NonZero(_))" )
89
+ }
90
+ }
91
+ }
0 commit comments