Skip to content

Commit f40877f

Browse files
committed
Add 12 num::NonZero* types for each primitive integer
RFC: rust-lang/rfcs#2307
1 parent adf2135 commit f40877f

File tree

4 files changed

+100
-1
lines changed

4 files changed

+100
-1
lines changed

src/libcore/nonzero.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl_zeroable_for_integer_types! {
6262
/// NULL or 0 that might allow certain optimizations.
6363
#[lang = "non_zero"]
6464
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
65-
pub struct NonZero<T: Zeroable>(T);
65+
pub struct NonZero<T: Zeroable>(pub(crate) T);
6666

6767
impl<T: Zeroable> NonZero<T> {
6868
/// Creates an instance of NonZero with the provided value.

src/libcore/num/mod.rs

+87
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,96 @@
1515
use convert::{Infallible, TryFrom};
1616
use fmt;
1717
use intrinsics;
18+
use nonzero::NonZero;
1819
use ops;
1920
use str::FromStr;
2021

22+
macro_rules! impl_nonzero_fmt {
23+
( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
24+
$(
25+
#[$stability]
26+
impl fmt::$Trait for $Ty {
27+
#[inline]
28+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
29+
self.get().fmt(f)
30+
}
31+
}
32+
)+
33+
}
34+
}
35+
36+
macro_rules! nonzero_integers {
37+
( #[$stability: meta] $( $Ty: ident($Int: ty); )+ ) => {
38+
$(
39+
/// An integer that is known not to equal zero.
40+
///
41+
/// This may enable some memory layout optimization such as:
42+
///
43+
/// ```rust
44+
/// # #![feature(nonzero)]
45+
/// use std::mem::size_of;
46+
/// assert_eq!(size_of::<Option<std::num::NonZeroU32>>(), size_of::<u32>());
47+
/// ```
48+
#[$stability]
49+
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
50+
pub struct $Ty(NonZero<$Int>);
51+
52+
impl $Ty {
53+
/// Create a non-zero without checking the value.
54+
///
55+
/// # Safety
56+
///
57+
/// The value must not be zero.
58+
#[$stability]
59+
#[inline]
60+
pub const unsafe fn new_unchecked(n: $Int) -> Self {
61+
$Ty(NonZero(n))
62+
}
63+
64+
/// Create a non-zero if the given value is not zero.
65+
#[$stability]
66+
#[inline]
67+
pub fn new(n: $Int) -> Option<Self> {
68+
if n != 0 {
69+
Some($Ty(NonZero(n)))
70+
} else {
71+
None
72+
}
73+
}
74+
75+
/// Returns the value as a primitive type.
76+
#[$stability]
77+
#[inline]
78+
pub fn get(self) -> $Int {
79+
self.0 .0
80+
}
81+
82+
}
83+
84+
impl_nonzero_fmt! {
85+
#[$stability]
86+
(Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
87+
}
88+
)+
89+
}
90+
}
91+
92+
nonzero_integers! {
93+
#[unstable(feature = "nonzero", issue = "27730")]
94+
NonZeroU8(u8); NonZeroI8(i8);
95+
NonZeroU16(u16); NonZeroI16(i16);
96+
NonZeroU32(u32); NonZeroI32(i32);
97+
NonZeroU64(u64); NonZeroI64(i64);
98+
NonZeroUsize(usize); NonZeroIsize(isize);
99+
}
100+
101+
nonzero_integers! {
102+
// Change this to `#[unstable(feature = "i128", issue = "35118")]`
103+
// if other NonZero* integer types are stabilizied before 128-bit integers
104+
#[unstable(feature = "nonzero", issue = "27730")]
105+
NonZeroU128(u128); NonZeroI128(i128);
106+
}
107+
21108
/// Provides intentionally-wrapped arithmetic on `T`.
22109
///
23110
/// Operations like `+` on `u32` values is intended to never overflow,

src/libstd/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@
282282
#![feature(macro_vis_matcher)]
283283
#![feature(needs_panic_runtime)]
284284
#![feature(exhaustive_patterns)]
285+
#![feature(nonzero)]
285286
#![feature(num_bits_bytes)]
286287
#![feature(old_wrapping)]
287288
#![feature(on_unimplemented)]

src/libstd/num.rs

+11
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@ pub use core::num::{FpCategory, ParseIntError, ParseFloatError, TryFromIntError}
2121
#[stable(feature = "rust1", since = "1.0.0")]
2222
pub use core::num::Wrapping;
2323

24+
#[unstable(feature = "nonzero", issue = "27730")]
25+
pub use core::num::{
26+
NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32,
27+
NonZeroU64, NonZeroI64, NonZeroUsize, NonZeroIsize,
28+
};
29+
30+
// Change this to `#[unstable(feature = "i128", issue = "35118")]`
31+
// if other NonZero* integer types are stabilizied before 128-bit integers
32+
#[unstable(feature = "nonzero", issue = "27730")]
33+
pub use core::num::{NonZeroU128, NonZeroI128};
34+
2435
#[cfg(test)] use fmt;
2536
#[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem};
2637

0 commit comments

Comments
 (0)