16
16
use ops:: CoerceUnsized ;
17
17
18
18
/// Unsafe trait to indicate what types are usable with the NonZero struct
19
- pub unsafe trait Zeroable { }
20
-
21
- unsafe impl < T : ?Sized > Zeroable for * const T { }
22
- unsafe impl < T : ?Sized > Zeroable for * mut T { }
23
- unsafe impl Zeroable for isize { }
24
- unsafe impl Zeroable for usize { }
25
- unsafe impl Zeroable for i8 { }
26
- unsafe impl Zeroable for u8 { }
27
- unsafe impl Zeroable for i16 { }
28
- unsafe impl Zeroable for u16 { }
29
- unsafe impl Zeroable for i32 { }
30
- unsafe impl Zeroable for u32 { }
31
- unsafe impl Zeroable for i64 { }
32
- unsafe impl Zeroable for u64 { }
33
- unsafe impl Zeroable for i128 { }
34
- unsafe impl Zeroable for u128 { }
19
+ pub unsafe trait Zeroable {
20
+ /// Whether this value is zero
21
+ fn is_zero ( & self ) -> bool ;
22
+ }
23
+
24
+ macro_rules! impl_zeroable_for_pointer_types {
25
+ ( $( $Ptr: ty ) + ) => {
26
+ $(
27
+ /// For fat pointers to be considered "zero", only the "data" part needs to be null.
28
+ unsafe impl <T : ?Sized > Zeroable for $Ptr {
29
+ #[ inline]
30
+ fn is_zero( & self ) -> bool {
31
+ // Cast because `is_null` is only available on thin pointers
32
+ ( * self as * mut u8 ) . is_null( )
33
+ }
34
+ }
35
+ ) +
36
+ }
37
+ }
38
+
39
+ macro_rules! impl_zeroable_for_integer_types {
40
+ ( $( $Int: ty ) + ) => {
41
+ $(
42
+ unsafe impl Zeroable for $Int {
43
+ #[ inline]
44
+ fn is_zero( & self ) -> bool {
45
+ * self == 0
46
+ }
47
+ }
48
+ ) +
49
+ }
50
+ }
51
+
52
+ impl_zeroable_for_pointer_types ! {
53
+ * const T
54
+ * mut T
55
+ }
56
+
57
+ impl_zeroable_for_integer_types ! {
58
+ usize u8 u16 u32 u64 u128
59
+ isize i8 i16 i32 i64 i128
60
+ }
35
61
36
62
/// A wrapper type for raw pointers and integers that will never be
37
63
/// NULL or 0 that might allow certain optimizations.
@@ -43,10 +69,20 @@ impl<T: Zeroable> NonZero<T> {
43
69
/// Creates an instance of NonZero with the provided value.
44
70
/// You must indeed ensure that the value is actually "non-zero".
45
71
#[ inline]
46
- pub const unsafe fn new ( inner : T ) -> NonZero < T > {
72
+ pub const unsafe fn new ( inner : T ) -> Self {
47
73
NonZero ( inner)
48
74
}
49
75
76
+ /// Creates an instance of NonZero with the provided value.
77
+ #[ inline]
78
+ pub fn new_checked ( inner : T ) -> Option < Self > {
79
+ if inner. is_zero ( ) {
80
+ None
81
+ } else {
82
+ Some ( NonZero ( inner) )
83
+ }
84
+ }
85
+
50
86
/// Gets the inner value.
51
87
pub fn get ( self ) -> T {
52
88
self . 0
0 commit comments