Skip to content

Commit 8234581

Browse files
committed
rebase isqrt edits
1 parent cd0c944 commit 8234581

File tree

3 files changed

+61
-50
lines changed

3 files changed

+61
-50
lines changed

library/core/src/num/mod.rs

-9
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#![stable(feature = "rust1", since = "1.0.0")]
44

55
use crate::ascii;
6-
use crate::hint;
76
use crate::intrinsics;
87
use crate::mem;
98
use crate::str::FromStr;
@@ -483,7 +482,6 @@ impl u8 {
483482
Self = u8,
484483
ActualT = u8,
485484
SignedT = i8,
486-
NonZeroT = NonZero<u8>,
487485
BITS = 8,
488486
MAX = 255,
489487
rot = 2,
@@ -1098,7 +1096,6 @@ impl u16 {
10981096
Self = u16,
10991097
ActualT = u16,
11001098
SignedT = i16,
1101-
NonZeroT = NonZero<u16>,
11021099
BITS = 16,
11031100
MAX = 65535,
11041101
rot = 4,
@@ -1147,7 +1144,6 @@ impl u32 {
11471144
Self = u32,
11481145
ActualT = u32,
11491146
SignedT = i32,
1150-
NonZeroT = NonZero<u32>,
11511147
BITS = 32,
11521148
MAX = 4294967295,
11531149
rot = 8,
@@ -1171,7 +1167,6 @@ impl u64 {
11711167
Self = u64,
11721168
ActualT = u64,
11731169
SignedT = i64,
1174-
NonZeroT = NonZero<u64>,
11751170
BITS = 64,
11761171
MAX = 18446744073709551615,
11771172
rot = 12,
@@ -1195,7 +1190,6 @@ impl u128 {
11951190
Self = u128,
11961191
ActualT = u128,
11971192
SignedT = i128,
1198-
NonZeroT = NonZero<u128>,
11991193
BITS = 128,
12001194
MAX = 340282366920938463463374607431768211455,
12011195
rot = 16,
@@ -1221,7 +1215,6 @@ impl usize {
12211215
Self = usize,
12221216
ActualT = u16,
12231217
SignedT = isize,
1224-
NonZeroT = NonZero<usize>,
12251218
BITS = 16,
12261219
MAX = 65535,
12271220
rot = 4,
@@ -1246,7 +1239,6 @@ impl usize {
12461239
Self = usize,
12471240
ActualT = u32,
12481241
SignedT = isize,
1249-
NonZeroT = NonZero<usize>,
12501242
BITS = 32,
12511243
MAX = 4294967295,
12521244
rot = 8,
@@ -1271,7 +1263,6 @@ impl usize {
12711263
Self = usize,
12721264
ActualT = u64,
12731265
SignedT = isize,
1274-
NonZeroT = NonZero<usize>,
12751266
BITS = 64,
12761267
MAX = 18446744073709551615,
12771268
rot = 12,

library/core/src/num/nonzero.rs

+56-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use crate::cmp::Ordering;
44
use crate::fmt;
55
use crate::hash::{Hash, Hasher};
6+
use crate::hint;
67
use crate::intrinsics;
78
use crate::marker::{Freeze, StructuralPartialEq};
89
use crate::ops::{BitOr, BitOrAssign, Div, DivAssign, Neg, Rem, RemAssign};
@@ -606,7 +607,6 @@ macro_rules! nonzero_integer {
606607
}
607608

608609
nonzero_integer_signedness_dependent_methods! {
609-
Self = $Ty,
610610
Primitive = $signedness $Int,
611611
UnsignedPrimitive = $Uint,
612612
}
@@ -825,7 +825,7 @@ macro_rules! nonzero_integer {
825825
}
826826
}
827827

828-
nonzero_integer_signedness_dependent_impls!($Ty $signedness $Int);
828+
nonzero_integer_signedness_dependent_impls!($signedness $Int);
829829
};
830830

831831
(Self = $Ty:ident, Primitive = unsigned $Int:ident $(,)?) => {
@@ -851,7 +851,7 @@ macro_rules! nonzero_integer {
851851

852852
macro_rules! nonzero_integer_signedness_dependent_impls {
853853
// Impls for unsigned nonzero types only.
854-
($Ty:ident unsigned $Int:ty) => {
854+
(unsigned $Int:ty) => {
855855
#[stable(feature = "nonzero_div", since = "1.51.0")]
856856
impl Div<NonZero<$Int>> for $Int {
857857
type Output = $Int;
@@ -899,7 +899,7 @@ macro_rules! nonzero_integer_signedness_dependent_impls {
899899
}
900900
};
901901
// Impls for signed nonzero types only.
902-
($Ty:ident signed $Int:ty) => {
902+
(signed $Int:ty) => {
903903
#[stable(feature = "signed_nonzero_neg", since = "1.71.0")]
904904
impl Neg for NonZero<$Int> {
905905
type Output = Self;
@@ -920,7 +920,6 @@ macro_rules! nonzero_integer_signedness_dependent_impls {
920920
macro_rules! nonzero_integer_signedness_dependent_methods {
921921
// Associated items for unsigned nonzero types only.
922922
(
923-
Self = $Ty:ident,
924923
Primitive = unsigned $Int:ident,
925924
UnsignedPrimitive = $Uint:ty,
926925
) => {
@@ -1226,11 +1225,62 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
12261225

12271226
intrinsics::ctpop(self.get()) < 2
12281227
}
1228+
1229+
/// Returns the square root of the number, rounded down.
1230+
///
1231+
/// # Examples
1232+
///
1233+
/// Basic usage:
1234+
/// ```
1235+
/// #![feature(isqrt)]
1236+
/// # use std::num::NonZero;
1237+
/// #
1238+
/// # fn main() { test().unwrap(); }
1239+
/// # fn test() -> Option<()> {
1240+
#[doc = concat!("let ten = NonZero::new(10", stringify!($Int), ")?;")]
1241+
#[doc = concat!("let three = NonZero::new(3", stringify!($Int), ")?;")]
1242+
///
1243+
/// assert_eq!(ten.isqrt(), three);
1244+
/// # Some(())
1245+
/// # }
1246+
#[unstable(feature = "isqrt", issue = "116226")]
1247+
#[rustc_const_unstable(feature = "isqrt", issue = "116226")]
1248+
#[must_use = "this returns the result of the operation, \
1249+
without modifying the original"]
1250+
#[inline]
1251+
pub const fn isqrt(self) -> Self {
1252+
// The algorithm is based on the one presented in
1253+
// <https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)>
1254+
// which cites as source the following C code:
1255+
// <https://web.archive.org/web/20120306040058/http://medialab.freaknet.org/martin/src/sqrt/sqrt.c>.
1256+
1257+
let mut op = self.get();
1258+
let mut res = 0;
1259+
let mut one = 1 << (self.ilog2() & !1);
1260+
1261+
while one != 0 {
1262+
if op >= res + one {
1263+
op -= res + one;
1264+
res = (res >> 1) + one;
1265+
} else {
1266+
res >>= 1;
1267+
}
1268+
one >>= 2;
1269+
}
1270+
1271+
// SAFETY: The result fits in an integer with half as many bits.
1272+
// Inform the optimizer about it.
1273+
unsafe {
1274+
hint::assert_unchecked(res < 1 << (Self::BITS / 2));
1275+
}
1276+
1277+
// SAFETY: The result is positive.
1278+
unsafe { Self::new_unchecked(res) }
1279+
}
12291280
};
12301281

12311282
// Associated items for signed nonzero types only.
12321283
(
1233-
Self = $Ty:ident,
12341284
Primitive = signed $Int:ident,
12351285
UnsignedPrimitive = $Uint:ty,
12361286
) => {

library/core/src/num/uint_macros.rs

+5-35
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ macro_rules! uint_impl {
33
Self = $SelfT:ty,
44
ActualT = $ActualT:ident,
55
SignedT = $SignedT:ident,
6-
NonZeroT = $NonZeroT:ty,
76

87
// There are all for use *only* in doc comments.
98
// As such, they're all passed as literals -- passing them as a string
@@ -1216,8 +1215,7 @@ macro_rules! uint_impl {
12161215
without modifying the original"]
12171216
#[inline]
12181217
pub const fn checked_ilog2(self) -> Option<u32> {
1219-
// FIXME: Simply use `NonZero::new` once it is actually generic.
1220-
if let Some(x) = <$NonZeroT>::new(self) {
1218+
if let Some(x) = NonZero::new(self) {
12211219
Some(x.ilog2())
12221220
} else {
12231221
None
@@ -1239,8 +1237,7 @@ macro_rules! uint_impl {
12391237
without modifying the original"]
12401238
#[inline]
12411239
pub const fn checked_ilog10(self) -> Option<u32> {
1242-
// FIXME: Simply use `NonZero::new` once it is actually generic.
1243-
if let Some(x) = <$NonZeroT>::new(self) {
1240+
if let Some(x) = NonZero::new(self) {
12441241
Some(x.ilog10())
12451242
} else {
12461243
None
@@ -2582,37 +2579,10 @@ macro_rules! uint_impl {
25822579
without modifying the original"]
25832580
#[inline]
25842581
pub const fn isqrt(self) -> Self {
2585-
if self < 2 {
2586-
return self;
2582+
match NonZero::new(self) {
2583+
Some(x) => x.isqrt().get(),
2584+
None => 0,
25872585
}
2588-
2589-
// The algorithm is based on the one presented in
2590-
// <https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)>
2591-
// which cites as source the following C code:
2592-
// <https://web.archive.org/web/20120306040058/http://medialab.freaknet.org/martin/src/sqrt/sqrt.c>.
2593-
2594-
let mut op = self;
2595-
let mut res = 0;
2596-
let mut one = 1 << (self.ilog2() & !1);
2597-
2598-
while one != 0 {
2599-
if op >= res + one {
2600-
op -= res + one;
2601-
res = (res >> 1) + one;
2602-
} else {
2603-
res >>= 1;
2604-
}
2605-
one >>= 2;
2606-
}
2607-
2608-
// SAFETY: the result is positive and fits in an integer with half as many bits.
2609-
// Inform the optimizer about it.
2610-
unsafe {
2611-
hint::assert_unchecked(0 < res);
2612-
hint::assert_unchecked(res < 1 << (Self::BITS / 2));
2613-
}
2614-
2615-
res
26162586
}
26172587

26182588
/// Performs Euclidean division.

0 commit comments

Comments
 (0)