1212
1313use ops:: Deref ;
1414
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+
1531/// A wrapper type for raw pointers and integers that will never be
1632/// NULL or 0 that might allow certain optimizations.
1733#[ lang="non_zero" ]
1834#[ deriving( Copy , Clone , Eq , PartialEq , Ord , PartialOrd , Show ) ]
1935#[ experimental]
20- pub struct NonZero < T > ( T ) ;
36+ pub struct NonZero < T : Zeroable > ( T ) ;
2137
22- impl < T > NonZero < T > {
38+ impl < T : Zeroable > NonZero < T > {
2339 /// Create an instance of NonZero with the provided value.
2440 /// You must indeed ensure that the value is actually "non-zero".
2541 #[ inline( always) ]
@@ -28,10 +44,48 @@ impl<T> NonZero<T> {
2844 }
2945}
3046
31- impl < T > Deref < T > for NonZero < T > {
47+ impl < T : Zeroable > Deref < T > for NonZero < T > {
3248 #[ inline]
3349 fn deref < ' a > ( & ' a self ) -> & ' a T {
3450 let NonZero ( ref inner) = * self ;
3551 inner
3652 }
3753}
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