diff --git a/library/core/src/num/int_bits.rs b/library/core/src/num/int_bits.rs index 44be6de473272..7e54591922358 100644 --- a/library/core/src/num/int_bits.rs +++ b/library/core/src/num/int_bits.rs @@ -1,12 +1,12 @@ -//! Implementations for `uN::gather_bits` and `uN::scatter_bits` +//! Implementations for `uN::extract_bits` and `uN::deposit_bits` //! //! For the purposes of this implementation, the operations can be thought //! of as operating on the input bits as a list, starting from the least -//! significant bit. Gathering is like `Vec::retain` that deletes bits -//! where the mask has a zero. Scattering is like doing the inverse by -//! inserting the zeros that gathering would delete. +//! significant bit. Extraction is like `Vec::retain` that deletes bits +//! where the mask has a zero. Deposition is like doing the inverse by +//! inserting the zeros that extraction would delete. //! -//! Key observation: Each bit that is gathered/scattered needs to be +//! Key observation: Each extracted or deposited bit needs to be //! shifted by the count of zeros up to the corresponding mask bit. //! //! With that in mind, the general idea is to decompose the operation into @@ -14,7 +14,7 @@ //! of the bits by `n = 1 << stage`. The masks for each stage are computed //! via prefix counts of zeros in the mask. //! -//! # Gathering +//! # Extraction //! //! Consider the input as a sequence of runs of data (bitstrings A,B,C,...), //! split by fixed-width groups of zeros ('.'), initially at width `n = 1`. @@ -36,9 +36,9 @@ //! ........abbbcccccddeghh //! ``` //! -//! # Scattering +//! # Deposition //! -//! For `scatter_bits`, the stages are reversed. We start with a single run of +//! For `deposit_bits`, the stages are reversed. We start with a single run of //! data in the low bits. Each stage then splits each run of data in two by //! shifting part of it left by `n`, which is halved each stage. //! ```text @@ -100,7 +100,7 @@ macro_rules! uint_impl { } #[inline(always)] - pub(in super::super) const fn gather_impl(mut x: $U, sparse: $U) -> $U { + pub(in super::super) const fn extract_impl(mut x: $U, sparse: $U) -> $U { let masks = prepare(sparse); x &= sparse; let mut stage = 0; @@ -131,7 +131,7 @@ macro_rules! uint_impl { x } #[inline(always)] - pub(in super::super) const fn scatter_impl(mut x: $U, sparse: $U) -> $U { + pub(in super::super) const fn deposit_impl(mut x: $U, sparse: $U) -> $U { let masks = prepare(sparse); let mut stage = STAGES; while stage > 0 { diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 57f0cd48fbe80..c48320c0eab3d 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -507,15 +507,15 @@ macro_rules! uint_impl { /// #![feature(uint_gather_scatter_bits)] #[doc = concat!("let n: ", stringify!($SelfT), " = 0b1011_1100;")] /// - /// assert_eq!(n.gather_bits(0b0010_0100), 0b0000_0011); - /// assert_eq!(n.gather_bits(0xF0), 0b0000_1011); + /// assert_eq!(n.extract_bits(0b0010_0100), 0b0000_0011); + /// assert_eq!(n.extract_bits(0xF0), 0b0000_1011); /// ``` #[unstable(feature = "uint_gather_scatter_bits", issue = "149069")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn gather_bits(self, mask: Self) -> Self { - crate::num::int_bits::$ActualT::gather_impl(self as $ActualT, mask as $ActualT) as $SelfT + pub const fn extract_bits(self, mask: Self) -> Self { + crate::num::int_bits::$ActualT::extract_impl(self as $ActualT, mask as $ActualT) as $SelfT } /// Returns an integer with the least significant bits of `self` @@ -524,15 +524,15 @@ macro_rules! uint_impl { /// #![feature(uint_gather_scatter_bits)] #[doc = concat!("let n: ", stringify!($SelfT), " = 0b1010_1101;")] /// - /// assert_eq!(n.scatter_bits(0b0101_0101), 0b0101_0001); - /// assert_eq!(n.scatter_bits(0xF0), 0b1101_0000); + /// assert_eq!(n.deposit_bits(0b0101_0101), 0b0101_0001); + /// assert_eq!(n.deposit_bits(0xF0), 0b1101_0000); /// ``` #[unstable(feature = "uint_gather_scatter_bits", issue = "149069")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn scatter_bits(self, mask: Self) -> Self { - crate::num::int_bits::$ActualT::scatter_impl(self as $ActualT, mask as $ActualT) as $SelfT + pub const fn deposit_bits(self, mask: Self) -> Self { + crate::num::int_bits::$ActualT::deposit_impl(self as $ActualT, mask as $ActualT) as $SelfT } /// Reverses the order of bits in the integer. The least significant bit becomes the most significant bit, diff --git a/library/coretests/benches/num/int_bits/mod.rs b/library/coretests/benches/num/int_bits/mod.rs index c6ec51f248baa..65ba48609e80c 100644 --- a/library/coretests/benches/num/int_bits/mod.rs +++ b/library/coretests/benches/num/int_bits/mod.rs @@ -50,8 +50,8 @@ macro_rules! bench_mask_kind { ($mask_kind:ident, $mask:expr) => { mod $mask_kind { use super::{Data, ITERATIONS, U}; - bench_template!(U::gather_bits, gather_bits, $mask); - bench_template!(U::scatter_bits, scatter_bits, $mask); + bench_template!(U::extract_bits, extract_bits, $mask); + bench_template!(U::deposit_bits, deposit_bits, $mask); } }; } diff --git a/library/coretests/tests/num/uint_macros.rs b/library/coretests/tests/num/uint_macros.rs index 72d500e575fa0..7c4fb22599c03 100644 --- a/library/coretests/tests/num/uint_macros.rs +++ b/library/coretests/tests/num/uint_macros.rs @@ -127,50 +127,50 @@ macro_rules! uint_module { assert_eq_const_safe!($T: _1.swap_bytes(), _1); } - fn test_gather_bits() { - assert_eq_const_safe!($T: $T::gather_bits(0b1010_0101, 0b0000_0011), 0b_0001); - assert_eq_const_safe!($T: $T::gather_bits(0b1010_0101, 0b0000_0110), 0b_0010); - assert_eq_const_safe!($T: $T::gather_bits(0b1010_0101, 0b0000_1100), 0b_0001); - assert_eq_const_safe!($T: $T::gather_bits(0b1010_0101, 0b0001_1000), 0b_0000); - assert_eq_const_safe!($T: $T::gather_bits(0b1010_0101, 0b0011_0000), 0b_0010); - assert_eq_const_safe!($T: $T::gather_bits(0b1010_0101, 0b0110_0000), 0b_0001); - assert_eq_const_safe!($T: $T::gather_bits(0b1010_0101, 0b1100_0000), 0b_0010); - - assert_eq_const_safe!($T: A.gather_bits(_0), 0); - assert_eq_const_safe!($T: B.gather_bits(_0), 0); - assert_eq_const_safe!($T: C.gather_bits(_0), 0); - assert_eq_const_safe!($T: _0.gather_bits(A), 0); - assert_eq_const_safe!($T: _0.gather_bits(B), 0); - assert_eq_const_safe!($T: _0.gather_bits(C), 0); - - assert_eq_const_safe!($T: A.gather_bits(_1), A); - assert_eq_const_safe!($T: B.gather_bits(_1), B); - assert_eq_const_safe!($T: C.gather_bits(_1), C); - assert_eq_const_safe!($T: _1.gather_bits(0b0010_0001), 0b0000_0011); - assert_eq_const_safe!($T: _1.gather_bits(0b0010_1100), 0b0000_0111); - assert_eq_const_safe!($T: _1.gather_bits(0b0111_1001), 0b0001_1111); - } - - fn test_scatter_bits() { - assert_eq_const_safe!($T: $T::scatter_bits(0b1111, 0b1001_0110), 0b1001_0110); - assert_eq_const_safe!($T: $T::scatter_bits(0b0001, 0b1001_0110), 0b0000_0010); - assert_eq_const_safe!($T: $T::scatter_bits(0b0010, 0b1001_0110), 0b0000_0100); - assert_eq_const_safe!($T: $T::scatter_bits(0b0100, 0b1001_0110), 0b0001_0000); - assert_eq_const_safe!($T: $T::scatter_bits(0b1000, 0b1001_0110), 0b1000_0000); - - assert_eq_const_safe!($T: A.scatter_bits(_0), 0); - assert_eq_const_safe!($T: B.scatter_bits(_0), 0); - assert_eq_const_safe!($T: C.scatter_bits(_0), 0); - assert_eq_const_safe!($T: _0.scatter_bits(A), 0); - assert_eq_const_safe!($T: _0.scatter_bits(B), 0); - assert_eq_const_safe!($T: _0.scatter_bits(C), 0); - - assert_eq_const_safe!($T: A.scatter_bits(_1), A); - assert_eq_const_safe!($T: B.scatter_bits(_1), B); - assert_eq_const_safe!($T: C.scatter_bits(_1), C); - assert_eq_const_safe!($T: _1.scatter_bits(A), A); - assert_eq_const_safe!($T: _1.scatter_bits(B), B); - assert_eq_const_safe!($T: _1.scatter_bits(C), C); + fn test_extract_bits() { + assert_eq_const_safe!($T: $T::extract_bits(0b1010_0101, 0b0000_0011), 0b_0001); + assert_eq_const_safe!($T: $T::extract_bits(0b1010_0101, 0b0000_0110), 0b_0010); + assert_eq_const_safe!($T: $T::extract_bits(0b1010_0101, 0b0000_1100), 0b_0001); + assert_eq_const_safe!($T: $T::extract_bits(0b1010_0101, 0b0001_1000), 0b_0000); + assert_eq_const_safe!($T: $T::extract_bits(0b1010_0101, 0b0011_0000), 0b_0010); + assert_eq_const_safe!($T: $T::extract_bits(0b1010_0101, 0b0110_0000), 0b_0001); + assert_eq_const_safe!($T: $T::extract_bits(0b1010_0101, 0b1100_0000), 0b_0010); + + assert_eq_const_safe!($T: A.extract_bits(_0), 0); + assert_eq_const_safe!($T: B.extract_bits(_0), 0); + assert_eq_const_safe!($T: C.extract_bits(_0), 0); + assert_eq_const_safe!($T: _0.extract_bits(A), 0); + assert_eq_const_safe!($T: _0.extract_bits(B), 0); + assert_eq_const_safe!($T: _0.extract_bits(C), 0); + + assert_eq_const_safe!($T: A.extract_bits(_1), A); + assert_eq_const_safe!($T: B.extract_bits(_1), B); + assert_eq_const_safe!($T: C.extract_bits(_1), C); + assert_eq_const_safe!($T: _1.extract_bits(0b0010_0001), 0b0000_0011); + assert_eq_const_safe!($T: _1.extract_bits(0b0010_1100), 0b0000_0111); + assert_eq_const_safe!($T: _1.extract_bits(0b0111_1001), 0b0001_1111); + } + + fn test_deposit_bits() { + assert_eq_const_safe!($T: $T::deposit_bits(0b1111, 0b1001_0110), 0b1001_0110); + assert_eq_const_safe!($T: $T::deposit_bits(0b0001, 0b1001_0110), 0b0000_0010); + assert_eq_const_safe!($T: $T::deposit_bits(0b0010, 0b1001_0110), 0b0000_0100); + assert_eq_const_safe!($T: $T::deposit_bits(0b0100, 0b1001_0110), 0b0001_0000); + assert_eq_const_safe!($T: $T::deposit_bits(0b1000, 0b1001_0110), 0b1000_0000); + + assert_eq_const_safe!($T: A.deposit_bits(_0), 0); + assert_eq_const_safe!($T: B.deposit_bits(_0), 0); + assert_eq_const_safe!($T: C.deposit_bits(_0), 0); + assert_eq_const_safe!($T: _0.deposit_bits(A), 0); + assert_eq_const_safe!($T: _0.deposit_bits(B), 0); + assert_eq_const_safe!($T: _0.deposit_bits(C), 0); + + assert_eq_const_safe!($T: A.deposit_bits(_1), A); + assert_eq_const_safe!($T: B.deposit_bits(_1), B); + assert_eq_const_safe!($T: C.deposit_bits(_1), C); + assert_eq_const_safe!($T: _1.deposit_bits(A), A); + assert_eq_const_safe!($T: _1.deposit_bits(B), B); + assert_eq_const_safe!($T: _1.deposit_bits(C), C); } fn test_reverse_bits() { @@ -389,7 +389,7 @@ macro_rules! uint_module { #[cfg(not(miri))] // Miri is too slow #[test] - fn test_lots_of_gather_scatter() { + fn test_lots_of_extract_deposit() { // Generate a handful of bit patterns to use as inputs let xs = { let mut xs = vec![]; @@ -414,7 +414,7 @@ macro_rules! uint_module { for sparse in sparse_masks { // Collect the set bits to sequential low bits - let dense = sparse.gather_bits(sparse); + let dense = sparse.extract_bits(sparse); let count = sparse.count_ones(); assert_eq!(count, dense.count_ones()); assert_eq!(count, dense.trailing_ones()); @@ -424,27 +424,27 @@ macro_rules! uint_module { let mut bit = 1 as $T; for _ in 0..count { let lowest_one = t.isolate_lowest_one(); - assert_eq!(lowest_one, bit.scatter_bits(sparse)); - assert_eq!(bit, lowest_one.gather_bits(sparse)); + assert_eq!(lowest_one, bit.deposit_bits(sparse)); + assert_eq!(bit, lowest_one.extract_bits(sparse)); t ^= lowest_one; bit <<= 1; } // Other bits are ignored - assert_eq!(0, bit.wrapping_neg().scatter_bits(sparse)); - assert_eq!(0, (!sparse).gather_bits(sparse)); + assert_eq!(0, bit.wrapping_neg().deposit_bits(sparse)); + assert_eq!(0, (!sparse).extract_bits(sparse)); for &x in &xs { // Gather bits from `x & sparse` to `dense` - let dx = x.gather_bits(sparse); + let dx = x.extract_bits(sparse); assert_eq!(dx & !dense, 0); // Scatter bits from `x & dense` to `sparse` - let sx = x.scatter_bits(sparse); + let sx = x.deposit_bits(sparse); assert_eq!(sx & !sparse, 0); // The other recovers the input (within the mask) - assert_eq!(dx.scatter_bits(sparse), x & sparse); - assert_eq!(sx.gather_bits(sparse), x & dense); + assert_eq!(dx.deposit_bits(sparse), x & sparse); + assert_eq!(sx.extract_bits(sparse), x & dense); } } }