Skip to content

Commit 864e465

Browse files
authored
Rollup merge of rust-lang#129377 - chorman0773:unbounded-shifts-impl, r=scottmcm
Add implementations for `unbounded_shl`/`unbounded_shr` Tracking Issue: rust-lang#129375 This implements `unbounded_shl` and `unbounded_shr` under the feature gate `unbounded_shifts`
2 parents d958260 + 3fd591e commit 864e465

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed

Diff for: core/src/num/int_macros.rs

+62
Original file line numberDiff line numberDiff line change
@@ -1312,6 +1312,34 @@ macro_rules! int_impl {
13121312
}
13131313
}
13141314

1315+
/// Unbounded shift left. Computes `self << rhs`, without bounding the value of `rhs`
1316+
///
1317+
/// If `rhs` is larger or equal to the number of bits in `self`,
1318+
/// the entire value is shifted out, and `0` is returned.
1319+
///
1320+
/// # Examples
1321+
///
1322+
/// Basic usage:
1323+
/// ```
1324+
/// #![feature(unbounded_shifts)]
1325+
#[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(4), 0x10);")]
1326+
#[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(129), 0);")]
1327+
/// ```
1328+
#[unstable(feature = "unbounded_shifts", issue = "129375")]
1329+
#[rustc_const_unstable(feature = "const_unbounded_shifts", issue = "129375")]
1330+
#[must_use = "this returns the result of the operation, \
1331+
without modifying the original"]
1332+
#[inline]
1333+
pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{
1334+
if rhs < Self::BITS {
1335+
// SAFETY:
1336+
// rhs is just checked to be in-range above
1337+
unsafe { self.unchecked_shl(rhs) }
1338+
} else {
1339+
0
1340+
}
1341+
}
1342+
13151343
/// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is
13161344
/// larger than or equal to the number of bits in `self`.
13171345
///
@@ -1410,6 +1438,40 @@ macro_rules! int_impl {
14101438
}
14111439
}
14121440

1441+
/// Unbounded shift right. Computes `self >> rhs`, without bounding the value of `rhs`
1442+
///
1443+
/// If `rhs` is larger or equal to the number of bits in `self`,
1444+
/// the entire value is shifted out, which yields `0` for a positive number,
1445+
/// and `-1` for a negative number.
1446+
///
1447+
/// # Examples
1448+
///
1449+
/// Basic usage:
1450+
/// ```
1451+
/// #![feature(unbounded_shifts)]
1452+
#[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(4), 0x1);")]
1453+
#[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(129), 0);")]
1454+
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.unbounded_shr(129), -1);")]
1455+
/// ```
1456+
#[unstable(feature = "unbounded_shifts", issue = "129375")]
1457+
#[rustc_const_unstable(feature = "const_unbounded_shifts", issue = "129375")]
1458+
#[must_use = "this returns the result of the operation, \
1459+
without modifying the original"]
1460+
#[inline]
1461+
pub const fn unbounded_shr(self, rhs: u32) -> $SelfT{
1462+
if rhs < Self::BITS {
1463+
// SAFETY:
1464+
// rhs is just checked to be in-range above
1465+
unsafe { self.unchecked_shr(rhs) }
1466+
} else {
1467+
// A shift by `Self::BITS-1` suffices for signed integers, because the sign bit is copied for each of the shifted bits.
1468+
1469+
// SAFETY:
1470+
// `Self::BITS-1` is guaranteed to be less than `Self::BITS`
1471+
unsafe { self.unchecked_shr(Self::BITS - 1) }
1472+
}
1473+
}
1474+
14131475
/// Checked absolute value. Computes `self.abs()`, returning `None` if
14141476
/// `self == MIN`.
14151477
///

Diff for: core/src/num/uint_macros.rs

+56
Original file line numberDiff line numberDiff line change
@@ -1501,6 +1501,34 @@ macro_rules! uint_impl {
15011501
}
15021502
}
15031503

1504+
/// Unbounded shift left. Computes `self << rhs`, without bounding the value of `rhs`
1505+
///
1506+
/// If `rhs` is larger or equal to the number of bits in `self`,
1507+
/// the entire value is shifted out, and `0` is returned.
1508+
///
1509+
/// # Examples
1510+
///
1511+
/// Basic usage:
1512+
/// ```
1513+
/// #![feature(unbounded_shifts)]
1514+
#[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(4), 0x10);")]
1515+
#[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".unbounded_shl(129), 0);")]
1516+
/// ```
1517+
#[unstable(feature = "unbounded_shifts", issue = "129375")]
1518+
#[rustc_const_unstable(feature = "const_unbounded_shifts", issue = "129375")]
1519+
#[must_use = "this returns the result of the operation, \
1520+
without modifying the original"]
1521+
#[inline]
1522+
pub const fn unbounded_shl(self, rhs: u32) -> $SelfT{
1523+
if rhs < Self::BITS {
1524+
// SAFETY:
1525+
// rhs is just checked to be in-range above
1526+
unsafe { self.unchecked_shl(rhs) }
1527+
} else {
1528+
0
1529+
}
1530+
}
1531+
15041532
/// Checked shift right. Computes `self >> rhs`, returning `None`
15051533
/// if `rhs` is larger than or equal to the number of bits in `self`.
15061534
///
@@ -1599,6 +1627,34 @@ macro_rules! uint_impl {
15991627
}
16001628
}
16011629

1630+
/// Unbounded shift right. Computes `self >> rhs`, without bounding the value of `rhs`
1631+
///
1632+
/// If `rhs` is larger or equal to the number of bits in `self`,
1633+
/// the entire value is shifted out, and `0` is returned.
1634+
///
1635+
/// # Examples
1636+
///
1637+
/// Basic usage:
1638+
/// ```
1639+
/// #![feature(unbounded_shifts)]
1640+
#[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(4), 0x1);")]
1641+
#[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".unbounded_shr(129), 0);")]
1642+
/// ```
1643+
#[unstable(feature = "unbounded_shifts", issue = "129375")]
1644+
#[rustc_const_unstable(feature = "const_unbounded_shifts", issue = "129375")]
1645+
#[must_use = "this returns the result of the operation, \
1646+
without modifying the original"]
1647+
#[inline]
1648+
pub const fn unbounded_shr(self, rhs: u32) -> $SelfT{
1649+
if rhs < Self::BITS {
1650+
// SAFETY:
1651+
// rhs is just checked to be in-range above
1652+
unsafe { self.unchecked_shr(rhs) }
1653+
} else {
1654+
0
1655+
}
1656+
}
1657+
16021658
/// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if
16031659
/// overflow occurred.
16041660
///

0 commit comments

Comments
 (0)